Skip to content

Commit

Permalink
hex-byte fns
Browse files Browse the repository at this point in the history
  • Loading branch information
Brord van Wierst committed Oct 4, 2023
1 parent 99ad3fc commit bc523c0
Show file tree
Hide file tree
Showing 3 changed files with 136 additions and 1 deletion.
104 changes: 104 additions & 0 deletions bindings/nodejs/lib/utils/converter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/**
* Convert arrays to and from different formats.
*/
export class Converter {
/**
* Lookup table for encoding.
* @internal
*/
private static ENCODE_LOOKUP: string[] | undefined;

/**
* Lookup table for decoding.
* @internal
*/
private static DECODE_LOOKUP: number[] | undefined;

/**
* Encode a raw array to hex string.
* @param array The bytes to encode.
* @param includePrefix Include the 0x prefix on the returned hex.
* @param startIndex The index to start in the bytes.
* @param length The length of bytes to read.
* @param reverse Reverse the combine direction.
* @returns The array formated as hex.
*/
public static bytesToHex(
array: ArrayLike<number>,
includePrefix: boolean = false,
startIndex?: number,
length?: number | undefined,
reverse?: boolean,
): string {
let hex = '';
this.buildHexLookups();
if (Converter.ENCODE_LOOKUP) {
const len = length ?? array.length;
const start = startIndex ?? 0;
if (reverse) {
for (let i = 0; i < len; i++) {
hex = Converter.ENCODE_LOOKUP[array[start + i]] + hex;
}
} else {
for (let i = 0; i < len; i++) {
hex += Converter.ENCODE_LOOKUP[array[start + i]];
}
}
}
return includePrefix ? hex.replace(/^0x/, '') : hex;
}

/**
* Decode a hex string to raw array.
* @param hex The hex to decode.
* @param reverse Store the characters in reverse.
* @returns The array.
*/
public static hexToBytes(hex: string, reverse?: boolean): Uint8Array {
const strippedHex = hex.replace(/^0x/, '');
const sizeof = strippedHex.length >> 1;
const length = sizeof << 1;
const array = new Uint8Array(sizeof);

this.buildHexLookups();
if (Converter.DECODE_LOOKUP) {
let i = 0;
let n = 0;
while (i < length) {
array[n++] =
(Converter.DECODE_LOOKUP[strippedHex.charCodeAt(i++)] <<
4) |
Converter.DECODE_LOOKUP[strippedHex.charCodeAt(i++)];
}

if (reverse) {
array.reverse();
}
}
return array;
}

/**
* Build the static lookup tables.
* @internal
*/
private static buildHexLookups(): void {
if (!Converter.ENCODE_LOOKUP) {
const alphabet = '0123456789abcdef';
Converter.ENCODE_LOOKUP = [];
Converter.DECODE_LOOKUP = [];

for (let i = 0; i < 256; i++) {
Converter.ENCODE_LOOKUP[i] =
alphabet[(i >> 4) & 0xf] + alphabet[i & 0xf];
if (i < 16) {
if (i < 10) {
Converter.DECODE_LOOKUP[0x30 + i] = i;
} else {
Converter.DECODE_LOOKUP[0x61 - 10 + i] = i;
}
}
}
}
}
}
31 changes: 31 additions & 0 deletions bindings/nodejs/lib/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,34 @@
export * from './utf8';
export * from './utils';
export * from '../types/utils';

/**
* Converts a byte array to a hexadecimal string.
*
* @param {Uint8Array} byteArray - The bytes to encode.
* @param {boolean} [prefix=false] - Whether to include the '0x' prefix in the resulting hexadecimal string.
* @returns {string} The hexadecimal representation of the input byte array.
*/
export const bytesToHex = (bytes: ArrayLike<number>, prefix = false) => {
const hexArray = Array.from(bytes, (byte) =>
byte.toString(16).padStart(2, '0'),
);
const hexString = hexArray.join('');
return prefix ? '0x' + hexString : hexString;
};

/**
* Converts a hexadecimal string to a Uint8Array byte array.
*
* @param {string} hexString - The hexadecimal string to be converted.
* @returns {Uint8Array} The Uint8Array byte array representation of the input hexadecimal string.
* @throws {Error} Will throw an error if the input string is not a valid hexadecimal string.
*/
export const hexToBytes = (hexString: string) => {
const hex = hexString.replace(/^0x/, '');
const bytes = [];
for (let i = 0; i < hex.length; i += 2) {
bytes.push(parseInt(hex.substr(i, 2), 16));
}
return new Uint8Array(bytes);
};
2 changes: 1 addition & 1 deletion bindings/nodejs/lib/utils/utf8.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export const utf8ToBytes = (utf8: string) => {

/** Convert hex encoded string to UTF8 string */
export const hexToUtf8 = (hex: HexEncodedString) =>
decodeURIComponent(hex.replace('0x', '').replace(/[0-9a-f]{2}/g, '%$&'));
decodeURIComponent(hex.replace(/^0x/, '').replace(/[0-9a-f]{2}/g, '%$&'));

/** Convert UTF8 string to hex encoded string */
export const utf8ToHex = (utf8: string) =>
Expand Down

0 comments on commit bc523c0

Please sign in to comment.