UNPKG

nehoid

Version:

Advanced unique ID generation utility with multi-layer encoding, collision detection, and context-aware features

197 lines 8.61 kB
import { __processor__ } from "nehonix-uri-processor"; export class Encoder { static async encode(input, encodings) { const encodingArray = Array.isArray(encodings) ? encodings : [encodings]; let result = input; const enc = await __processor__.encodeMultipleAsync(result, encodingArray); result = enc.results[enc.results.length - 1].encoded; return result; } static decode(input, encodings, opt) { const encodingArray = Array.isArray(encodings) ? encodings : [encodings]; let result = input; // Decode in reverse order for (const encoding of encodingArray.reverse()) { if (opt?.autoDetect) { result = __processor__.autoDetectAndDecode(result).val(); } else { result = __processor__.decode(result, encoding); } } return result; } static compress(input, method) { if (!input) return ""; switch (method) { case "lz77": // Basic LZ77-inspired compression let compressed = ""; let i = 0; while (i < input.length) { // Look for repeated sequences let maxLength = 0; let maxOffset = 0; // Search window (limited to previous 255 chars for simplicity) const searchLimit = Math.min(i, 255); for (let offset = 1; offset <= searchLimit; offset++) { let length = 0; while (i + length < input.length && input[i - offset + length] === input[i + length] && length < 255 // Limit match length ) { length++; } if (length > maxLength) { maxLength = length; maxOffset = offset; } } if (maxLength >= 4) { // Only use compression for sequences of 4+ chars // Format: <flag><offset><length><next char> compressed += String.fromCharCode(0xff); // Flag for compressed sequence compressed += String.fromCharCode(maxOffset); compressed += String.fromCharCode(maxLength); i += maxLength; } else { // Literal character if (input.charCodeAt(i) === 0xff) { // Escape the flag character compressed += String.fromCharCode(0xff) + String.fromCharCode(0); } else { compressed += input[i]; } i++; } } return btoa(compressed); // Base64 encode for safe storage case "gzip": // For gzip, we'll use a dictionary-based approach since we can't use native gzip in browser const dictionary = {}; let nextCode = 256; // Start after ASCII let result = []; // Initialize dictionary with single characters for (let i = 0; i < 256; i++) { dictionary[String.fromCharCode(i)] = i; } let currentSequence = ""; for (let i = 0; i < input.length; i++) { const char = input[i]; const newSequence = currentSequence + char; if (dictionary[newSequence] !== undefined) { currentSequence = newSequence; } else { // Output code for current sequence result.push(dictionary[currentSequence]); // Add new sequence to dictionary if there's room if (nextCode < 65536) { // Limit dictionary size dictionary[newSequence] = nextCode++; } currentSequence = char; } } // Output code for remaining sequence if (currentSequence !== "") { result.push(dictionary[currentSequence]); } // Convert to string and base64 encode return btoa(result.map((code) => String.fromCharCode(code)).join("")); default: return input; } } static decompress(input, method) { if (!input) return ""; switch (method) { case "lz77": try { // Base64 decode const compressed = atob(input); let decompressed = ""; let i = 0; while (i < compressed.length) { if (compressed.charCodeAt(i) === 0xff) { i++; if (i < compressed.length && compressed.charCodeAt(i) === 0) { // Escaped flag character decompressed += String.fromCharCode(0xff); i++; } else if (i + 1 < compressed.length) { // Compressed sequence const offset = compressed.charCodeAt(i); const length = compressed.charCodeAt(i + 1); i += 2; // Copy sequence from already decompressed data const start = decompressed.length - offset; for (let j = 0; j < length; j++) { decompressed += decompressed[start + j]; } } } else { // Literal character decompressed += compressed[i]; i++; } } return decompressed; } catch (e) { console.error("LZ77 decompression error:", e); return input; } case "gzip": try { // Base64 decode const compressed = atob(input); const codes = Array.from(compressed).map((char) => char.charCodeAt(0)); // Initialize dictionary with single characters const dictionary = []; for (let i = 0; i < 256; i++) { dictionary[i] = String.fromCharCode(i); } let nextCode = 256; let result = ""; let oldCode = codes[0]; let character = dictionary[oldCode]; result = character; for (let i = 1; i < codes.length; i++) { const code = codes[i]; let entry; if (code < dictionary.length) { entry = dictionary[code]; } else if (code === nextCode) { entry = character + character[0]; } else { throw new Error("Invalid code"); } result += entry; // Add to dictionary if (nextCode < 65536) { // Limit dictionary size dictionary[nextCode++] = character + entry[0]; } character = entry; } return result; } catch (e) { console.error("Dictionary decompression error:", e); return input; } default: return input; } } } //# sourceMappingURL=encoder.js.map