UNPKG

@tbela99/css-parser

Version:

CSS parser, minifier and validator for node and the browser

87 lines (85 loc) 2.54 kB
// Alphabet: a-z, A-Z, 0-9, _, - const LOWER = "abcdefghijklmnopqrstuvwxyz"; const DIGITS = "0123456789"; const FULL_ALPHABET = (LOWER + DIGITS).split(""); // 64 chars const FIRST_ALPHABET = LOWER.split(""); // 54 chars (no digits) /** * supported hash algorithms */ const hashAlgorithms = ["hex", "base64", "base64url", "sha1", "sha256", "sha384", "sha512"]; // simple deterministic hash → number function hashCode(str) { let hash = 0; let l = str.length; let i = 0; while (i < l) { hash = (hash * 31 + str.charCodeAt(i++)) >>> 0; } return hash; } /** * generate a hash id * @param input * @param length */ function hashId(input, length = 6) { let n = hashCode(input); const chars = []; // First character: must not be a digit chars.push(FIRST_ALPHABET[n % FIRST_ALPHABET.length]); // Remaining characters for (let i = 1; i < length; i++) { n = (n + chars.length + i) % FULL_ALPHABET.length; chars.push(FULL_ALPHABET[n]); } return chars.join(""); } /** * convert input to hex * @param input */ function toHex(input) { let result = ""; if (input instanceof ArrayBuffer || ArrayBuffer.isView(input)) { for (const byte of Array.from(new Uint8Array(input))) { result += byte.toString(16).padStart(2, "0"); } } else { for (const char of String(input)) { result += char.charCodeAt(0).toString(16).padStart(2, "0"); } } return result; } /** * generate a hash * @param input * @param length * @param algo */ async function hash(input, length = 6, algo) { let result; if (algo != null) { switch (algo) { case "hex": return toHex(input).slice(0, length); case "base64url": case "base64": result = btoa(input); if (algo == "base64url") { result = result.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, ""); } return result.slice(0, length); case "sha256": case "sha384": case "sha512": case "sha1": return toHex(await crypto.subtle.digest(algo.replace("sha", "SHA-"), new TextEncoder().encode(input))).slice(0, length); default: throw new Error(`Unsupported hash algorithm: ${algo}`); } } return hashId(input, length); } export { DIGITS, FIRST_ALPHABET, FULL_ALPHABET, LOWER, hash, hashAlgorithms, hashId };