UNPKG

base53-encoder

Version:

A unique Base53 encoding scheme with 30-bit block and 5-bit segment encoding

219 lines (205 loc) 6.57 kB
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; } function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e) { t && (r = t); var n = 0, F = function () {}; return { s: F, n: function () { return n >= r.length ? { done: true } : { done: false, value: r[n++] }; }, e: function (r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = true, u = false; return { s: function () { t = t.call(r); }, n: function () { var r = t.next(); return a = r.done, r; }, e: function (r) { u = true, o = r; }, f: function () { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; } function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : undefined; } } /** * Base53 Encoding/Decoding Module * * A custom base encoding scheme that uses a 32-character encoding table * with 5-bit segments, creating a 30-bit block encoding strategy. * * @module Base53 */ /** * Encoding table for Base53 encoding * @type {string[]} * @private */ var encodeTable = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'a', 'b', 'c', 'd', 'e', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/']; /** * Binary mapping for each character in the encoding table * @type {string[]} * @private */ var binaryMapping = ['00000', '00001', '00010', '00011', '00100', '00101', '00110', '00111', '01000', '01001', '01010', '01011', '01100', '01101', '01110', '01111', '10000', '10001', '10010', '10011', '10100', '10101', '10110', '10111', '11000', '11001', '11010', '11011', '11100', '11101', '11110', '11111']; /** * Converts a string to its binary representation * * @param {string} str - Input string to convert * @returns {string} Binary string representation * @private */ function toBinaryString(str) { return str.split('').map(function (c) { return c.charCodeAt(0).toString(2).padStart(8, '0'); }).join(''); } /** * Converts a binary string back to its text representation * * @param {string} binStr - Binary string to convert * @returns {string} Decoded text string * @private */ function fromBinaryString(binStr) { var bytes = binStr.match(/.{8}/g) || []; return bytes.map(function (_byte) { return String.fromCharCode(parseInt(_byte, 2)); }).join(''); } /** * Encodes a string using Base53 encoding * * @param {string} input - Input string to encode * @returns {string} Base53 encoded string */ function base53_encode(input) { if (input.length === 0) return ''; var binaryString = toBinaryString(input); var blockSize = 30; // Block size in bits (6 segments of 5 bits each) // Pad binary string to a multiple of blockSize var paddingLength = (blockSize - binaryString.length % blockSize) % blockSize; var paddedBinaryString = binaryString + '0'.repeat(paddingLength); var encodedString = ''; for (var i = 0; i < paddedBinaryString.length; i += blockSize) { var block = paddedBinaryString.substr(i, blockSize); for (var j = 0; j < blockSize; j += 5) { var segment = block.substr(j, 5); var index = parseInt(segment, 2); encodedString += encodeTable[index]; } } return encodedString; } /** * Decodes a Base53 encoded string * * @param {string} encoded - Base53 encoded string to decode * @returns {string} Decoded original string */ function base53_decode(encoded) { if (encoded.length === 0) return ''; var binaryString = ''; var _iterator = _createForOfIteratorHelper(encoded), _step; try { for (_iterator.s(); !(_step = _iterator.n()).done;) { var _char = _step.value; var index = encodeTable.indexOf(_char); if (index === -1) throw new Error('Invalid character in encoded string'); binaryString += binaryMapping[index]; } // Remove trailing zeros } catch (err) { _iterator.e(err); } finally { _iterator.f(); } while (binaryString.length > 0 && binaryString.slice(-8) === '00000000') { binaryString = binaryString.slice(0, -8); } var byteString = binaryString.match(/.{8}/g) || []; return fromBinaryString(byteString.join('')); } /** * Generates a random string of specified length * * @param {number} length - Length of the random string * @returns {string} Generated random string */ function generateRandomString(length) { var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; var result = ''; var charactersLength = characters.length; for (var i = 0; i < length; i++) { result += characters.charAt(Math.floor(Math.random() * charactersLength)); } return result; } /** * Builds a 150-bit key using Base53 encoding * * @param {number} [numSegments=5] - Number of segments to generate * @param {number} [segmentLength=32] - Length of each random string segment * @returns {Object} Object containing raw, encoded, and decoded key */ function buildBase53Key() { var numSegments = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 5; var segmentLength = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 32; var rawKey = ''; for (var i = 0; i < numSegments; i++) { var randomString = generateRandomString(segmentLength); var encodedSegment = base53_encode(randomString); rawKey += encodedSegment; } var encodedKey = base53_encode(rawKey); var decodedKey = base53_decode(encodedKey); return { rawKey: rawKey, encodedKey: encodedKey, decodedKey: decodedKey }; } // Export the module's key functions var Base53 = { encode: base53_encode, decode: base53_decode, buildKey: buildBase53Key }; export { Base53, Base53 as default };