tinyhmacmd5 0.1.6 → 0.1.7
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/README.md +52 -24
- package/browser.min.js +1 -1
- package/main.js +11 -19
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -2,16 +2,17 @@ English | [中文](README-zh.md)
|
|
|
2
2
|
|
|
3
3
|
# Tiny HMAC MD5
|
|
4
4
|
|
|
5
|
-
A tiny
|
|
6
|
-
[`browser.min.js`](browser.min.js) is only **1017 bytes**.
|
|
5
|
+
A tiny and reliable HMAC-MD5 implementation for JavaScript: [`browser.min.js`](browser.min.js) is only **997 bytes**.
|
|
7
6
|
|
|
8
7
|
- **Input type**: `string` (UTF‑8), `Uint8Array` or `Uint8ClampedArray`
|
|
9
|
-
- **Output type**: hex `string` or
|
|
10
|
-
- **Supports inputs ≥ 512 MiB**:
|
|
8
|
+
- **Output type**: hex `string` or bytes `Uint8Array`
|
|
9
|
+
- **Supports inputs ≥ 512 MiB**: The input length theoretically supports 0 to $2^{53}-1$ (`Number.MAX_SAFE_INTEGER`).
|
|
11
10
|
- **TypeScript‑ready**: [`main.d.ts`](main.d.ts)
|
|
12
11
|
- **0 dependencies**
|
|
13
12
|
|
|
14
|
-
|
|
13
|
+
`tinyhmacmd5` does not simply aim for the smallest possible size.
|
|
14
|
+
Its goal is to balance code size and runtime performance, so some performance-oriented implementations are intentionally retained.
|
|
15
|
+
As a result, the final size is not the smallest theoretically achievable.
|
|
15
16
|
|
|
16
17
|
**Live demo**: https://bddjr.github.io/tinyhmacmd5/
|
|
17
18
|
|
|
@@ -44,10 +45,11 @@ See https://www.jsdelivr.com/package/npm/tinyhmacmd5
|
|
|
44
45
|
<script src="https://cdn.jsdelivr.net/npm/tinyhmacmd5"></script>
|
|
45
46
|
```
|
|
46
47
|
|
|
47
|
-
|
|
48
|
+
It will define the `md5` function using `var`.
|
|
48
49
|
|
|
49
|
-
|
|
50
|
+
### Inline
|
|
50
51
|
|
|
52
|
+
You can embed [`browser.min.js`](browser.min.js) directly into your script.
|
|
51
53
|
It will define the `md5` function using `var`.
|
|
52
54
|
|
|
53
55
|
---
|
|
@@ -55,20 +57,18 @@ It will define the `md5` function using `var`.
|
|
|
55
57
|
## Example
|
|
56
58
|
|
|
57
59
|
> [!NOTE]
|
|
58
|
-
>
|
|
59
|
-
>
|
|
60
|
-
> TypeScript will catch mismatches at compile time (unless you use `any`).
|
|
61
|
-
> Invalid types may produce an incorrect MD5 hash.
|
|
60
|
+
> Please ensure that the input type matches the definition in [`main.d.ts`](main.d.ts).
|
|
61
|
+
> Invalid types may return an incorrect MD5 hash.
|
|
62
62
|
|
|
63
63
|
HMAC-MD5:
|
|
64
64
|
|
|
65
65
|
```js
|
|
66
|
-
// string to hex
|
|
66
|
+
// string (UTF-8) to hex
|
|
67
67
|
// returns "c87fdc912df24da05a6e3fed927e9d89"
|
|
68
68
|
md5("Hello world!👋", "HMAC key 🔑")
|
|
69
69
|
|
|
70
|
-
// string to bytes
|
|
71
|
-
// returns Uint8Array
|
|
70
|
+
// string (UTF-8) to bytes
|
|
71
|
+
// returns Uint8Array(16)
|
|
72
72
|
md5("Hello world!👋", "HMAC key 🔑", true)
|
|
73
73
|
|
|
74
74
|
// bytes to hex
|
|
@@ -76,19 +76,19 @@ md5("Hello world!👋", "HMAC key 🔑", true)
|
|
|
76
76
|
md5(Uint8Array.of(1, 2, 3), Uint8Array.of(4, 5, 6))
|
|
77
77
|
|
|
78
78
|
// bytes to bytes
|
|
79
|
-
// returns Uint8Array
|
|
79
|
+
// returns Uint8Array(16)
|
|
80
80
|
md5(Uint8Array.of(1, 2, 3), Uint8Array.of(4, 5, 6), true)
|
|
81
81
|
```
|
|
82
82
|
|
|
83
83
|
MD5: (when `key` is `null` or `undefined`)
|
|
84
84
|
|
|
85
85
|
```js
|
|
86
|
-
// string to hex
|
|
86
|
+
// string (UTF-8) to hex
|
|
87
87
|
// returns "3ac851eecf9e37be7565bf073a73c9dc"
|
|
88
88
|
md5("Hello world!👋")
|
|
89
89
|
|
|
90
|
-
// string to bytes
|
|
91
|
-
// returns Uint8Array
|
|
90
|
+
// string (UTF-8) to bytes
|
|
91
|
+
// returns Uint8Array(16)
|
|
92
92
|
md5("Hello world!👋", null, true)
|
|
93
93
|
|
|
94
94
|
// bytes to hex
|
|
@@ -96,10 +96,40 @@ md5("Hello world!👋", null, true)
|
|
|
96
96
|
md5(Uint8Array.of(1, 2, 3))
|
|
97
97
|
|
|
98
98
|
// bytes to bytes
|
|
99
|
-
// returns Uint8Array
|
|
99
|
+
// returns Uint8Array(16)
|
|
100
100
|
md5(Uint8Array.of(1, 2, 3), null, true)
|
|
101
101
|
```
|
|
102
102
|
|
|
103
|
+
`ArrayBuffer` must be wrapped in a `Uint8Array` before use as input;
|
|
104
|
+
otherwise, it will return an incorrect MD5 hash.
|
|
105
|
+
|
|
106
|
+
```js
|
|
107
|
+
let data = new ArrayBuffer(8)
|
|
108
|
+
|
|
109
|
+
// MD5: bytes to hex
|
|
110
|
+
md5(new Uint8Array(data))
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
You can also input a `Uint8ClampedArray`, which has the same effect as using a `Uint8Array`.
|
|
114
|
+
|
|
115
|
+
```js
|
|
116
|
+
// MD5: bytes to hex
|
|
117
|
+
// returns "5289df737df57326fcdd22597afb1fac"
|
|
118
|
+
md5(Uint8ClampedArray.of(1, 2, 3))
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
**[⚠️Unsafe]** You can also input a `number[]`, but every element must be an integer in the range `0 ≤ x ≤ 255`;
|
|
122
|
+
otherwise, it will return an incorrect MD5 hash.
|
|
123
|
+
|
|
124
|
+
```js
|
|
125
|
+
let data = [0, 1, 127, 255]
|
|
126
|
+
|
|
127
|
+
// MD5: bytes to hex
|
|
128
|
+
// returns "b23d6235d525eed4c4b8d741d4c2a5a1"
|
|
129
|
+
//@ts-ignore
|
|
130
|
+
md5(data)
|
|
131
|
+
```
|
|
132
|
+
|
|
103
133
|
---
|
|
104
134
|
|
|
105
135
|
## Runtime Environment
|
|
@@ -117,10 +147,6 @@ Not recommended for use in environments that support `node:crypto`, as `node:cry
|
|
|
117
147
|
|
|
118
148
|
## Why I Made This Project
|
|
119
149
|
|
|
120
|
-
> [!NOTE]
|
|
121
|
-
> AI-translated from Chinese.
|
|
122
|
-
> [查看原文](README-zh.md#为什么做这个项目)
|
|
123
|
-
|
|
124
150
|
I initially used HMAC-MD5 just to call a certain website's API. That site signs the request body with `crypto-js`'s HMAC-MD5 to make reverse engineering harder.
|
|
125
151
|
|
|
126
152
|
But I only needed HMAC-MD5. Depending on `crypto-js` felt way too bloated. The Web Crypto API doesn't support HMAC-MD5, so I had no choice but to drag in a dependency.
|
|
@@ -135,12 +161,14 @@ During the adaptation, I discovered that `blueimp-md5` did not correctly handle
|
|
|
135
161
|
|
|
136
162
|
I also found that using `Array` to process inputs over 512 MiB could throw a `RangeError`, so I replaced it with `Int32Array`.
|
|
137
163
|
|
|
138
|
-
I demonstrated in practice that HMAC-MD5 can be implemented in an extremely small footprint (
|
|
164
|
+
I demonstrated in practice that HMAC-MD5 can be implemented in an extremely small footprint (997 bytes) while also improving reliability.
|
|
139
165
|
|
|
140
166
|
Maybe not many people care about saving just a few KB, but `tinyhmacmd5` exists precisely to "explore the unknown".
|
|
141
167
|
|
|
142
168
|
INVINCIBLE EXPERIMENT!
|
|
143
169
|
|
|
170
|
+
[查看原文](README-zh.md#为什么做这个项目)
|
|
171
|
+
|
|
144
172
|
---
|
|
145
173
|
|
|
146
174
|
## License
|
package/browser.min.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/** @license https://bddjr.github.io/tinyhmacmd5/lic */
|
|
2
|
-
{let r=
|
|
2
|
+
{let r=[],n=Math,t=n.floor,e=r=>16*t((r+72)/64),o=(o,f,a=0,l=e(f),c=1732584193,i=271733878,d,g,h=[c,~i,~c,i],u=[...h])=>{for(o[l-1]=0|f/2**29,o[t(f/4)]|=128<<(o[l-2]=f<<3);a<o.length;){for(l=0;l<64;)h[g&=3]=0|((i=0|h[g]+(c=h[3&++g],i=h[3&++g],d=h[3&++g],(f=l>>4<<2)?f>4?f>8?i^(c|~d):c^i^d:c&d|i&~d:c&i|~c&d)+(0|o[a+(l*(29521>>f)+(1296>>f)&15)])+(d="',16%).4$+07&*/5".charCodeAt(3&l|f),r[63-l++]??=0|2**32*n.abs(n.sin(l))))<<d|i>>>64-d)+c;for(;g;a+=4)u[--g]=h[g]=0|u[g]+h[g]}return h},f=(r,n,t=("string"==typeof r?r=(new TextEncoder).encode(r):r).length,o=new Int32Array(e(4*n+t)),f=0)=>{for(;f<t;)o[n++]=r[f++]|r[f++]<<8|r[f++]<<16|r[f++]<<24;return[o,t]};var md5=(r,n,t)=>{var e=16,a=null!=n,[l,c]=f(r,a*e),i=[],d=t?new Uint8Array(e):"";if(a){let[r,t]=f(n,0);for(t>64&&(r=o(r,t));e;)i[--e]=1785358954^(l[e]=909522486^r[e]);e=16,l=i.concat(o(l,64+c)),c=80}for(l=o(l,c);e;t?d[e]=i:d=(i>>4&&"")+i.toString(16)+d)i=l[--e>>2]>>8*e&255;return d}}
|
package/main.js
CHANGED
|
@@ -2,9 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
// Adapted from https://github.com/blueimp/JavaScript-MD5
|
|
4
4
|
|
|
5
|
-
let A = 1732584193
|
|
6
|
-
, D = 271733878
|
|
7
|
-
|
|
8
5
|
/** @type {number[]} MD5 constants cached in memory */
|
|
9
6
|
let K = []
|
|
10
7
|
|
|
@@ -22,9 +19,6 @@ let toBinlLen = (byteLen) => floor((byteLen + 72) / 64) * 16
|
|
|
22
19
|
* @param {Int32Array | number[]} x Array of little-endian words
|
|
23
20
|
* @param {number} l Byte length
|
|
24
21
|
*
|
|
25
|
-
* @param {number} [j]
|
|
26
|
-
* @param {number} [t0]
|
|
27
|
-
* @param {number} [t1]
|
|
28
22
|
* @param {number} [t2]
|
|
29
23
|
* @param {number} [oi]
|
|
30
24
|
*
|
|
@@ -36,11 +30,11 @@ let binlMD5 = (
|
|
|
36
30
|
// var:
|
|
37
31
|
i = 0,
|
|
38
32
|
j = toBinlLen(l),
|
|
39
|
-
t0,
|
|
40
|
-
t1,
|
|
33
|
+
t0 = 1732584193,
|
|
34
|
+
t1 = 271733878,
|
|
41
35
|
t2,
|
|
42
36
|
oi,
|
|
43
|
-
output = [
|
|
37
|
+
output = [t0, ~t1, ~t0, t1],
|
|
44
38
|
oldOutput = [...output],
|
|
45
39
|
) => {
|
|
46
40
|
// console.time("binlMD5")
|
|
@@ -48,13 +42,13 @@ let binlMD5 = (
|
|
|
48
42
|
// append padding
|
|
49
43
|
// `l` may be >= 2**32, so cannot use `>>>` as a replacement for `floor`
|
|
50
44
|
x[j - 1] = 0 | l / 2 ** 29;
|
|
51
|
-
x[j - 2] =
|
|
52
|
-
x[floor(l / 4)] |= 0x80 << l * 8;
|
|
45
|
+
x[floor(l / 4)] |= 0x80 << (x[j - 2] = l << 3);
|
|
53
46
|
|
|
54
47
|
for (; i < x.length;) {
|
|
55
48
|
for (j = 0; j < 64;) {
|
|
56
|
-
output[oi &= 3] = (
|
|
57
|
-
|
|
49
|
+
output[oi &= 3] = 0 | (
|
|
50
|
+
(t1 = 0 | (
|
|
51
|
+
output[oi] +
|
|
58
52
|
(
|
|
59
53
|
t0 = output[++oi & 3],
|
|
60
54
|
t1 = output[++oi & 3],
|
|
@@ -71,13 +65,11 @@ let binlMD5 = (
|
|
|
71
65
|
0 | x[i + (j * (0x7351 >> l) + (0x0510 >> l) & 15)]
|
|
72
66
|
) +
|
|
73
67
|
(
|
|
74
|
-
|
|
68
|
+
t2 = "',16%).4$+07&*/5".charCodeAt(j & 3 | l),
|
|
75
69
|
K[63 - j++] ??= 0 | 2 ** 32 * $Math.abs($Math.sin(j))
|
|
76
|
-
)
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
0 | (t0 << t1 | t0 >>> 64 - t1) + output[oi + 2 & 3]
|
|
80
|
-
)
|
|
70
|
+
)
|
|
71
|
+
)) << t2 | t1 >>> 64 - t2
|
|
72
|
+
) + t0
|
|
81
73
|
}
|
|
82
74
|
for (; oi; i += 4) {
|
|
83
75
|
oldOutput[--oi] = output[oi] = 0 | oldOutput[oi] + output[oi]
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tinyhmacmd5",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "A tiny
|
|
3
|
+
"version": "0.1.7",
|
|
4
|
+
"description": "A tiny and reliable HMAC-MD5 implementation for JavaScript: browser.min.js is only 997 bytes.",
|
|
5
5
|
"author": "bddjr",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"type": "module",
|