UNPKG

@tldraw/utils

Version:

tldraw infinite canvas SDK (private utilities).

8 lines (7 loc) 5.15 kB
{ "version": 3, "sources": ["../../src/lib/hash.ts"], "sourcesContent": ["/**\n * Hash a string using the FNV-1a algorithm.\n *\n * Generates a deterministic hash value for a given string using a variant of the FNV-1a\n * (Fowler-Noll-Vo) algorithm. The hash is returned as a string representation of a 32-bit integer.\n *\n * @param string - The input string to hash\n * @returns A string representation of the 32-bit hash value\n * @example\n * ```ts\n * const hash = getHashForString('hello world')\n * console.log(hash) // '-862545276'\n *\n * // Same input always produces same hash\n * const hash2 = getHashForString('hello world')\n * console.log(hash === hash2) // true\n * ```\n * @public\n */\nexport function getHashForString(string: string) {\n\tlet hash = 0\n\tfor (let i = 0; i < string.length; i++) {\n\t\thash = (hash << 5) - hash + string.charCodeAt(i)\n\t\thash |= 0 // Convert to 32bit integer\n\t}\n\treturn hash + ''\n}\n\n/**\n * Hash an object by converting it to JSON and then hashing the resulting string.\n *\n * Converts the object to a JSON string using JSON.stringify and then applies the same\n * hashing algorithm as getHashForString. Useful for creating consistent hash values\n * for objects, though the hash depends on JSON serialization order.\n *\n * @param obj - The object to hash (any JSON-serializable value)\n * @returns A string representation of the 32-bit hash value\n * @example\n * ```ts\n * const hash1 = getHashForObject({ name: 'John', age: 30 })\n * const hash2 = getHashForObject({ name: 'John', age: 30 })\n * console.log(hash1 === hash2) // true\n *\n * // Arrays work too\n * const arrayHash = getHashForObject([1, 2, 3, 'hello'])\n * console.log(arrayHash) // '-123456789'\n * ```\n * @public\n */\nexport function getHashForObject(obj: any) {\n\treturn getHashForString(JSON.stringify(obj))\n}\n\n/**\n * Hash an ArrayBuffer using the FNV-1a algorithm.\n *\n * Generates a deterministic hash value for binary data stored in an ArrayBuffer.\n * Processes the buffer byte by byte using the same hashing algorithm as getHashForString.\n * Useful for creating consistent identifiers for binary data like images or files.\n *\n * @param buffer - The ArrayBuffer containing binary data to hash\n * @returns A string representation of the 32-bit hash value\n * @example\n * ```ts\n * // Hash some binary data\n * const data = new Uint8Array([1, 2, 3, 4, 5])\n * const hash = getHashForBuffer(data.buffer)\n * console.log(hash) // '123456789'\n *\n * // Hash image file data\n * const fileBuffer = await file.arrayBuffer()\n * const fileHash = getHashForBuffer(fileBuffer)\n * console.log(fileHash) // Unique hash for the file\n * ```\n * @public\n */\nexport function getHashForBuffer(buffer: ArrayBuffer) {\n\tconst view = new DataView(buffer)\n\tlet hash = 0\n\tfor (let i = 0; i < view.byteLength; i++) {\n\t\thash = (hash << 5) - hash + view.getUint8(i)\n\t\thash |= 0 // Convert to 32bit integer\n\t}\n\treturn hash + ''\n}\n\n/**\n * Applies a string transformation algorithm that rearranges and modifies characters.\n *\n * Performs a series of character manipulations on the input string including\n * character repositioning through splicing operations and numeric character transformations.\n * This appears to be a custom encoding/obfuscation function.\n *\n * @param str - The input string to transform\n * @returns The transformed string after applying all manipulations\n * @example\n * ```ts\n * const result = lns('hello123')\n * console.log(result) // Transformed string (exact output depends on algorithm)\n *\n * // Can be used for simple string obfuscation\n * const obfuscated = lns('sensitive-data')\n * console.log(obfuscated) // Obfuscated version\n * ```\n * @public\n */\nexport function lns(str: string) {\n\tconst result = str.split('')\n\tresult.push(...result.splice(0, Math.round(result.length / 5)))\n\tresult.push(...result.splice(0, Math.round(result.length / 4)))\n\tresult.push(...result.splice(0, Math.round(result.length / 3)))\n\tresult.push(...result.splice(0, Math.round(result.length / 2)))\n\treturn result\n\t\t.reverse()\n\t\t.map((n) => (+n ? (+n < 5 ? 5 + +n : +n > 5 ? +n - 5 : n) : n))\n\t\t.join('')\n}\n"], "mappings": "AAmBO,SAAS,iBAAiB,QAAgB;AAChD,MAAI,OAAO;AACX,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACvC,YAAQ,QAAQ,KAAK,OAAO,OAAO,WAAW,CAAC;AAC/C,YAAQ;AAAA,EACT;AACA,SAAO,OAAO;AACf;AAuBO,SAAS,iBAAiB,KAAU;AAC1C,SAAO,iBAAiB,KAAK,UAAU,GAAG,CAAC;AAC5C;AAyBO,SAAS,iBAAiB,QAAqB;AACrD,QAAM,OAAO,IAAI,SAAS,MAAM;AAChC,MAAI,OAAO;AACX,WAAS,IAAI,GAAG,IAAI,KAAK,YAAY,KAAK;AACzC,YAAQ,QAAQ,KAAK,OAAO,KAAK,SAAS,CAAC;AAC3C,YAAQ;AAAA,EACT;AACA,SAAO,OAAO;AACf;AAsBO,SAAS,IAAI,KAAa;AAChC,QAAM,SAAS,IAAI,MAAM,EAAE;AAC3B,SAAO,KAAK,GAAG,OAAO,OAAO,GAAG,KAAK,MAAM,OAAO,SAAS,CAAC,CAAC,CAAC;AAC9D,SAAO,KAAK,GAAG,OAAO,OAAO,GAAG,KAAK,MAAM,OAAO,SAAS,CAAC,CAAC,CAAC;AAC9D,SAAO,KAAK,GAAG,OAAO,OAAO,GAAG,KAAK,MAAM,OAAO,SAAS,CAAC,CAAC,CAAC;AAC9D,SAAO,KAAK,GAAG,OAAO,OAAO,GAAG,KAAK,MAAM,OAAO,SAAS,CAAC,CAAC,CAAC;AAC9D,SAAO,OACL,QAAQ,EACR,IAAI,CAAC,MAAO,CAAC,IAAK,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,IAAI,IAAK,CAAE,EAC7D,KAAK,EAAE;AACV;", "names": [] }