Skip to content

Commit 663da12

Browse files
committed
utils: use built-in Uint8Array toHex / fromHex when available
1 parent 3c2f472 commit 663da12

File tree

1 file changed

+22
-10
lines changed

1 file changed

+22
-10
lines changed

src/abstract/utils.ts

+22-10
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,34 @@ export function abool(title: string, value: boolean): void {
3333
if (typeof value !== 'boolean') throw new Error(title + ' boolean expected, got ' + value);
3434
}
3535

36+
export function numberToHexUnpadded(num: number | bigint): string {
37+
const hex = num.toString(16);
38+
return hex.length & 1 ? '0' + hex : hex;
39+
}
40+
41+
export function hexToNumber(hex: string): bigint {
42+
if (typeof hex !== 'string') throw new Error('hex string expected, got ' + typeof hex);
43+
return hex === '' ? _0n : BigInt('0x' + hex); // Big Endian
44+
}
45+
46+
// Built-in hex conversion https://caniuse.com/mdn-javascript_builtins_uint8array_fromhex
47+
const hasHexBuiltin: boolean =
48+
// @ts-ignore
49+
typeof Uint8Array.from([]).toHex === 'function' && typeof Uint8Array.fromHex === 'function';
50+
3651
// Array where index 0xf0 (240) is mapped to string 'f0'
3752
const hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) =>
3853
i.toString(16).padStart(2, '0')
3954
);
55+
4056
/**
57+
* Convert byte array to hex string. Uses built-in function, when available.
4158
* @example bytesToHex(Uint8Array.from([0xca, 0xfe, 0x01, 0x23])) // 'cafe0123'
4259
*/
4360
export function bytesToHex(bytes: Uint8Array): string {
4461
abytes(bytes);
62+
// @ts-ignore
63+
if (hasHexBuiltin) return bytes.toHex();
4564
// pre-caching improves the speed 6x
4665
let hex = '';
4766
for (let i = 0; i < bytes.length; i++) {
@@ -50,16 +69,6 @@ export function bytesToHex(bytes: Uint8Array): string {
5069
return hex;
5170
}
5271

53-
export function numberToHexUnpadded(num: number | bigint): string {
54-
const hex = num.toString(16);
55-
return hex.length & 1 ? '0' + hex : hex;
56-
}
57-
58-
export function hexToNumber(hex: string): bigint {
59-
if (typeof hex !== 'string') throw new Error('hex string expected, got ' + typeof hex);
60-
return hex === '' ? _0n : BigInt('0x' + hex); // Big Endian
61-
}
62-
6372
// We use optimized technique to convert hex string to byte array
6473
const asciis = { _0: 48, _9: 57, A: 65, F: 70, a: 97, f: 102 } as const;
6574
function asciiToBase16(ch: number): number | undefined {
@@ -70,10 +79,13 @@ function asciiToBase16(ch: number): number | undefined {
7079
}
7180

7281
/**
82+
* Convert hex string to byte array. Uses built-in function, when available.
7383
* @example hexToBytes('cafe0123') // Uint8Array.from([0xca, 0xfe, 0x01, 0x23])
7484
*/
7585
export function hexToBytes(hex: string): Uint8Array {
7686
if (typeof hex !== 'string') throw new Error('hex string expected, got ' + typeof hex);
87+
// @ts-ignore
88+
if (hasHexBuiltin) return Uint8Array.fromHex(hex);
7789
const hl = hex.length;
7890
const al = hl / 2;
7991
if (hl % 2) throw new Error('hex string expected, got unpadded hex of length ' + hl);

0 commit comments

Comments
 (0)