tinyhmacmd5 0.1.8 → 0.2.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/README.md CHANGED
@@ -2,11 +2,11 @@ English | [中文](README-zh.md)
2
2
 
3
3
  # Tiny HMAC MD5
4
4
 
5
- A tiny and reliable HMAC-MD5 implementation for JavaScript: [`browser.min.js`](browser.min.js) is only **997 bytes**.
5
+ A tiny and reliable HMAC-MD5 implementation for JavaScript: [`browser.min.js`](browser.min.js) is only **983 bytes**.
6
6
 
7
7
  - **Input type**: `string` (UTF‑8), `Uint8Array` or `Uint8ClampedArray`
8
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`).
9
+ - **Supports inputs ≥ 512 MiB**: The input length theoretically supports 0 to 2⁵³-1 (`Number.MAX_SAFE_INTEGER`).
10
10
  - **TypeScript‑ready**: [`main.d.ts`](main.d.ts)
11
11
  - **0 dependencies**
12
12
 
@@ -47,6 +47,14 @@ See https://www.jsdelivr.com/package/npm/tinyhmacmd5
47
47
 
48
48
  It will define the `md5` function using `var`.
49
49
 
50
+ ### UNPKG
51
+
52
+ ```html
53
+ <script src="https://unpkg.com/tinyhmacmd5"></script>
54
+ ```
55
+
56
+ It will define the `md5` function using `var`.
57
+
50
58
  ### Inline
51
59
 
52
60
  You can embed [`browser.min.js`](browser.min.js) directly into your script.
@@ -100,8 +108,7 @@ md5(Uint8Array.of(1, 2, 3))
100
108
  md5(Uint8Array.of(1, 2, 3), null, true)
101
109
  ```
102
110
 
103
- `ArrayBuffer` must be wrapped in a `Uint8Array` before use as input;
104
- otherwise, it will return an incorrect MD5 hash.
111
+ `ArrayBuffer` must be wrapped in a `Uint8Array` before use as input; otherwise, it will return an incorrect MD5 hash.
105
112
 
106
113
  ```js
107
114
  let data = new ArrayBuffer(8)
@@ -118,8 +125,8 @@ You can also input a `Uint8ClampedArray`, which has the same effect as using a `
118
125
  md5(Uint8ClampedArray.of(1, 2, 3))
119
126
  ```
120
127
 
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.
128
+ **[⚠️Unsafe]**
129
+ You can also input a `number[]`, but every element must be an integer in the range `0 ≤ x ≤ 255`; otherwise, it will return an incorrect MD5 hash.
123
130
 
124
131
  ```js
125
132
  let data = [0, 1, 127, 255]
@@ -134,12 +141,22 @@ md5(data)
134
141
 
135
142
  ## Runtime Environment
136
143
 
137
- Environments that support [Nullish coalescing assignment (`??=`)](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_assignment) :
138
-
139
- - Chrome ≥ 85 (2020-08-25)
140
- - Edge85 (2020-08-27)
141
- - Firefox ≥ 79 (2020-07-28)
142
- - Safari14 (2020-09-16)
144
+ Environments that support [Exponentiation (`**`)](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators/Exponentiation) and [`TextEncoder`](https://developer.mozilla.org/docs/Web/API/TextEncoder) :
145
+
146
+ - Desktop
147
+ - Chrome52 (2016-07-20)
148
+ - Edge ≥ 79 (2020-01-15)
149
+ - Firefox52 (2017-03-07)
150
+ - Opera ≥ 39 (2016-08-02)
151
+ - Safari ≥ 10.1 (2017-03-27)
152
+ - Mobile
153
+ - Chrome Android ≥ 52 (2016-07-27)
154
+ - Firefox for Android ≥ 52 (2017-03-07)
155
+ - Opera Android ≥ 41 (2016-10-25)
156
+ - Safari on iOS ≥ 10.3 (2017-03-27)
157
+ - Samsung Browser ≥ 6 (2017-08-23)
158
+ - WebView Android ≥ 51 (2016-06-08)
159
+ - WebView on iOS ≥ 10.3 (2017-03-27)
143
160
 
144
161
  Not recommended for use in environments that support `node:crypto`, as `node:crypto` already provides HMAC-MD5.
145
162
 
@@ -161,13 +178,13 @@ During the adaptation, I discovered that `blueimp-md5` did not correctly handle
161
178
 
162
179
  I also found that using `Array` to process inputs over 512 MiB could throw a `RangeError`, so I replaced it with `Int32Array`.
163
180
 
164
- I demonstrated in practice that HMAC-MD5 can be implemented in an extremely small footprint (997 bytes) while also improving reliability.
181
+ I demonstrated in practice that HMAC-MD5 can be implemented in an extremely small footprint (983 bytes) while also improving reliability.
165
182
 
166
183
  Maybe not many people care about saving just a few KB, but `tinyhmacmd5` exists precisely to "explore the unknown".
167
184
 
168
185
  INVINCIBLE EXPERIMENT!
169
186
 
170
- [查看原文](README-zh.md#为什么做这个项目)
187
+ [Read the original Chinese text](README-zh.md#为什么做这个项目)
171
188
 
172
189
  ---
173
190
 
package/browser.min.js CHANGED
@@ -1,2 +1 @@
1
- /** @license https://bddjr.github.io/tinyhmacmd5/lic */
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}}
1
+ /*! npmjs.com/tinyhmacmd5 */{let r=[],n=0,t=Math,e=t.floor,o=r=>16*e((r+72)/64),f=(n,t,f=0,a=o(t),l=1732584193,c=271733878,i,d,g=[l,~c,~l,c],h=[...g])=>{for(n[a-1]=0|t/2**29,n[e(t/4)]|=128<<(n[a-2]=t<<3);f<n.length;){for(a=0;a<64;)g[d&=3]=0|((c=0|g[d]+r[a]+(l=g[3&++d],c=g[3&++d],i=g[3&++d],(t=a>>4<<2)?t>4?t>8?c^(l|~i):l^c^i:l&i|c&~i:l&c|~l&i)+(0|n[f+(a*(29521>>t)+(1296>>t)&15)]))<<(i="',16%).4$+07&*/5".charCodeAt(3&a++|t))|c>>>64-i)+l;for(;d;f+=4)h[--d]=g[d]=0|h[d]+g[d]}return g},a=(r,n,t=("string"==typeof r?r=(new TextEncoder).encode(r):r).length,e=new Int32Array(o(4*n+t)),f=0)=>{for(;f<t;)e[n++]=r[f++]|r[f++]<<8|r[f++]<<16|r[f++]<<24;return[e,t]};for(var md5=(r,n,t)=>{var e=16,o=null!=n,[l,c]=a(r,o*e),i=[],d=t?new Uint8Array(e):"";if(o){let[r,t]=a(n,0);for(t>64&&(r=f(r,t));e;)i[--e]=1785358954^(l[e]=909522486^r[e]);e=16,l=i.concat(f(l,64+c)),c=80}for(l=f(l,c);e;t?d[e]=i:d=(i>>4&&"")+i.toString(16)+d)i=l[--e>>2]>>8*e&255;return d};n<64;)r[n]=0|2**32*t.abs(t.sin(++n))}
package/main.js CHANGED
@@ -1,17 +1,19 @@
1
- /** @license https://bddjr.github.io/tinyhmacmd5/lic */
1
+ /*! npmjs.com/tinyhmacmd5 */
2
2
 
3
3
  // Adapted from https://github.com/blueimp/JavaScript-MD5
4
4
 
5
5
  /** @type {number[]} MD5 constants cached in memory */
6
6
  let K = []
7
7
 
8
+ let i = 0
9
+
8
10
  let $Math = Math
9
11
 
10
12
  let floor = $Math.floor
11
13
 
12
14
  /** @param {number} byteLen */
13
15
  // `byteLen` may be >= 2**32, so cannot use `>>>` as a replacement for `floor`
14
- let toBinlLen = (byteLen) => floor((byteLen + 72) / 64) * 16
16
+ let wordsLen = (byteLen) => floor((byteLen + 72) / 64) * 16
15
17
 
16
18
  /**
17
19
  * Calculate the MD5 of an array of little-endian words, and a byte length.
@@ -24,12 +26,12 @@ let toBinlLen = (byteLen) => floor((byteLen + 72) / 64) * 16
24
26
  *
25
27
  * @returns {number[]} MD5 Array
26
28
  */
27
- let binlMD5 = (
29
+ let wordsMD5 = (
28
30
  x,
29
31
  l,
30
32
  // var:
31
33
  i = 0,
32
- j = toBinlLen(l),
34
+ j = wordsLen(l),
33
35
  t0 = 1732584193,
34
36
  t1 = 271733878,
35
37
  t2,
@@ -37,8 +39,6 @@ let binlMD5 = (
37
39
  output = [t0, ~t1, ~t0, t1],
38
40
  oldOutput = [...output],
39
41
  ) => {
40
- // console.time("binlMD5")
41
-
42
42
  // append padding
43
43
  // `l` may be >= 2**32, so cannot use `>>>` as a replacement for `floor`
44
44
  x[j - 1] = 0 | l / 2 ** 29;
@@ -47,35 +47,35 @@ let binlMD5 = (
47
47
  for (; i < x.length;) {
48
48
  for (j = 0; j < 64;) {
49
49
  output[oi &= 3] = 0 | (
50
- (t1 = 0 | (
51
- output[oi] +
52
- (
53
- t0 = output[++oi & 3],
54
- t1 = output[++oi & 3],
55
- t2 = output[++oi & 3],
56
- (l = j >> 4 << 2)
57
- ? l > 4
58
- ? l > 8
59
- ? t1 ^ (t0 | ~t2) // Round 4: I
60
- : t0 ^ t1 ^ t2 // Round 3: H
61
- : t0 & t2 | t1 & ~t2 // Round 2: G
62
- : t0 & t1 | ~t0 & t2 // Round 1: F
63
- ) +
64
- (
65
- 0 | x[i + (j * (0x7351 >> l) + (0x0510 >> l) & 15)]
66
- ) +
67
- (
68
- t2 = "',16%).4$+07&*/5".charCodeAt(j & 3 | l),
69
- K[63 - j++] ??= 0 | 2 ** 32 * $Math.abs($Math.sin(j))
50
+ (
51
+ t1 = 0 | (
52
+ output[oi] +
53
+ K[j] +
54
+ (
55
+ t0 = output[++oi & 3],
56
+ t1 = output[++oi & 3],
57
+ t2 = output[++oi & 3],
58
+ (l = j >> 4 << 2)
59
+ ? l > 4
60
+ ? l > 8
61
+ ? t1 ^ (t0 | ~t2) // Round 4: I
62
+ : t0 ^ t1 ^ t2 // Round 3: H
63
+ : t0 & t2 | t1 & ~t2 // Round 2: G
64
+ : t0 & t1 | ~t0 & t2 // Round 1: F
65
+ ) +
66
+ (
67
+ 0 | x[i + (j * (0x7351 >> l) + (0x0510 >> l) & 15)]
68
+ )
70
69
  )
71
- )) << t2 | t1 >>> 64 - t2
70
+ ) << (
71
+ t2 = "',16%).4$+07&*/5".charCodeAt(j++ & 3 | l)
72
+ ) | t1 >>> 64 - t2
72
73
  ) + t0
73
74
  }
74
75
  for (; oi; i += 4) {
75
76
  oldOutput[--oi] = output[oi] = 0 | oldOutput[oi] + output[oi]
76
77
  }
77
78
  }
78
- // console.timeEnd("binlMD5")
79
79
  return output
80
80
  }
81
81
 
@@ -87,7 +87,7 @@ let binlMD5 = (
87
87
  *
88
88
  * @returns {[Int32Array<ArrayBuffer> | number[], number]}
89
89
  */
90
- let inputToBinl = (
90
+ let inputToWords = (
91
91
  input,
92
92
  j,
93
93
  // var:
@@ -98,10 +98,9 @@ let inputToBinl = (
98
98
  ).length,
99
99
  // Using `Array` to process inputs over 512 MiB could throw a `RangeError`,
100
100
  // so I replaced it with `Int32Array`.
101
- output = new Int32Array(toBinlLen(j * 4 + byteLen)),
101
+ output = new Int32Array(wordsLen(j * 4 + byteLen)),
102
102
  i = 0,
103
103
  ) => {
104
- // console.time("inputToBinl")
105
104
  for (; i < byteLen;) {
106
105
  output[j++] = (
107
106
  input[i++] |
@@ -110,7 +109,6 @@ let inputToBinl = (
110
109
  input[i++] << 24
111
110
  )
112
111
  }
113
- // console.timeEnd("inputToBinl")
114
112
  return [output, byteLen]
115
113
  }
116
114
 
@@ -128,7 +126,7 @@ let inputToBinl = (
128
126
  var md5 = (data, key, raw) => {
129
127
  var i = 16
130
128
  , hasKey = key != null
131
- , [bdata, dataByteLen] = inputToBinl(data, /**@type {*}*/(hasKey) * i)
129
+ , [bdata, dataByteLen] = inputToWords(data, /**@type {*}*/(hasKey) * i)
132
130
 
133
131
  /** @type {*} */
134
132
  var temp = []
@@ -138,22 +136,22 @@ var md5 = (data, key, raw) => {
138
136
 
139
137
  if (hasKey) {
140
138
  // HMAC
141
- let [bkey, keyByteLen] = inputToBinl(key, 0)
139
+ let [bkey, keyByteLen] = inputToWords(key, 0)
142
140
  if (keyByteLen > 64) {
143
- bkey = binlMD5(bkey, keyByteLen)
141
+ bkey = wordsMD5(bkey, keyByteLen)
144
142
  }
145
143
  for (; i;) {
146
144
  // (0x36363636 ^ 0x5c5c5c5c) == 0x6a6a6a6a
147
145
  temp[--i] = 0x6a6a6a6a ^ (bdata[i] = 0x36363636 ^ bkey[i])
148
146
  }
149
147
  i = 16
150
- bdata = temp.concat(binlMD5(bdata, 64 + dataByteLen))
148
+ bdata = temp.concat(wordsMD5(bdata, 64 + dataByteLen))
151
149
  dataByteLen = 80
152
150
  }
153
151
 
154
- bdata = binlMD5(bdata, dataByteLen)
152
+ bdata = wordsMD5(bdata, dataByteLen)
155
153
 
156
- // binl to bytes or hex
154
+ // words to bytes or hex
157
155
  for (; i;
158
156
  raw
159
157
  ? out[i] = temp
@@ -165,4 +163,8 @@ var md5 = (data, key, raw) => {
165
163
  return out
166
164
  }
167
165
 
166
+ for (; i < 64;) {
167
+ K[i] = 0 | 2 ** 32 * $Math.abs($Math.sin(++i))
168
+ }
169
+
168
170
  export default md5
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "tinyhmacmd5",
3
- "version": "0.1.8",
4
- "description": "A tiny and reliable HMAC-MD5 implementation for JavaScript: browser.min.js is only 997 bytes.",
3
+ "version": "0.2.0",
4
+ "description": "A tiny and reliable HMAC-MD5 implementation for JavaScript: browser.min.js is only 983 bytes.",
5
5
  "author": "bddjr",
6
6
  "license": "MIT",
7
7
  "type": "module",
@@ -60,7 +60,7 @@
60
60
  "typescript": "^7.0.2"
61
61
  },
62
62
  "scripts": {
63
- "build": "tsc && node scripts/build.mjs && es-check es2021 --module --checkFeatures main.js browser.min.js",
63
+ "build": "tsc && node scripts/build.mjs && es-check es2016 --module --checkFeatures main.js browser.min.js",
64
64
  "build:unchanged": "node scripts/build-unchanged.mjs",
65
65
  "test": "pnpm build && pnpm test:only",
66
66
  "test:only": "node scripts/test.mjs",