Как преобразовать шестнадцатеричную строку в Uint8Array и обратно в JavaScript?
Я хочу преобразовать шестнадцатеричную строку как bada55
в Uint8Array
и обратно
4 ответа
Решение
Ваниль JS:
const fromHexString = hexString =>
new Uint8Array(hexString.match(/.{1,2}/g).map(byte => parseInt(byte, 16)));
const toHexString = bytes =>
bytes.reduce((str, byte) => str + byte.toString(16).padStart(2, '0'), '');
console.log(toHexString(new Uint8Array([0, 1, 2, 42, 100, 101, 102, 255])))
console.log(fromHexString('0001022a646566ff'))
Node.js
Для JavaScript, работающего на Node
ты можешь это сделать:
const hexString = 'bada55';
const hex = Uint8Array.from(Buffer.from(hexString, 'hex'));
const backToHexString = Buffer.from(hex).toString('hex');
(источник: этот ответ @Teneff, предоставлен с разрешения)
Вот решение в нативном JavaScript:
var string = 'bada55';
var bytes = new Uint8Array(Math.ceil(string.length / 2));
for (var i = 0; i < bytes.length; i++) bytes[i] = parseInt(string.substr(i * 2, 2), 16);
console.log(bytes);
var convertedBack = '';
for (var i = 0; i < bytes.length; i++) {
if (bytes[i] < 16) convertedBack += '0';
convertedBack += bytes[i].toString(16);
}
console.log(convertedBack);
Браузер (точно имитирует поведение NodeJS)
Мне нужно было имитировать NodeJS
Buffer.from(x, 'hex')
поведение в среде браузера, и это то, что я придумал.
Это довольно быстро, когда я провел несколько тестов.
const HEX_STRINGS = "0123456789abcdefABCDEF";
const MAP_HEX = HEX_STRINGS
.split("")
.reduce((r, s) => ({ ...r, [s]: 1 }), {});
// Fast Uint8Array to hex
function toHex(bytes) {
return Array.from(bytes).map((b) => HEX_STRINGS[b >> 4] + HEX_STRINGS[b & 15])
.join("");
}
// Mimics Buffer.from(x, 'hex') logic
// Stops on first non-hex string and returns
// https://github.com/nodejs/node/blob/v14.18.1/src/string_bytes.cc#L246-L261
function fromHex(hexString) {
const bytes = new Uint8Array(Math.ceil(hexString.length / 2));
let finalLen = bytes.length;
for (let i = 0; i < finalLen; i++) {
const a = hexString[i * 2];
const b = hexString[i * 2 + 1];
if (!MAP_HEX[a] || !MAP_HEX[b]) {
finalLen = i;
break;
}
bytes[i] = parseInt(hexString.substr(i * 2, 2), 16);
}
return finalLen === bytes.length ? bytes : bytes.slice(0, finalLen);
}