J'ai un tableau d'octets de la forme [4,-101,122,-41,-30,23,-28,3,..]
que je souhaite convertir sous la forme 6d69f597b217fa333246c2c8
J'utilise la fonction ci-dessous
function toHexString(bytes) {
return bytes.map(function(byte) {
return (byte & 0xFF).toString(16)
}).join('')
}
ce qui me donne une chaîne de la même forme mais je soupçonne que ce n'est pas une conversion efficace car la chaîne hexadécimale est un peu plus courte que prévu. Je pense que la traduction devrait obtenir "0a10a6dc". Veuillez me dire si je me trompe ou si c'est une bonne conversion mais peut-être que je n'utilise pas le bon tableau d'octets
tableau d'octets 4,-127,45,126,58,-104,41,-27,-43,27,-35,100,-50,-77,93,-16,96,105,-101,-63,48,-105,49,-67,110,111,26,84,67,-89,-7,-50,10,-12,56,47,-49,-42,-11,-8,-96,-117,-78,97,-105,9,-62,-44,-97,-73,113,96,23,112,-14,-62,103,-104,90,-14,117,78,31,-116,-7
Conversion correspondante 4812d7e3a9829e5d51bdd64ceb35df060699bc1309731bd6e6f1a5443a7f9ceaf4382fcfd6f5f8a08bb261979c2d49fb771601770f2c267985af2754e1f8cf9
Il vous manque le rembourrage dans la conversion hexadécimale. Vous voudrez utiliser
function toHexString(byteArray) {
return Array.from(byteArray, function(byte) {
return ('0' + (byte & 0xFF).toString(16)).slice(-2);
}).join('')
}
de sorte que chaque octet se transforme en exactement deux chiffres hexadécimaux. Votre sortie attendue serait 04812d7e3a9829e5d51bdd64ceb35df060699bc1309731bd6e6f1a5443a7f9ce0af4382fcfd6f5f8a08bb2619709c2d49fb771601770f2c267985af2754e1f8cf9
L'utilisation de map()
ne fonctionnera pas si l'entrée est d'un type comme Uint8Array
: Le résultat de map()
est aussi Uint8Array
Qui ne peut pas contenir les résultats de la conversion de chaîne.
function toHexString(byteArray) {
var s = '0x';
byteArray.forEach(function(byte) {
s += ('0' + (byte & 0xFF).toString(16)).slice(-2);
});
return s;
}
Une alternative plus concise et performante (voir https://jsperf.com/byte-array-to-hex-string ) en utilisant Array.reduce ():
function toHexString(byteArray) {
return byteArray.reduce((output, elem) =>
(output + ('0' + elem.toString(16)).slice(-2)),
'');
}
(Aussi sans "0xFF" car à mon avis, si un tableau contenant des valeurs supérieures à 255 est transmis, la sortie doit être gâchée, afin que l'utilisateur puisse plus facilement voir que son entrée était incorrecte.)
Comme il s'agit du premier hit de Google pour "js byte to hex" et que j'avais besoin de temps pour comprendre la fonction de Bergi, j'ai réécrit la fonction et ajouté quelques commentaires qui me facilitaient la compréhension:
function byteToHex(byte) {
// convert the possibly signed byte (-128 to 127) to an unsigned byte (0 to 255).
// if you know, that you only deal with unsigned bytes (Uint8Array), you can omit this line
const unsignedByte = byte & 0xff;
// If the number can be represented with only 4 bits (0-15),
// the hexadecimal representation of this number is only one char (0-9, a-f).
if (unsignedByte < 16) {
return '0' + unsignedByte.toString(16);
} else {
return unsignedByte.toString(16);
}
}
// bytes is an typed array (Int8Array or Uint8Array)
function toHexString(bytes) {
// Since the .map() method is not available for typed arrays,
// we will convert the typed array to an array using Array.from().
return Array.from(bytes)
.map(byte => byteToHex(byte))
.join('');
}
const unsignedByte = byte & 0xff
- partie, vérifiez Que fait AND 0xFF? .Array.from
n'est pas disponible dans tous les navigateurs (par exemple, pas dans IE11), consultez Comment convertir un tableau typé JavaScript en tableau JavaScript pour plus d'informationsL'OP a oublié d'ajouter le premier 0
pour les nombres qui peuvent être affichés avec seulement 4 bits.
Vous devez remplir la conversion hexadécimale avec le nombre approprié de zéros non significatifs.
Pour garder votre code propre, vous pouvez utiliser les bibliothèques existantes, par exemple array-buffer-to-hex . Exemple:
const arrayBufferToHex = require('array-buffer-to-hex')
const crypto = require('crypto')
const bytes = crypto.randomBytes(10)
console.log(arrayBufferToHex(bytes)) // => "557f694f76c628fd6acb"
Toutes les solutions précédentes fonctionnent mais elles nécessitent toutes la création de nombreuses chaînes et la concaténation et le découpage des chaînes créées. J'ai pensé qu'il devait y avoir une meilleure façon de procéder maintenant qu'il y a des tableaux typés. À l'origine, j'ai fait cela en utilisant le nœud, puis j'ai commenté les lignes qui utilisent Buffer et les ai modifiées en TypedArrays afin que cela fonctionne également dans un navigateur.
C'est plus de code mais c'est beaucoup plus rapide, au moins dans le quick jsperf j'ai mis ensemble. La version de manipulation de chaîne dans la réponse acceptée a effectué 37 000 opérations/s tandis que le code ci-dessous gérait 317 000 opérations/s. Il y a beaucoup de frais généraux cachés dans la création d'objets chaîne.
function toHexString (byteArray) {
//const chars = new Buffer(byteArray.length * 2);
const chars = new Uint8Array(byteArray.length * 2);
const alpha = 'a'.charCodeAt(0) - 10;
const digit = '0'.charCodeAt(0);
let p = 0;
for (let i = 0; i < byteArray.length; i++) {
let nibble = byteArray[i] >>> 4;
chars[p++] = nibble > 9 ? nibble + alpha : nibble + digit;
nibble = byteArray[i] & 0xF;
chars[p++] = nibble > 9 ? nibble + alpha : nibble + digit;
}
//return chars.toString('utf8');
return String.fromCharCode.apply(null, chars);
}