如何将十六进制字符串转换为 Uint8Array 并返回 JavaScript?
How to convert a hexadecimal string to Uint8Array and back in JavaScript?
我想将像 bada55
这样的十六进制字符串转换成 Uint8Array
然后再转换回来。
这是原生的解决方案 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);
香草 JS:
const fromHexString = (hexString) =>
Uint8Array.from(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(Uint8Array.from([0, 1, 2, 42, 100, 101, 102, 255])));
console.log(fromHexString('0001022a646566ff'));
注意:此方法信任其输入。如果提供的输入的长度为 0,则会抛出错误。如果十六进制编码缓冲区的长度不能被 2 整除,则最后一个字节将被解析为好像它前面有 0
(例如 aaa
被解释为 aa0a
)。
如果十六进制可能格式错误或为空(例如用户输入),请在调用此方法之前检查其长度并处理错误,例如:
const isHex = (maybeHex) =>
maybeHex.length !== 0 && maybeHex.length % 2 === 0 && !/[^a-fA-F0-9]/u.test(maybeHex);
const missingLetter = 'abc';
if (!isHex(missingLetter)) {
console.log(`The string "${missingLetter}" is not valid hex.`)
} else {
fromHexString(missingLetter);
}
来源:Libauth library (hexToBin method)
Node.js
对于 Node
上的 JavaScript 运行,您可以这样做:
const hexString = 'bada55';
const hex = Uint8Array.from(Buffer.from(hexString, 'hex'));
const backToHexString = Buffer.from(hex).toString('hex');
(来源:@Teneff 的 ,经许可共享)
浏览器(准确模仿 NodeJS 行为)
我需要在浏览器环境中模仿 NodeJS Buffer.from(x, 'hex')
行为,这就是我想到的。
当我 运行 通过一些基准测试时,它非常快。
const HEX_STRINGS = "0123456789abcdef";
const MAP_HEX = {
0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6,
7: 7, 8: 8, 9: 9, a: 10, b: 11, c: 12, d: 13,
e: 14, f: 15, A: 10, B: 11, C: 12, D: 13,
E: 14, F: 15
};
// 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.floor((hexString || "").length / 2));
let i;
for (i = 0; i < bytes.length; i++) {
const a = MAP_HEX[hexString[i * 2]];
const b = MAP_HEX[hexString[i * 2 + 1]];
if (a === undefined || b === undefined) {
break;
}
bytes[i] = (a << 4) | b;
}
return i === bytes.length ? bytes : bytes.slice(0, i);
}
我想将像 bada55
这样的十六进制字符串转换成 Uint8Array
然后再转换回来。
这是原生的解决方案 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);
香草 JS:
const fromHexString = (hexString) =>
Uint8Array.from(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(Uint8Array.from([0, 1, 2, 42, 100, 101, 102, 255])));
console.log(fromHexString('0001022a646566ff'));
注意:此方法信任其输入。如果提供的输入的长度为 0,则会抛出错误。如果十六进制编码缓冲区的长度不能被 2 整除,则最后一个字节将被解析为好像它前面有 0
(例如 aaa
被解释为 aa0a
)。
如果十六进制可能格式错误或为空(例如用户输入),请在调用此方法之前检查其长度并处理错误,例如:
const isHex = (maybeHex) =>
maybeHex.length !== 0 && maybeHex.length % 2 === 0 && !/[^a-fA-F0-9]/u.test(maybeHex);
const missingLetter = 'abc';
if (!isHex(missingLetter)) {
console.log(`The string "${missingLetter}" is not valid hex.`)
} else {
fromHexString(missingLetter);
}
来源:Libauth library (hexToBin method)
Node.js
对于 Node
上的 JavaScript 运行,您可以这样做:
const hexString = 'bada55';
const hex = Uint8Array.from(Buffer.from(hexString, 'hex'));
const backToHexString = Buffer.from(hex).toString('hex');
(来源:@Teneff 的
浏览器(准确模仿 NodeJS 行为)
我需要在浏览器环境中模仿 NodeJS Buffer.from(x, 'hex')
行为,这就是我想到的。
当我 运行 通过一些基准测试时,它非常快。
const HEX_STRINGS = "0123456789abcdef";
const MAP_HEX = {
0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6,
7: 7, 8: 8, 9: 9, a: 10, b: 11, c: 12, d: 13,
e: 14, f: 15, A: 10, B: 11, C: 12, D: 13,
E: 14, F: 15
};
// 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.floor((hexString || "").length / 2));
let i;
for (i = 0; i < bytes.length; i++) {
const a = MAP_HEX[hexString[i * 2]];
const b = MAP_HEX[hexString[i * 2 + 1]];
if (a === undefined || b === undefined) {
break;
}
bytes[i] = (a << 4) | b;
}
return i === bytes.length ? bytes : bytes.slice(0, i);
}