@fuzdev/fuz_util 0.48.2 → 0.48.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/hash.d.ts +27 -0
- package/dist/hash.d.ts.map +1 -0
- package/dist/hash.js +66 -0
- package/package.json +6 -6
- package/src/lib/hash.ts +73 -0
package/dist/hash.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hash utilities for content comparison and cache invalidation.
|
|
3
|
+
*
|
|
4
|
+
* Provides both secure (cryptographic) and insecure (fast) hash functions.
|
|
5
|
+
*
|
|
6
|
+
* @module
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Computes a cryptographic hash using Web Crypto API.
|
|
10
|
+
*
|
|
11
|
+
* @param data - String or binary data to hash. Strings are UTF-8 encoded.
|
|
12
|
+
* @param algorithm - Hash algorithm. Defaults to SHA-256.
|
|
13
|
+
* @returns Hexadecimal hash string.
|
|
14
|
+
*/
|
|
15
|
+
export declare const hash_secure: (data: BufferSource | string, algorithm?: "SHA-256" | "SHA-384" | "SHA-512") => Promise<string>;
|
|
16
|
+
/**
|
|
17
|
+
* Computes a fast non-cryptographic hash using DJB2 algorithm.
|
|
18
|
+
* Use for content comparison and cache keys, not security.
|
|
19
|
+
*
|
|
20
|
+
* Note: Strings use UTF-16 code units, buffers use raw bytes.
|
|
21
|
+
* For non-ASCII, `hash_insecure(str) !== hash_insecure(encoder.encode(str))`.
|
|
22
|
+
*
|
|
23
|
+
* @param data - String or binary data to hash.
|
|
24
|
+
* @returns 8-character hex-encoded unsigned 32-bit hash.
|
|
25
|
+
*/
|
|
26
|
+
export declare const hash_insecure: (data: BufferSource | string) => string;
|
|
27
|
+
//# sourceMappingURL=hash.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hash.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/hash.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAgBH;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,GACvB,MAAM,YAAY,GAAG,MAAM,EAC3B,YAAW,SAAS,GAAG,SAAS,GAAG,SAAqB,KACtD,OAAO,CAAC,MAAM,CAUhB,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,aAAa,GAAI,MAAM,YAAY,GAAG,MAAM,KAAG,MAkB3D,CAAC"}
|
package/dist/hash.js
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hash utilities for content comparison and cache invalidation.
|
|
3
|
+
*
|
|
4
|
+
* Provides both secure (cryptographic) and insecure (fast) hash functions.
|
|
5
|
+
*
|
|
6
|
+
* @module
|
|
7
|
+
*/
|
|
8
|
+
const encoder = new TextEncoder();
|
|
9
|
+
// Lazily computed lookup table for byte to hex conversion
|
|
10
|
+
let byte_to_hex;
|
|
11
|
+
const get_byte_to_hex = () => {
|
|
12
|
+
if (byte_to_hex === undefined) {
|
|
13
|
+
byte_to_hex = new Array(256); // 256 possible byte values (0x00-0xff)
|
|
14
|
+
for (let i = 0; i < 256; i++) {
|
|
15
|
+
byte_to_hex[i] = i.toString(16).padStart(2, '0');
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return byte_to_hex;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Computes a cryptographic hash using Web Crypto API.
|
|
22
|
+
*
|
|
23
|
+
* @param data - String or binary data to hash. Strings are UTF-8 encoded.
|
|
24
|
+
* @param algorithm - Hash algorithm. Defaults to SHA-256.
|
|
25
|
+
* @returns Hexadecimal hash string.
|
|
26
|
+
*/
|
|
27
|
+
export const hash_secure = async (data, algorithm = 'SHA-256') => {
|
|
28
|
+
const buffer = typeof data === 'string' ? encoder.encode(data) : data;
|
|
29
|
+
const digested = await crypto.subtle.digest(algorithm, buffer);
|
|
30
|
+
const bytes = new Uint8Array(digested);
|
|
31
|
+
const lookup = get_byte_to_hex();
|
|
32
|
+
let hex = '';
|
|
33
|
+
for (const byte of bytes) {
|
|
34
|
+
hex += lookup[byte];
|
|
35
|
+
}
|
|
36
|
+
return hex;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Computes a fast non-cryptographic hash using DJB2 algorithm.
|
|
40
|
+
* Use for content comparison and cache keys, not security.
|
|
41
|
+
*
|
|
42
|
+
* Note: Strings use UTF-16 code units, buffers use raw bytes.
|
|
43
|
+
* For non-ASCII, `hash_insecure(str) !== hash_insecure(encoder.encode(str))`.
|
|
44
|
+
*
|
|
45
|
+
* @param data - String or binary data to hash.
|
|
46
|
+
* @returns 8-character hex-encoded unsigned 32-bit hash.
|
|
47
|
+
*/
|
|
48
|
+
export const hash_insecure = (data) => {
|
|
49
|
+
let hash = 5381; // DJB2 initial value, chosen empirically for good distribution
|
|
50
|
+
if (typeof data === 'string') {
|
|
51
|
+
for (let i = 0; i < data.length; i++) {
|
|
52
|
+
hash = (hash << 5) - hash + data.charCodeAt(i);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
const bytes = data instanceof Uint8Array
|
|
57
|
+
? data
|
|
58
|
+
: data instanceof ArrayBuffer
|
|
59
|
+
? new Uint8Array(data)
|
|
60
|
+
: new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
|
|
61
|
+
for (const byte of bytes) {
|
|
62
|
+
hash = (hash << 5) - hash + byte;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return (hash >>> 0).toString(16).padStart(8, '0');
|
|
66
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fuzdev/fuz_util",
|
|
3
|
-
"version": "0.48.
|
|
3
|
+
"version": "0.48.3",
|
|
4
4
|
"description": "utility belt for JS",
|
|
5
5
|
"glyph": "🦕",
|
|
6
6
|
"logo": "logo.svg",
|
|
@@ -61,9 +61,9 @@
|
|
|
61
61
|
},
|
|
62
62
|
"devDependencies": {
|
|
63
63
|
"@changesets/changelog-git": "^0.2.1",
|
|
64
|
-
"@fuzdev/fuz_code": "^0.
|
|
65
|
-
"@fuzdev/fuz_css": "^0.
|
|
66
|
-
"@fuzdev/fuz_ui": "^0.
|
|
64
|
+
"@fuzdev/fuz_code": "^0.41.0",
|
|
65
|
+
"@fuzdev/fuz_css": "^0.45.0",
|
|
66
|
+
"@fuzdev/fuz_ui": "^0.180.0",
|
|
67
67
|
"@ryanatkn/eslint-config": "^0.9.0",
|
|
68
68
|
"@ryanatkn/gro": "^0.189.3",
|
|
69
69
|
"@sveltejs/adapter-static": "^3.0.10",
|
|
@@ -79,8 +79,8 @@
|
|
|
79
79
|
"fast-deep-equal": "^3.1.3",
|
|
80
80
|
"prettier": "^3.7.4",
|
|
81
81
|
"prettier-plugin-svelte": "^3.4.1",
|
|
82
|
-
"svelte": "^5.48.
|
|
83
|
-
"svelte-check": "^4.3.
|
|
82
|
+
"svelte": "^5.48.5",
|
|
83
|
+
"svelte-check": "^4.3.5",
|
|
84
84
|
"tslib": "^2.8.1",
|
|
85
85
|
"typescript": "^5.9.3",
|
|
86
86
|
"typescript-eslint": "^8.48.1",
|
package/src/lib/hash.ts
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hash utilities for content comparison and cache invalidation.
|
|
3
|
+
*
|
|
4
|
+
* Provides both secure (cryptographic) and insecure (fast) hash functions.
|
|
5
|
+
*
|
|
6
|
+
* @module
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
const encoder = new TextEncoder();
|
|
10
|
+
|
|
11
|
+
// Lazily computed lookup table for byte to hex conversion
|
|
12
|
+
let byte_to_hex: Array<string> | undefined;
|
|
13
|
+
const get_byte_to_hex = (): Array<string> => {
|
|
14
|
+
if (byte_to_hex === undefined) {
|
|
15
|
+
byte_to_hex = new Array(256); // 256 possible byte values (0x00-0xff)
|
|
16
|
+
for (let i = 0; i < 256; i++) {
|
|
17
|
+
byte_to_hex[i] = i.toString(16).padStart(2, '0');
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return byte_to_hex;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Computes a cryptographic hash using Web Crypto API.
|
|
25
|
+
*
|
|
26
|
+
* @param data - String or binary data to hash. Strings are UTF-8 encoded.
|
|
27
|
+
* @param algorithm - Hash algorithm. Defaults to SHA-256.
|
|
28
|
+
* @returns Hexadecimal hash string.
|
|
29
|
+
*/
|
|
30
|
+
export const hash_secure = async (
|
|
31
|
+
data: BufferSource | string,
|
|
32
|
+
algorithm: 'SHA-256' | 'SHA-384' | 'SHA-512' = 'SHA-256',
|
|
33
|
+
): Promise<string> => {
|
|
34
|
+
const buffer = typeof data === 'string' ? encoder.encode(data) : data;
|
|
35
|
+
const digested = await crypto.subtle.digest(algorithm, buffer);
|
|
36
|
+
const bytes = new Uint8Array(digested);
|
|
37
|
+
const lookup = get_byte_to_hex();
|
|
38
|
+
let hex = '';
|
|
39
|
+
for (const byte of bytes) {
|
|
40
|
+
hex += lookup[byte];
|
|
41
|
+
}
|
|
42
|
+
return hex;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Computes a fast non-cryptographic hash using DJB2 algorithm.
|
|
47
|
+
* Use for content comparison and cache keys, not security.
|
|
48
|
+
*
|
|
49
|
+
* Note: Strings use UTF-16 code units, buffers use raw bytes.
|
|
50
|
+
* For non-ASCII, `hash_insecure(str) !== hash_insecure(encoder.encode(str))`.
|
|
51
|
+
*
|
|
52
|
+
* @param data - String or binary data to hash.
|
|
53
|
+
* @returns 8-character hex-encoded unsigned 32-bit hash.
|
|
54
|
+
*/
|
|
55
|
+
export const hash_insecure = (data: BufferSource | string): string => {
|
|
56
|
+
let hash = 5381; // DJB2 initial value, chosen empirically for good distribution
|
|
57
|
+
if (typeof data === 'string') {
|
|
58
|
+
for (let i = 0; i < data.length; i++) {
|
|
59
|
+
hash = (hash << 5) - hash + data.charCodeAt(i);
|
|
60
|
+
}
|
|
61
|
+
} else {
|
|
62
|
+
const bytes: Uint8Array =
|
|
63
|
+
data instanceof Uint8Array
|
|
64
|
+
? data
|
|
65
|
+
: data instanceof ArrayBuffer
|
|
66
|
+
? new Uint8Array(data)
|
|
67
|
+
: new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
|
|
68
|
+
for (const byte of bytes) {
|
|
69
|
+
hash = (hash << 5) - hash + byte;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return (hash >>> 0).toString(16).padStart(8, '0');
|
|
73
|
+
};
|