]> git.codecow.com Git - libnemo.git/commitdiff
Refactor hex converter to merge array with byte converter, fix minimum padding, limit...
authorChris Duncan <chris@codecow.com>
Tue, 30 Jun 2026 20:53:19 +0000 (13:53 -0700)
committerChris Duncan <chris@codecow.com>
Tue, 30 Jun 2026 20:53:19 +0000 (13:53 -0700)
src/lib/convert/hex.ts

index 43be081383daffa5376a92f233b722615f8680c1..b356de4539b37cf9ff5867d54b3cf5b1f1c7c197 100644 (file)
@@ -1,62 +1,43 @@
 //! SPDX-FileCopyrightText: 2025 Chris Duncan <chris@codecow.com>
 //! SPDX-License-Identifier: GPL-3.0-or-later
 
-import { dec } from './dec'
-
 export const hex = Object.freeze({
-       /**
-        * Convert a hexadecimal string to an array of decimal byte values.
-        *
-        * @param {string} hex - Hexadecimal number string to convert
-        * @param {number}[padding=0] - Minimum length of the resulting array padded as necessary with starting 0 values
-        * @returns {number[]} Decimal array representation of the input value
-        */
-       toArray (hex: string, padding: number = 0): number[] {
-               if (typeof hex !== 'string' || !/^[A-Fa-f0-9]+$/i.test(hex)) {
-                       throw new TypeError('Invalid string when converting hex to array', { cause: hex })
-               }
-               if (typeof padding !== 'number') {
-                       throw new TypeError('Invalid padding when converting hex to array', { cause: padding })
-               }
-               if ((hex.length & 1) !== 0) hex = `0${hex}`
-               const hexArray = hex.match(/.{2}/g)
-               if (hexArray == null) {
-                       throw new RangeError('Invalid hex string when converting to array', { cause: hexArray })
-               }
-               const diff = padding - hexArray.length
-               const pad = new Array(diff > 0 ? diff : 0).fill(0)
-               return pad.concat(hexArray.map(v => parseInt(v, 16)))
-       },
-
-       /**
-        * Convert a hexadecimal string to a binary string.
-        *
-        * @param {string} hex - Hexadecimal number string to convert
-        * @returns {string} Binary string representation of the input value
-        */
-       toBin (hex: string): string {
-               return [...hex].map(c => dec.toBin(parseInt(c, 16), 4)).join('')
-       },
-
        /**
         * Convert a hexadecimal string to an ArrayBuffer.
         *
         * @param {string} hex - Hexadecimal number string to convert
-        * @param {number} [padding=0] - Minimum length of the resulting array padded as necessary with starting 0x00 bytes
+        * @param {number} [padding=1] - Minimum length of the resulting array padded as necessary with starting 0x00 bytes
         * @returns {ArrayBuffer} Buffer representation of the input value
         */
-       toBuffer (hex: string, padding: number = 0): ArrayBuffer {
+       toBuffer (hex: string, padding: number = 1): ArrayBuffer {
                return this.toBytes(hex, padding).buffer
        },
 
        /**
-        * Convert a hexadecimal string to a Uint8Array of bytes.
+        * Convert a hexadecimal string to a Uint8Array of bytes. The result must be
+        * at least one byte and no more than 4 GiB.
         *
         * @param {string} hex - Hexadecimal number string to convert
-        * @param {number} [padding=0] - Minimum length of the resulting array padded as necessary with starting 0x00 bytes
+        * @param {number} [padding=1] - Minimum length of the resulting array padded as necessary with starting 0x00 bytes
         * @returns {Uint8Array} Byte array representation of the input value
         */
-       toBytes (hex: string, padding: number = 0): Uint8Array<ArrayBuffer> {
-               return new Uint8Array(this.toArray(hex, padding))
+       toBytes (hex: string, padding: number = 1): Uint8Array<ArrayBuffer> {
+               if (typeof hex !== 'string' || !/^[0-9a-f]+$/i.test(hex)) {
+                       throw new TypeError('Invalid string when converting hex to array', { cause: hex })
+               }
+               if (typeof padding !== 'number' || padding < 1 || padding > 0xffffffff) {
+                       throw new TypeError('Invalid padding when converting hex to array', { cause: padding })
+               }
+               if (hex.length & 1) hex = `0${hex}`
+               const hexArray = hex.match(/.{2}/g)
+               if (hexArray == null) {
+                       throw new RangeError('Invalid hex string when converting to array', { cause: hexArray })
+               }
+               const diff = padding - hexArray.length
+               const offset = diff & ~(diff >> 31)
+               const length = hexArray.length + offset
+               const bytes = new Uint8Array(length)
+               bytes.set(hex.match(/.{2}/g)?.map(b => parseInt(b, 16)) ?? [], offset)
+               return bytes
        },
 })