tinyhmacmd5 0.1.6 → 0.1.8

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 CHANGED
@@ -2,16 +2,17 @@ English | [中文](README-zh.md)
2
2
 
3
3
  # Tiny HMAC MD5
4
4
 
5
- A tiny, fully compliant HMAC-MD5 implementation for JavaScript:
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 raw `Uint8Array`
10
- - **Supports inputs ≥ 512 MiB**: Full 64‑bit length padding per RFC 1321
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
- The goal of `tinyhmacmd5` is to strike a balance between size and performance, rather than sacrificing performance for the sake of minimizing size. Therefore, some performance-oriented optimizations are intentionally retained, and the final size is not the smallest theoretically achievable.
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
- ### Inline
48
+ It will define the `md5` function using `var`.
48
49
 
49
- You can embed [`browser.min.js`](browser.min.js) directly into your script.
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
- > This library does not validate input types.
59
- > Please ensure the input type matches the definitions in [`main.d.ts`](main.d.ts).
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<ArrayBuffer>
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<ArrayBuffer>
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<ArrayBuffer>
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<ArrayBuffer>
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 (1017 bytes) while also improving reliability.
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=1732584193,n=271733878,t=[],e=Math,o=e.floor,f=r=>16*o((r+72)/64),a=(a,l,c=0,i=f(l),d,g,h,u,s=[r,~n,~r,n],w=[...s])=>{for(a[i-1]=0|l/2**29,a[i-2]=0|8*l,a[o(l/4)]|=128<<8*l;c<a.length;){for(i=0;i<64;)s[u&=3]=0|((d=0|(d=s[3&++u],g=s[3&++u],h=s[3&++u],((l=i>>4<<2)?l>4?l>8?g^(d|~h):d^g^h:d&h|g&~h:d&g|~d&h)+(0|a[c+(i*(29521>>l)+(1296>>l)&15)])+(g="',16%).4$+07&*/5".charCodeAt(l+i%4),t[63-i++]??=0|2**32*e.abs(e.sin(i)))+s[u+1&3]))<<g|d>>>64-g)+s[u+2&3];for(;u;c+=4)w[--u]=s[u]=0|w[u]+s[u]}return s},l=(r,n,t=("string"==typeof r?r=(new TextEncoder).encode(r):r).length,e=new Int32Array(f(4*n+t)),o=0)=>{for(;o<t;)e[n++]=r[o++]|r[o++]<<8|r[o++]<<16|r[o++]<<24;return[e,t]};var md5=(r,n,t)=>{var e=16,o=null!=n,[f,c]=l(r,o*e),i=[],d=t?new Uint8Array(e):"";if(o){let[r,t]=l(n,0);for(t>64&&(r=a(r,t));e;)i[--e]=1785358954^(f[e]=909522486^r[e]);e=16,f=i.concat(a(f,64+c)),c=80}for(f=a(f,c);e;t?d[e]=i:d=(i>>4&&"")+i.toString(16)+d)i=f[--e>>2]>>8*e&255;return d}}
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 = [A, ~D, ~A, D],
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] = 0 | l * 8;
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
- t0 = 0 | (
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
- t1 = "',16%).4$+07&*/5".charCodeAt(l + j % 4),
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
- output[oi + 1 & 3]
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,13 +1,15 @@
1
1
  {
2
2
  "name": "tinyhmacmd5",
3
- "version": "0.1.6",
4
- "description": "A tiny, fully compliant HMAC-MD5 implementation for JavaScript: browser.min.js is only 1017 bytes.",
3
+ "version": "0.1.8",
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",
8
8
  "main": "main.js",
9
9
  "types": "main.d.ts",
10
- "browser": "browser.min.js",
10
+ "jsdelivr": "browser.min.js",
11
+ "unpkg": "browser.min.js",
12
+ "cdn": "browser.min.js",
11
13
  "files": [
12
14
  "main.js",
13
15
  "main.d.ts",