[4,-101,122,-41,-30,23,-28,3,..]
の形式のバイト配列があり、これを6d69f597b217fa333246c2c8
の形式に変換したい
function toHexString(bytes) {
return bytes.map(function(byte) {
return (byte & 0xFF).toString(16)
}).join('')
}
これは同じ形式の文字列を私に与えていますが、16進文字列は予想よりも少し短いため、効率的な変換ではないと思われます。翻訳は「0a10a6dc」になるはずだと思います。私が間違っているか、これが正しい変換であるかどうか教えてください、しかしおそらく私は正しいバイト配列を使用していません
バイト配列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
対応するコンバージョン4812d7e3a9829e5d51bdd64ceb35df060699bc1309731bd6e6f1a5443a7f9ceaf4382fcfd6f5f8a08bb261979c2d49fb771601770f2c267985af2754e1f8cf9
16進変換でパディングが欠落しています。使用したくなるでしょう
function toHexString(byteArray) {
return Array.from(byteArray, function(byte) {
return ('0' + (byte & 0xFF).toString(16)).slice(-2);
}).join('')
}
各バイトが正確に2桁の16進数に変換されるようにします。予想される出力は04812d7e3a9829e5d51bdd64ceb35df060699bc1309731bd6e6f1a5443a7f9ce0af4382fcfd6f5f8a08bb2619709c2d49fb771601770f2c267985af2754e1f8cf9
入力がUint8Array
のようなタイプの場合、map()
を使用しても機能しません。map()
の結果もUint8Array
で、文字列の結果を保持できません変換。
function toHexString(byteArray) {
var s = '0x';
byteArray.forEach(function(byte) {
s += ('0' + (byte & 0xFF).toString(16)).slice(-2);
});
return s;
}
Array.reduce()を使用したより簡潔で高性能な( https://jsperf.com/byte-array-to-hex-string を参照)代替案:
function toHexString(byteArray) {
return byteArray.reduce((output, elem) =>
(output + ('0' + elem.toString(16)).slice(-2)),
'');
}
(「&0xFF」なしでも、私の意見では、255より大きい値を含む配列が渡された場合、ユーザーが入力が間違っていることをより簡単に確認できるように、出力を台無しにする必要があります。)
これは「js byte to hex」に対するGoogleの最初のヒットであり、Bergiの機能を理解するのに時間が必要だったので、機能を書き直し、理解しやすいコメントを追加しました。
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
- partの詳細については、 AND 0xFFとは何ですか? を確認してください。Array.from
はすべてのブラウザで使用できるわけではありません(例:IE11では使用できません)、チェック JavaScript型付き配列をJavaScript配列に変換する方法 詳細OPは、4ビットのみで表示できる数字の先頭の0
を追加するのを忘れていました。
16進変換に適切な数の先行ゼロを埋め込む必要があります。
コードをきれいに保つために、既存のライブラリ、たとえば array-buffer-to-hex を使用できます。例:
const arrayBufferToHex = require('array-buffer-to-hex')
const crypto = require('crypto')
const bytes = crypto.randomBytes(10)
console.log(arrayBufferToHex(bytes)) // => "557f694f76c628fd6acb"
以前のソリューションはすべて機能しますが、多くの文字列を作成し、作成した文字列を連結およびスライスする必要があります。型付き配列があるので、もっと良い方法が必要だと思いました。私はもともとノードを使用してこれを行い、その後、Bufferを使用する行をコメント化してTypedArraysに変更し、ブラウザーでも機能するようにしました。
それはより多くのコードですが、少なくとも迅速に大幅に高速です jsperf 私はまとめます。受け入れられた回答の文字列操作バージョンは37000 ops/secを実行しましたが、以下のコードは317000 ops/secを管理していました。文字列オブジェクトの作成には、多くの隠れたオーバーヘッドがあります。
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);
}