@philiprehberger/hash-kit 0.1.0
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/LICENSE +21 -0
- package/README.md +34 -0
- package/dist/index.cjs +100 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +21 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.js +92 -0
- package/dist/index.js.map +1 -0
- package/package.json +31 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 philiprehberger
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# @philiprehberger/hash-kit
|
|
2
|
+
|
|
3
|
+
Simple cross-platform hashing utilities.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @philiprehberger/hash-kit
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import { hash } from '@philiprehberger/hash-kit';
|
|
15
|
+
|
|
16
|
+
const checksum = hash.murmur3('cache-key'); // sync, fast
|
|
17
|
+
const digest = await hash.sha256('hello'); // cross-platform
|
|
18
|
+
const sig = await hash.hmac(secret, payload, 'SHA-256'); // HMAC
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## API
|
|
22
|
+
|
|
23
|
+
| Function | Description |
|
|
24
|
+
|----------|-------------|
|
|
25
|
+
| `hash.murmur3(input, seed?)` | MurmurHash3 (sync) |
|
|
26
|
+
| `hash.sha256(input)` | SHA-256 via Web Crypto |
|
|
27
|
+
| `hash.sha512(input)` | SHA-512 via Web Crypto |
|
|
28
|
+
| `hash.hmac(key, data, algorithm?)` | HMAC signing |
|
|
29
|
+
| `toHex(buffer)` | ArrayBuffer to hex string |
|
|
30
|
+
| `toUint8Array(input)` | String to Uint8Array |
|
|
31
|
+
|
|
32
|
+
## License
|
|
33
|
+
|
|
34
|
+
MIT
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/murmur3.ts
|
|
4
|
+
function murmur3(input, seed = 0) {
|
|
5
|
+
let h1 = seed >>> 0;
|
|
6
|
+
const len = input.length;
|
|
7
|
+
const nblocks = len >> 2;
|
|
8
|
+
const c1 = 3432918353;
|
|
9
|
+
const c2 = 461845907;
|
|
10
|
+
for (let i = 0; i < nblocks; i++) {
|
|
11
|
+
let k12 = input.charCodeAt(i * 4) & 255 | (input.charCodeAt(i * 4 + 1) & 255) << 8 | (input.charCodeAt(i * 4 + 2) & 255) << 16 | (input.charCodeAt(i * 4 + 3) & 255) << 24;
|
|
12
|
+
k12 = Math.imul(k12, c1);
|
|
13
|
+
k12 = k12 << 15 | k12 >>> 17;
|
|
14
|
+
k12 = Math.imul(k12, c2);
|
|
15
|
+
h1 ^= k12;
|
|
16
|
+
h1 = h1 << 13 | h1 >>> 19;
|
|
17
|
+
h1 = Math.imul(h1, 5) + 3864292196;
|
|
18
|
+
}
|
|
19
|
+
let k1 = 0;
|
|
20
|
+
const tail = nblocks * 4;
|
|
21
|
+
switch (len & 3) {
|
|
22
|
+
case 3:
|
|
23
|
+
k1 ^= (input.charCodeAt(tail + 2) & 255) << 16;
|
|
24
|
+
// falls through
|
|
25
|
+
case 2:
|
|
26
|
+
k1 ^= (input.charCodeAt(tail + 1) & 255) << 8;
|
|
27
|
+
// falls through
|
|
28
|
+
case 1:
|
|
29
|
+
k1 ^= input.charCodeAt(tail) & 255;
|
|
30
|
+
k1 = Math.imul(k1, c1);
|
|
31
|
+
k1 = k1 << 15 | k1 >>> 17;
|
|
32
|
+
k1 = Math.imul(k1, c2);
|
|
33
|
+
h1 ^= k1;
|
|
34
|
+
}
|
|
35
|
+
h1 ^= len;
|
|
36
|
+
h1 ^= h1 >>> 16;
|
|
37
|
+
h1 = Math.imul(h1, 2246822507);
|
|
38
|
+
h1 ^= h1 >>> 13;
|
|
39
|
+
h1 = Math.imul(h1, 3266489909);
|
|
40
|
+
h1 ^= h1 >>> 16;
|
|
41
|
+
return (h1 >>> 0).toString(16).padStart(8, "0");
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// src/utils.ts
|
|
45
|
+
function toHex(buffer) {
|
|
46
|
+
const bytes = new Uint8Array(buffer);
|
|
47
|
+
let hex = "";
|
|
48
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
49
|
+
hex += bytes[i].toString(16).padStart(2, "0");
|
|
50
|
+
}
|
|
51
|
+
return hex;
|
|
52
|
+
}
|
|
53
|
+
function toUint8Array(input) {
|
|
54
|
+
return new TextEncoder().encode(input);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// src/crypto.ts
|
|
58
|
+
async function digestWith(algorithm, input) {
|
|
59
|
+
const data = toUint8Array(input);
|
|
60
|
+
const buffer = await globalThis.crypto.subtle.digest(algorithm, data.buffer);
|
|
61
|
+
return toHex(buffer);
|
|
62
|
+
}
|
|
63
|
+
async function sha256(input) {
|
|
64
|
+
return digestWith("SHA-256", input);
|
|
65
|
+
}
|
|
66
|
+
async function sha512(input) {
|
|
67
|
+
return digestWith("SHA-512", input);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// src/hmac.ts
|
|
71
|
+
async function hmac(key, data, algorithm = "SHA-256") {
|
|
72
|
+
const keyData = toUint8Array(key);
|
|
73
|
+
const cryptoKey = await globalThis.crypto.subtle.importKey(
|
|
74
|
+
"raw",
|
|
75
|
+
keyData.buffer,
|
|
76
|
+
{ name: "HMAC", hash: algorithm },
|
|
77
|
+
false,
|
|
78
|
+
["sign"]
|
|
79
|
+
);
|
|
80
|
+
const signature = await globalThis.crypto.subtle.sign("HMAC", cryptoKey, toUint8Array(data).buffer);
|
|
81
|
+
return toHex(signature);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// src/hash.ts
|
|
85
|
+
var hash = {
|
|
86
|
+
murmur3,
|
|
87
|
+
sha256,
|
|
88
|
+
sha512,
|
|
89
|
+
hmac
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
exports.hash = hash;
|
|
93
|
+
exports.hmac = hmac;
|
|
94
|
+
exports.murmur3 = murmur3;
|
|
95
|
+
exports.sha256 = sha256;
|
|
96
|
+
exports.sha512 = sha512;
|
|
97
|
+
exports.toHex = toHex;
|
|
98
|
+
exports.toUint8Array = toUint8Array;
|
|
99
|
+
//# sourceMappingURL=index.cjs.map
|
|
100
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/murmur3.ts","../src/utils.ts","../src/crypto.ts","../src/hmac.ts","../src/hash.ts"],"names":["k1"],"mappings":"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","file":"index.cjs","sourcesContent":["export function murmur3(input: string, seed: number = 0): string {\n let h1 = seed >>> 0;\n const len = input.length;\n const nblocks = len >> 2;\n\n const c1 = 0xcc9e2d51;\n const c2 = 0x1b873593;\n\n for (let i = 0; i < nblocks; i++) {\n let k1 =\n (input.charCodeAt(i * 4) & 0xff) |\n ((input.charCodeAt(i * 4 + 1) & 0xff) << 8) |\n ((input.charCodeAt(i * 4 + 2) & 0xff) << 16) |\n ((input.charCodeAt(i * 4 + 3) & 0xff) << 24);\n\n k1 = Math.imul(k1, c1);\n k1 = (k1 << 15) | (k1 >>> 17);\n k1 = Math.imul(k1, c2);\n\n h1 ^= k1;\n h1 = (h1 << 13) | (h1 >>> 19);\n h1 = Math.imul(h1, 5) + 0xe6546b64;\n }\n\n let k1 = 0;\n const tail = nblocks * 4;\n switch (len & 3) {\n case 3: k1 ^= (input.charCodeAt(tail + 2) & 0xff) << 16;\n // falls through\n case 2: k1 ^= (input.charCodeAt(tail + 1) & 0xff) << 8;\n // falls through\n case 1:\n k1 ^= input.charCodeAt(tail) & 0xff;\n k1 = Math.imul(k1, c1);\n k1 = (k1 << 15) | (k1 >>> 17);\n k1 = Math.imul(k1, c2);\n h1 ^= k1;\n }\n\n h1 ^= len;\n h1 ^= h1 >>> 16;\n h1 = Math.imul(h1, 0x85ebca6b);\n h1 ^= h1 >>> 13;\n h1 = Math.imul(h1, 0xc2b2ae35);\n h1 ^= h1 >>> 16;\n\n return (h1 >>> 0).toString(16).padStart(8, '0');\n}\n","export function toHex(buffer: ArrayBuffer): string {\n const bytes = new Uint8Array(buffer);\n let hex = '';\n for (let i = 0; i < bytes.length; i++) {\n hex += bytes[i].toString(16).padStart(2, '0');\n }\n return hex;\n}\n\nexport function toUint8Array(input: string): Uint8Array {\n return new TextEncoder().encode(input);\n}\n","import { toHex, toUint8Array } from './utils';\nimport type { HashAlgorithm } from './types';\n\nasync function digestWith(algorithm: HashAlgorithm, input: string): Promise<string> {\n const data = toUint8Array(input);\n const buffer = await globalThis.crypto.subtle.digest(algorithm, data.buffer as ArrayBuffer);\n return toHex(buffer);\n}\n\nexport async function sha256(input: string): Promise<string> {\n return digestWith('SHA-256', input);\n}\n\nexport async function sha512(input: string): Promise<string> {\n return digestWith('SHA-512', input);\n}\n","import { toHex, toUint8Array } from './utils';\nimport type { HashAlgorithm } from './types';\n\nexport async function hmac(\n key: string,\n data: string,\n algorithm: HashAlgorithm = 'SHA-256',\n): Promise<string> {\n const keyData = toUint8Array(key);\n const cryptoKey = await globalThis.crypto.subtle.importKey(\n 'raw',\n keyData.buffer as ArrayBuffer,\n { name: 'HMAC', hash: algorithm },\n false,\n ['sign'],\n );\n const signature = await globalThis.crypto.subtle.sign('HMAC', cryptoKey, toUint8Array(data).buffer as ArrayBuffer);\n return toHex(signature);\n}\n","import { murmur3 } from './murmur3';\nimport { sha256, sha512 } from './crypto';\nimport { hmac } from './hmac';\n\nexport const hash = {\n murmur3,\n sha256,\n sha512,\n hmac,\n} as const;\n"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
declare function murmur3(input: string, seed?: number): string;
|
|
2
|
+
|
|
3
|
+
declare function sha256(input: string): Promise<string>;
|
|
4
|
+
declare function sha512(input: string): Promise<string>;
|
|
5
|
+
|
|
6
|
+
type HashAlgorithm = 'SHA-256' | 'SHA-512';
|
|
7
|
+
type HashInput = string | ArrayBuffer | Uint8Array;
|
|
8
|
+
|
|
9
|
+
declare function hmac(key: string, data: string, algorithm?: HashAlgorithm): Promise<string>;
|
|
10
|
+
|
|
11
|
+
declare const hash: {
|
|
12
|
+
readonly murmur3: typeof murmur3;
|
|
13
|
+
readonly sha256: typeof sha256;
|
|
14
|
+
readonly sha512: typeof sha512;
|
|
15
|
+
readonly hmac: typeof hmac;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
declare function toHex(buffer: ArrayBuffer): string;
|
|
19
|
+
declare function toUint8Array(input: string): Uint8Array;
|
|
20
|
+
|
|
21
|
+
export { type HashAlgorithm, type HashInput, hash, hmac, murmur3, sha256, sha512, toHex, toUint8Array };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
declare function murmur3(input: string, seed?: number): string;
|
|
2
|
+
|
|
3
|
+
declare function sha256(input: string): Promise<string>;
|
|
4
|
+
declare function sha512(input: string): Promise<string>;
|
|
5
|
+
|
|
6
|
+
type HashAlgorithm = 'SHA-256' | 'SHA-512';
|
|
7
|
+
type HashInput = string | ArrayBuffer | Uint8Array;
|
|
8
|
+
|
|
9
|
+
declare function hmac(key: string, data: string, algorithm?: HashAlgorithm): Promise<string>;
|
|
10
|
+
|
|
11
|
+
declare const hash: {
|
|
12
|
+
readonly murmur3: typeof murmur3;
|
|
13
|
+
readonly sha256: typeof sha256;
|
|
14
|
+
readonly sha512: typeof sha512;
|
|
15
|
+
readonly hmac: typeof hmac;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
declare function toHex(buffer: ArrayBuffer): string;
|
|
19
|
+
declare function toUint8Array(input: string): Uint8Array;
|
|
20
|
+
|
|
21
|
+
export { type HashAlgorithm, type HashInput, hash, hmac, murmur3, sha256, sha512, toHex, toUint8Array };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
// src/murmur3.ts
|
|
2
|
+
function murmur3(input, seed = 0) {
|
|
3
|
+
let h1 = seed >>> 0;
|
|
4
|
+
const len = input.length;
|
|
5
|
+
const nblocks = len >> 2;
|
|
6
|
+
const c1 = 3432918353;
|
|
7
|
+
const c2 = 461845907;
|
|
8
|
+
for (let i = 0; i < nblocks; i++) {
|
|
9
|
+
let k12 = input.charCodeAt(i * 4) & 255 | (input.charCodeAt(i * 4 + 1) & 255) << 8 | (input.charCodeAt(i * 4 + 2) & 255) << 16 | (input.charCodeAt(i * 4 + 3) & 255) << 24;
|
|
10
|
+
k12 = Math.imul(k12, c1);
|
|
11
|
+
k12 = k12 << 15 | k12 >>> 17;
|
|
12
|
+
k12 = Math.imul(k12, c2);
|
|
13
|
+
h1 ^= k12;
|
|
14
|
+
h1 = h1 << 13 | h1 >>> 19;
|
|
15
|
+
h1 = Math.imul(h1, 5) + 3864292196;
|
|
16
|
+
}
|
|
17
|
+
let k1 = 0;
|
|
18
|
+
const tail = nblocks * 4;
|
|
19
|
+
switch (len & 3) {
|
|
20
|
+
case 3:
|
|
21
|
+
k1 ^= (input.charCodeAt(tail + 2) & 255) << 16;
|
|
22
|
+
// falls through
|
|
23
|
+
case 2:
|
|
24
|
+
k1 ^= (input.charCodeAt(tail + 1) & 255) << 8;
|
|
25
|
+
// falls through
|
|
26
|
+
case 1:
|
|
27
|
+
k1 ^= input.charCodeAt(tail) & 255;
|
|
28
|
+
k1 = Math.imul(k1, c1);
|
|
29
|
+
k1 = k1 << 15 | k1 >>> 17;
|
|
30
|
+
k1 = Math.imul(k1, c2);
|
|
31
|
+
h1 ^= k1;
|
|
32
|
+
}
|
|
33
|
+
h1 ^= len;
|
|
34
|
+
h1 ^= h1 >>> 16;
|
|
35
|
+
h1 = Math.imul(h1, 2246822507);
|
|
36
|
+
h1 ^= h1 >>> 13;
|
|
37
|
+
h1 = Math.imul(h1, 3266489909);
|
|
38
|
+
h1 ^= h1 >>> 16;
|
|
39
|
+
return (h1 >>> 0).toString(16).padStart(8, "0");
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// src/utils.ts
|
|
43
|
+
function toHex(buffer) {
|
|
44
|
+
const bytes = new Uint8Array(buffer);
|
|
45
|
+
let hex = "";
|
|
46
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
47
|
+
hex += bytes[i].toString(16).padStart(2, "0");
|
|
48
|
+
}
|
|
49
|
+
return hex;
|
|
50
|
+
}
|
|
51
|
+
function toUint8Array(input) {
|
|
52
|
+
return new TextEncoder().encode(input);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// src/crypto.ts
|
|
56
|
+
async function digestWith(algorithm, input) {
|
|
57
|
+
const data = toUint8Array(input);
|
|
58
|
+
const buffer = await globalThis.crypto.subtle.digest(algorithm, data.buffer);
|
|
59
|
+
return toHex(buffer);
|
|
60
|
+
}
|
|
61
|
+
async function sha256(input) {
|
|
62
|
+
return digestWith("SHA-256", input);
|
|
63
|
+
}
|
|
64
|
+
async function sha512(input) {
|
|
65
|
+
return digestWith("SHA-512", input);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// src/hmac.ts
|
|
69
|
+
async function hmac(key, data, algorithm = "SHA-256") {
|
|
70
|
+
const keyData = toUint8Array(key);
|
|
71
|
+
const cryptoKey = await globalThis.crypto.subtle.importKey(
|
|
72
|
+
"raw",
|
|
73
|
+
keyData.buffer,
|
|
74
|
+
{ name: "HMAC", hash: algorithm },
|
|
75
|
+
false,
|
|
76
|
+
["sign"]
|
|
77
|
+
);
|
|
78
|
+
const signature = await globalThis.crypto.subtle.sign("HMAC", cryptoKey, toUint8Array(data).buffer);
|
|
79
|
+
return toHex(signature);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// src/hash.ts
|
|
83
|
+
var hash = {
|
|
84
|
+
murmur3,
|
|
85
|
+
sha256,
|
|
86
|
+
sha512,
|
|
87
|
+
hmac
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
export { hash, hmac, murmur3, sha256, sha512, toHex, toUint8Array };
|
|
91
|
+
//# sourceMappingURL=index.js.map
|
|
92
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/murmur3.ts","../src/utils.ts","../src/crypto.ts","../src/hmac.ts","../src/hash.ts"],"names":["k1"],"mappings":";AAAO,SAAS,OAAA,CAAQ,KAAA,EAAe,IAAA,GAAe,CAAA,EAAW;AAC/D,EAAA,IAAI,KAAK,IAAA,KAAS,CAAA;AAClB,EAAA,MAAM,MAAM,KAAA,CAAM,MAAA;AAClB,EAAA,MAAM,UAAU,GAAA,IAAO,CAAA;AAEvB,EAAA,MAAM,EAAA,GAAK,UAAA;AACX,EAAA,MAAM,EAAA,GAAK,SAAA;AAEX,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,OAAA,EAAS,CAAA,EAAA,EAAK;AAChC,IAAA,IAAIA,GAAAA,GACD,KAAA,CAAM,UAAA,CAAW,CAAA,GAAI,CAAC,CAAA,GAAI,GAAA,GAAA,CACzB,KAAA,CAAM,UAAA,CAAW,CAAA,GAAI,CAAA,GAAI,CAAC,CAAA,GAAI,GAAA,KAAS,CAAA,GAAA,CACvC,KAAA,CAAM,UAAA,CAAW,CAAA,GAAI,CAAA,GAAI,CAAC,CAAA,GAAI,GAAA,KAAS,EAAA,GAAA,CACvC,KAAA,CAAM,UAAA,CAAW,CAAA,GAAI,CAAA,GAAI,CAAC,IAAI,GAAA,KAAS,EAAA;AAE3C,IAAAA,GAAAA,GAAK,IAAA,CAAK,IAAA,CAAKA,GAAAA,EAAI,EAAE,CAAA;AACrB,IAAAA,GAAAA,GAAMA,GAAAA,IAAM,EAAA,GAAOA,GAAAA,KAAO,EAAA;AAC1B,IAAAA,GAAAA,GAAK,IAAA,CAAK,IAAA,CAAKA,GAAAA,EAAI,EAAE,CAAA;AAErB,IAAA,EAAA,IAAMA,GAAAA;AACN,IAAA,EAAA,GAAM,EAAA,IAAM,KAAO,EAAA,KAAO,EAAA;AAC1B,IAAA,EAAA,GAAK,IAAA,CAAK,IAAA,CAAK,EAAA,EAAI,CAAC,CAAA,GAAI,UAAA;AAAA,EAC1B;AAEA,EAAA,IAAI,EAAA,GAAK,CAAA;AACT,EAAA,MAAM,OAAO,OAAA,GAAU,CAAA;AACvB,EAAA,QAAQ,MAAM,CAAA;AAAG,IACf,KAAK,CAAA;AAAG,MAAA,EAAA,IAAA,CAAO,KAAA,CAAM,UAAA,CAAW,IAAA,GAAO,CAAC,IAAI,GAAA,KAAS,EAAA;AAAA;AAAA,IAErD,KAAK,CAAA;AAAG,MAAA,EAAA,IAAA,CAAO,KAAA,CAAM,UAAA,CAAW,IAAA,GAAO,CAAC,IAAI,GAAA,KAAS,CAAA;AAAA;AAAA,IAErD,KAAK,CAAA;AACH,MAAA,EAAA,IAAM,KAAA,CAAM,UAAA,CAAW,IAAI,CAAA,GAAI,GAAA;AAC/B,MAAA,EAAA,GAAK,IAAA,CAAK,IAAA,CAAK,EAAA,EAAI,EAAE,CAAA;AACrB,MAAA,EAAA,GAAM,EAAA,IAAM,KAAO,EAAA,KAAO,EAAA;AAC1B,MAAA,EAAA,GAAK,IAAA,CAAK,IAAA,CAAK,EAAA,EAAI,EAAE,CAAA;AACrB,MAAA,EAAA,IAAM,EAAA;AAAA;AAGV,EAAA,EAAA,IAAM,GAAA;AACN,EAAA,EAAA,IAAM,EAAA,KAAO,EAAA;AACb,EAAA,EAAA,GAAK,IAAA,CAAK,IAAA,CAAK,EAAA,EAAI,UAAU,CAAA;AAC7B,EAAA,EAAA,IAAM,EAAA,KAAO,EAAA;AACb,EAAA,EAAA,GAAK,IAAA,CAAK,IAAA,CAAK,EAAA,EAAI,UAAU,CAAA;AAC7B,EAAA,EAAA,IAAM,EAAA,KAAO,EAAA;AAEb,EAAA,OAAA,CAAQ,OAAO,CAAA,EAAG,QAAA,CAAS,EAAE,CAAA,CAAE,QAAA,CAAS,GAAG,GAAG,CAAA;AAChD;;;AC/CO,SAAS,MAAM,MAAA,EAA6B;AACjD,EAAA,MAAM,KAAA,GAAQ,IAAI,UAAA,CAAW,MAAM,CAAA;AACnC,EAAA,IAAI,GAAA,GAAM,EAAA;AACV,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,KAAA,CAAM,QAAQ,CAAA,EAAA,EAAK;AACrC,IAAA,GAAA,IAAO,KAAA,CAAM,CAAC,CAAA,CAAE,QAAA,CAAS,EAAE,CAAA,CAAE,QAAA,CAAS,GAAG,GAAG,CAAA;AAAA,EAC9C;AACA,EAAA,OAAO,GAAA;AACT;AAEO,SAAS,aAAa,KAAA,EAA2B;AACtD,EAAA,OAAO,IAAI,WAAA,EAAY,CAAE,MAAA,CAAO,KAAK,CAAA;AACvC;;;ACRA,eAAe,UAAA,CAAW,WAA0B,KAAA,EAAgC;AAClF,EAAA,MAAM,IAAA,GAAO,aAAa,KAAK,CAAA;AAC/B,EAAA,MAAM,MAAA,GAAS,MAAM,UAAA,CAAW,MAAA,CAAO,OAAO,MAAA,CAAO,SAAA,EAAW,KAAK,MAAqB,CAAA;AAC1F,EAAA,OAAO,MAAM,MAAM,CAAA;AACrB;AAEA,eAAsB,OAAO,KAAA,EAAgC;AAC3D,EAAA,OAAO,UAAA,CAAW,WAAW,KAAK,CAAA;AACpC;AAEA,eAAsB,OAAO,KAAA,EAAgC;AAC3D,EAAA,OAAO,UAAA,CAAW,WAAW,KAAK,CAAA;AACpC;;;ACZA,eAAsB,IAAA,CACpB,GAAA,EACA,IAAA,EACA,SAAA,GAA2B,SAAA,EACV;AACjB,EAAA,MAAM,OAAA,GAAU,aAAa,GAAG,CAAA;AAChC,EAAA,MAAM,SAAA,GAAY,MAAM,UAAA,CAAW,MAAA,CAAO,MAAA,CAAO,SAAA;AAAA,IAC/C,KAAA;AAAA,IACA,OAAA,CAAQ,MAAA;AAAA,IACR,EAAE,IAAA,EAAM,MAAA,EAAQ,IAAA,EAAM,SAAA,EAAU;AAAA,IAChC,KAAA;AAAA,IACA,CAAC,MAAM;AAAA,GACT;AACA,EAAA,MAAM,SAAA,GAAY,MAAM,UAAA,CAAW,MAAA,CAAO,MAAA,CAAO,IAAA,CAAK,MAAA,EAAQ,SAAA,EAAW,YAAA,CAAa,IAAI,CAAA,CAAE,MAAqB,CAAA;AACjH,EAAA,OAAO,MAAM,SAAS,CAAA;AACxB;;;ACdO,IAAM,IAAA,GAAO;AAAA,EAClB,OAAA;AAAA,EACA,MAAA;AAAA,EACA,MAAA;AAAA,EACA;AACF","file":"index.js","sourcesContent":["export function murmur3(input: string, seed: number = 0): string {\n let h1 = seed >>> 0;\n const len = input.length;\n const nblocks = len >> 2;\n\n const c1 = 0xcc9e2d51;\n const c2 = 0x1b873593;\n\n for (let i = 0; i < nblocks; i++) {\n let k1 =\n (input.charCodeAt(i * 4) & 0xff) |\n ((input.charCodeAt(i * 4 + 1) & 0xff) << 8) |\n ((input.charCodeAt(i * 4 + 2) & 0xff) << 16) |\n ((input.charCodeAt(i * 4 + 3) & 0xff) << 24);\n\n k1 = Math.imul(k1, c1);\n k1 = (k1 << 15) | (k1 >>> 17);\n k1 = Math.imul(k1, c2);\n\n h1 ^= k1;\n h1 = (h1 << 13) | (h1 >>> 19);\n h1 = Math.imul(h1, 5) + 0xe6546b64;\n }\n\n let k1 = 0;\n const tail = nblocks * 4;\n switch (len & 3) {\n case 3: k1 ^= (input.charCodeAt(tail + 2) & 0xff) << 16;\n // falls through\n case 2: k1 ^= (input.charCodeAt(tail + 1) & 0xff) << 8;\n // falls through\n case 1:\n k1 ^= input.charCodeAt(tail) & 0xff;\n k1 = Math.imul(k1, c1);\n k1 = (k1 << 15) | (k1 >>> 17);\n k1 = Math.imul(k1, c2);\n h1 ^= k1;\n }\n\n h1 ^= len;\n h1 ^= h1 >>> 16;\n h1 = Math.imul(h1, 0x85ebca6b);\n h1 ^= h1 >>> 13;\n h1 = Math.imul(h1, 0xc2b2ae35);\n h1 ^= h1 >>> 16;\n\n return (h1 >>> 0).toString(16).padStart(8, '0');\n}\n","export function toHex(buffer: ArrayBuffer): string {\n const bytes = new Uint8Array(buffer);\n let hex = '';\n for (let i = 0; i < bytes.length; i++) {\n hex += bytes[i].toString(16).padStart(2, '0');\n }\n return hex;\n}\n\nexport function toUint8Array(input: string): Uint8Array {\n return new TextEncoder().encode(input);\n}\n","import { toHex, toUint8Array } from './utils';\nimport type { HashAlgorithm } from './types';\n\nasync function digestWith(algorithm: HashAlgorithm, input: string): Promise<string> {\n const data = toUint8Array(input);\n const buffer = await globalThis.crypto.subtle.digest(algorithm, data.buffer as ArrayBuffer);\n return toHex(buffer);\n}\n\nexport async function sha256(input: string): Promise<string> {\n return digestWith('SHA-256', input);\n}\n\nexport async function sha512(input: string): Promise<string> {\n return digestWith('SHA-512', input);\n}\n","import { toHex, toUint8Array } from './utils';\nimport type { HashAlgorithm } from './types';\n\nexport async function hmac(\n key: string,\n data: string,\n algorithm: HashAlgorithm = 'SHA-256',\n): Promise<string> {\n const keyData = toUint8Array(key);\n const cryptoKey = await globalThis.crypto.subtle.importKey(\n 'raw',\n keyData.buffer as ArrayBuffer,\n { name: 'HMAC', hash: algorithm },\n false,\n ['sign'],\n );\n const signature = await globalThis.crypto.subtle.sign('HMAC', cryptoKey, toUint8Array(data).buffer as ArrayBuffer);\n return toHex(signature);\n}\n","import { murmur3 } from './murmur3';\nimport { sha256, sha512 } from './crypto';\nimport { hmac } from './hmac';\n\nexport const hash = {\n murmur3,\n sha256,\n sha512,\n hmac,\n} as const;\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@philiprehberger/hash-kit",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Simple cross-platform hashing utilities",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.cjs",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"import": { "types": "./dist/index.d.ts", "default": "./dist/index.js" },
|
|
12
|
+
"require": { "types": "./dist/index.d.cts", "default": "./dist/index.cjs" }
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": ["dist"],
|
|
16
|
+
"scripts": {
|
|
17
|
+
"build": "tsup",
|
|
18
|
+
"dev": "tsup --watch",
|
|
19
|
+
"typecheck": "tsc --noEmit",
|
|
20
|
+
"prepublishOnly": "npm run build"
|
|
21
|
+
},
|
|
22
|
+
"devDependencies": { "tsup": "^8.0.0", "typescript": "^5.0.0" },
|
|
23
|
+
"keywords": ["hash", "murmur", "sha256", "hmac", "checksum", "crypto"],
|
|
24
|
+
"license": "MIT",
|
|
25
|
+
"repository": { "type": "git", "url": "git+https://github.com/philiprehberger/ts-hash-kit.git" },
|
|
26
|
+
"homepage": "https://github.com/philiprehberger/ts-hash-kit#readme",
|
|
27
|
+
"bugs": { "url": "https://github.com/philiprehberger/ts-hash-kit/issues" },
|
|
28
|
+
"author": "Philip Rehberger",
|
|
29
|
+
"engines": { "node": ">=18.0.0" },
|
|
30
|
+
"sideEffects": false
|
|
31
|
+
}
|