UNPKG

@safeheron/crypto-utils

Version:
193 lines 4.97 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Hex = void 0; const CryptoJS = require("crypto-js"); /** * @brief: pad with "0" if the hex.length === 1; no change otherwise. * - situation 1: * "1" => "01" * "f" => "0f" * * - situation 1: * "12" => "12" * "ff" => "ff" * @param hex */ function zero2(hex) { if (hex.length === 1) { return '0' + hex; } else if (hex.length === 2) { return hex; } else { throw "Invalid hex length: " + hex.length; } } class Hex { /** * Hex ===> Bytes: * "0100ff" => [0x01, 0x00, 0xff] * * @param hex */ static toBytes(hex) { let msg = hex.replace(/[^a-z0-9]+/ig, ''); msg = Hex.padEven(msg); let res = new Uint8Array(msg.length / 2); for (let i = 0; i < msg.length; i += 2) { res[i / 2] = parseInt(msg.slice(i, i + 2), 16); } return res; } /** * Bytes(Uint8Array) ===> Hex: * [0x01, 0x00, 0xff] => "0100ff" * * @param bytes */ static fromBytes(bytes) { var res = ''; if (bytes.length == 0) return res; for (var i = 0; i < bytes.length; i++) { res += zero2(bytes[i].toString(16)); } return res; } /** * Hex ===> CryptoJSBytes * * "1234" ===> 0x1234 * "123" ===> 0x0123 * "120" ===> 0x0120 * * Use the function to avoid the bugs in "crypto-js" * "123" ===> 0x1203 * "120" ===> 0x1200 * * More details for the bugs in "crypto-js": * - Problem 1 * const a = CryptoJS.enc.Hex.parse('d6021ef5d7cccd55cda318fe2bd47334bac0b699e4a6676f8d941f7706d3820') * const expected_a = a.toString(CryptoJS.enc.Hex) * console.log('expected_a:', expected_a) * * The result is: * expected_a: d6021ef5d7cccd55cda318fe2bd47334bac0b699e4a6676f8d941f7706d38200 * * - Problem 2 * const a = CryptoJS.enc.Hex.parse('d6021ef5d7cccd55cda318fe2bd47334bac0b699e4a6676f8d941f7706d3821') * const expected_a = a.toString(CryptoJS.enc.Hex) * console.log('expected_a:', expected_a) * * The result is: * expected_a: d6021ef5d7cccd55cda318fe2bd47334bac0b699e4a6676f8d941f7706d38201 * @param hex */ static toCryptoJSBytes(hex) { return CryptoJS.enc.Hex.parse(Hex.padEven(hex)); } /** * Bytes ===> Hex * @param bytes */ static fromCryptoJSBytes(bytes) { return CryptoJS.enc.Hex.stringify(bytes); } /** * Reverse hex string byte by byte. * "01234567" ===> "67452301" * @param hex */ static reverseHex(hex) { if (hex.length % 2 !== 0) { throw "Invalid hex: " + hex.length + ". Length of input hex must be even!"; } let bytes = Hex.toBytes(hex); var res = ''; for (let i = bytes.length - 1; i >= 0; i--) res += zero2(bytes[i].toString(16)); return res; } /** * Pad the hex string to the specified length * @param hex. For example "01020304" * @param expectedLen. For example 16 * @returns {*} For example "0000000001020304" */ static padLength(hex, expectedLen) { if (hex.length > expectedLen) { throw "Input hex is too long(" + hex.length + " chars). It should be no more than " + expectedLen + " chars according to specified expectedLen."; } while (expectedLen > hex.length) { hex = '0' + hex; } return hex; } /** * Pad to 64 chars long * @param hex * @returns {*} */ static pad64(hex) { return Hex.padLength(hex, 64); } /** * Pad to 32 chars long * @param hex * @returns {*} */ static pad32(hex) { return Hex.padLength(hex, 32); } /** * Pad to 16 chars long * "12345678" => "0000000012345678" * @param hex * @returns {*} */ static pad16(hex) { return Hex.padLength(hex, 16); } /** * Pad to 8 chars long * "1234567" => "01234567" * @param hex * @returns {*} */ static pad8(hex) { return Hex.padLength(hex, 8); } /** * Pad to 4 chars long * "1" => "0001" * @param hex * @returns {*} */ static pad4(hex) { return Hex.padLength(hex, 4); } /** * Pad to 2 chars long * "1" => "01" * @param hex * @returns {*} */ static pad2(hex) { return Hex.padLength(hex, 2); } /** * Pad to even chars. * "123" => "0123" * @param hex * @returns {*} */ static padEven(hex) { if (hex.length % 2 !== 0) { hex = '0' + hex; } return hex; } } exports.Hex = Hex; //# sourceMappingURL=hex.js.map