UNPKG

libnexa-ts

Version:

A pure and powerful Nexa SDK library.

223 lines (196 loc) 6.13 kB
import CommonUtils from "./common.utils"; import ValidationUtils from "./validation.utils"; import * as base64 from "base64-js"; export default class BufferUtils { /** * Tests for both node's Buffer and Uint8Array * * @param arg * @return Returns true if the given argument is an instance of a Uint8Array. */ public static isBuffer(arg: unknown): arg is Uint8Array { return arg instanceof Uint8Array; } /** * Tests for both node's Buffer and Uint8Array * * @param arg * @return Returns true if the given argument is an instance of a hash160 or hash256 buffer. */ public static isHashBuffer(arg: unknown): boolean { return this.isBuffer(arg) && (arg.length === 20 || arg.length === 32); } /** * Reverse a Uint8Array * @param param * @return new reversed Uint8Array */ public static reverse(param: Uint8Array): Uint8Array { return Uint8Array.from(param).reverse(); } /** * Convert a Uint8Array to a UTF-8 string. * * @param buffer - Uint8Array containing UTF-8 encoded bytes * @returns Decoded string */ public static bufferToUtf8(buffer: Uint8Array): string { return new TextDecoder("utf-8").decode(buffer); } /** * Convert a UTF-8 string to a Uint8Array. * * @param str - UTF-8 string * @returns Encoded Uint8Array */ public static utf8ToBuffer(str: string): Uint8Array { return new TextEncoder().encode(str); } /** * Convert a Uint8Array to a Base64 string. * * @param buffer - Uint8Array containing Base64 encoded bytes * @returns Decoded string */ public static bufferToBase64(buffer: Uint8Array): string { return base64.fromByteArray(buffer); } /** * Convert a Base64 string to a Uint8Array. * * @param str - Base64 string * @returns Encoded Uint8Array */ public static base64ToBuffer(str: string): Uint8Array { return base64.toByteArray(str); } /** * Transforms a buffer into a string with a number in hexa representation * * Similar for <tt>buffer.toString('hex')</tt> * * @param buffer * @return string */ public static bufferToHex(buffer: Uint8Array): string { ValidationUtils.validateArgumentType(buffer, Uint8Array, 'buffer'); return Array.from(buffer) .map(b => b.toString(16).padStart(2, '0')) .join(''); } /** * Convert a hexadecimal string into a Uint8Array. * * @param hex - Hex string (must have even length) * @returns Uint8Array representing the bytes */ public static hexToBuffer(hex: string): Uint8Array { if (!CommonUtils.isHexa(hex)) { return new Uint8Array(); } const length = hex.length / 2; const bytes = new Uint8Array(length); for (let i = 0; i < length; i++) { bytes[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16); } return bytes; } /** * Concatenate multiple Uint8Arrays into a single Uint8Array. * * Mimics Node.js Buffer.concat(list, totalLength?): * - list: Array of Uint8Arrays * - totalLength: Optional precomputed total length * * @param list - Array of Uint8Arrays to concatenate * @param totalLength - Optional total length to preallocate * @returns New Uint8Array containing all bytes from input arrays * * @example * const a = new Uint8Array([1,2]); * const b = new Uint8Array([3,4]); * const result = Uint8ArrayUtils.concat([a,b]); * console.log(result); // Uint8Array(4) [1,2,3,4] */ public static concat(list: Uint8Array[], totalLength?: number): Uint8Array { const length = totalLength ?? list.reduce((sum, arr) => sum + arr.length, 0); const result = new Uint8Array(length); let offset = 0; for (const arr of list) { result.set(arr, offset); offset += arr.length; } return result; } /** * Compares two Uint8Arrays for byte-wise equality. * * This function checks whether the two arrays have the same length * and the same content. * * @param a - The first Uint8Array to compare. * @param b - The second Uint8Array to compare. * @returns `true` if the arrays have the same length and contents, `false` otherwise. */ public static equals(a: Uint8Array, b: Uint8Array): boolean { if (a === b) return true; if (a.byteLength !== b.byteLength) return false; for (let i = 0; i < a.byteLength; i++) { if (a[i] !== b[i]) return false; } return true; } /** * Transforms a number from 0 to 255 into a Uint8Array of size 1 with that value * * @param integer * @return Uint8Array */ public static integerAsSingleByteBuffer(integer: number): Uint8Array { ValidationUtils.validateArgumentType(integer, 'number', 'integer'); return new Uint8Array([integer & 0xff]); } /** * Transforms the first byte of an array into a number ranging from -128 to 127 * * @param buffer * @return number */ public static integerFromSingleByteBuffer(buffer: Uint8Array): number { ValidationUtils.validateArgumentType(buffer, Uint8Array, 'buffer'); return buffer[0]; } /** * Transform a 4-byte integer into a Uint8Array of length 4. * * @param integer * @return Uint8Array */ public static integerAsBuffer(integer: number): Uint8Array { ValidationUtils.validateArgumentType(integer, 'number', 'integer'); const bytes = new Uint8Array(4); bytes[0] = (integer >> 24) & 0xff; bytes[1] = (integer >> 16) & 0xff; bytes[2] = (integer >> 8) & 0xff; bytes[3] = integer & 0xff; return bytes; } /** * Transform the first 4 values of a Uint8Array into a number, in little endian encoding * * @param buffer * @return integer */ public static integerFromBuffer(buffer: Uint8Array): number { ValidationUtils.validateArgumentType(buffer, Uint8Array, 'buffer'); return buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3]; } /** * @return secure random bytes */ public static getRandomBuffer(size: number): Uint8Array { const bytes = new Uint8Array(size); crypto.getRandomValues(bytes); return bytes; } }