tinyhmacmd5 0.1.5 → 0.1.6

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
@@ -3,7 +3,7 @@ English | [中文](README-zh.md)
3
3
  # Tiny HMAC MD5
4
4
 
5
5
  A tiny, fully compliant HMAC-MD5 implementation for JavaScript:
6
- [`browser.min.js`](browser.min.js) is only **1045 bytes**.
6
+ [`browser.min.js`](browser.min.js) is only **1017 bytes**.
7
7
 
8
8
  - **Input type**: `string` (UTF‑8), `Uint8Array` or `Uint8ClampedArray`
9
9
  - **Output type**: hex `string` or raw `Uint8Array`
@@ -11,6 +11,8 @@ A tiny, fully compliant HMAC-MD5 implementation for JavaScript:
11
11
  - **TypeScript‑ready**: [`main.d.ts`](main.d.ts)
12
12
  - **0 dependencies**
13
13
 
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.
15
+
14
16
  **Live demo**: https://bddjr.github.io/tinyhmacmd5/
15
17
 
16
18
  > [!WARNING]
@@ -109,6 +111,8 @@ Environments that support [Nullish coalescing assignment (`??=`)](https://develo
109
111
  - Firefox ≥ 79 (2020-07-28)
110
112
  - Safari ≥ 14 (2020-09-16)
111
113
 
114
+ Not recommended for use in environments that support `node:crypto`, as `node:crypto` already provides HMAC-MD5.
115
+
112
116
  ---
113
117
 
114
118
  ## Why I Made This Project
@@ -131,7 +135,7 @@ During the adaptation, I discovered that `blueimp-md5` did not correctly handle
131
135
 
132
136
  I also found that using `Array` to process inputs over 512 MiB could throw a `RangeError`, so I replaced it with `Int32Array`.
133
137
 
134
- I demonstrated in practice that HMAC-MD5 can be implemented in an extremely small footprint (1045 bytes) while also improving reliability.
138
+ I demonstrated in practice that HMAC-MD5 can be implemented in an extremely small footprint (1017 bytes) while also improving reliability.
135
139
 
136
140
  Maybe not many people care about saving just a few KB, but `tinyhmacmd5` exists precisely to "explore the unknown".
137
141
 
package/browser.min.js CHANGED
@@ -1,2 +1,2 @@
1
1
  /** @license https://bddjr.github.io/tinyhmacmd5/lic */
2
- {let r=1732584193,e=271733878,n=~r,t=~e,o=2**32,f=Math,a=f.floor,l=r=>16*a((r+8)/64)+16,c=[],d=(d,i,u=0,g=l(i),h,s,w,y,A=[r,t,n,e],v=[...A])=>{for(d[g-1]=0|8*i/o,d[g-2]=0|8*i,d[a(i/4)]|=128<<i%4*8;u<d.length;u+=16){for(y=g=0;g<64;)A[3&y]=0|((h=0|(h=A[3&++y],s=A[3&++y],w=A[3&++y],((i=g>>4<<2)?i>4?i>8?s^(h|~w):h^s^w:h&w|s&~w:h&s|~h&w)+(0|d[u+(g*(29521>>i)+(1296>>i)&15)])+(s="',16%).4$+07&*/5".charCodeAt(i+g%4),c[63-g++]??=0|o*f.abs(f.sin(g)))+A[y+1&3]))<<s|h>>>64-s)+A[y+2&3];for(y=4;y;)v[--y]=A[y]=0|v[y]+A[y]}return A},i=(r,e,n=("string"==typeof r?r=(new TextEncoder).encode(r):r).length,t=new Int32Array(l(4*e+n)),o=0)=>{for(;o<n;)t[e++]=r[o++]|r[o++]<<8|r[o++]<<16|r[o++]<<24;return[t,n]};var md5=(r,e,n)=>{var t=16,o=null!=e,[f,a]=i(r,o*t),l=new Uint8Array(t);if(o){let[r,n]=i(e,0),o=[];for(n>64&&(r=d(r,n));t;)o[--t]=1785358954^(f[t]=909522486^r[t]);t=16,f=o.concat(d(f,64+a)),a=80}for(f=d(f,a);t;)l[--t]=f[t>>2]>>>t%4*8;return n?l:l.reduce((r,e)=>r+(e>>4&&"")+e.toString(16),"")}}
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}}
package/main.js CHANGED
@@ -4,20 +4,17 @@
4
4
 
5
5
  let A = 1732584193
6
6
  , D = 271733878
7
- , C = ~A
8
- , B = ~D
9
7
 
10
- let $2_32 = 2 ** 32
8
+ /** @type {number[]} MD5 constants cached in memory */
9
+ let K = []
11
10
 
12
11
  let $Math = Math
13
12
 
14
13
  let floor = $Math.floor
15
14
 
16
15
  /** @param {number} byteLen */
17
- let toBinlLen = (byteLen) => floor((byteLen + 8) / 64) * 16 + 16
18
-
19
- /** @type {number[]} MD5 constants cached in memory */
20
- let K = []
16
+ // `byteLen` may be >= 2**32, so cannot use `>>>` as a replacement for `floor`
17
+ let toBinlLen = (byteLen) => floor((byteLen + 72) / 64) * 16
21
18
 
22
19
  /**
23
20
  * Calculate the MD5 of an array of little-endian words, and a byte length.
@@ -43,19 +40,20 @@ let binlMD5 = (
43
40
  t1,
44
41
  t2,
45
42
  oi,
46
- output = [A, B, C, D],
43
+ output = [A, ~D, ~A, D],
47
44
  oldOutput = [...output],
48
45
  ) => {
49
46
  // console.time("binlMD5")
50
47
 
51
48
  // append padding
52
- x[j - 1] = 0 | l * 8 / $2_32;
49
+ // `l` may be >= 2**32, so cannot use `>>>` as a replacement for `floor`
50
+ x[j - 1] = 0 | l / 2 ** 29;
53
51
  x[j - 2] = 0 | l * 8;
54
- x[floor(l / 4)] |= 0x80 << l % 4 * 8;
52
+ x[floor(l / 4)] |= 0x80 << l * 8;
55
53
 
56
- for (; i < x.length; i += 16) {
57
- for (oi = j = 0; j < 64;) {
58
- output[oi & 3] = (
54
+ for (; i < x.length;) {
55
+ for (j = 0; j < 64;) {
56
+ output[oi &= 3] = (
59
57
  t0 = 0 | (
60
58
  (
61
59
  t0 = output[++oi & 3],
@@ -74,14 +72,14 @@ let binlMD5 = (
74
72
  ) +
75
73
  (
76
74
  t1 = "',16%).4$+07&*/5".charCodeAt(l + j % 4),
77
- K[63 - j++] ??= 0 | $2_32 * $Math.abs($Math.sin(j))
75
+ K[63 - j++] ??= 0 | 2 ** 32 * $Math.abs($Math.sin(j))
78
76
  ) +
79
77
  output[oi + 1 & 3]
80
78
  ),
81
79
  0 | (t0 << t1 | t0 >>> 64 - t1) + output[oi + 2 & 3]
82
80
  )
83
81
  }
84
- for (oi = 4; oi;) {
82
+ for (; oi; i += 4) {
85
83
  oldOutput[--oi] = output[oi] = 0 | oldOutput[oi] + output[oi]
86
84
  }
87
85
  }
@@ -139,34 +137,40 @@ var md5 = (data, key, raw) => {
139
137
  var i = 16
140
138
  , hasKey = key != null
141
139
  , [bdata, dataByteLen] = inputToBinl(data, /**@type {*}*/(hasKey) * i)
142
- , out = new Uint8Array(i)
140
+
141
+ /** @type {*} */
142
+ var temp = []
143
+
144
+ /** @type {*} */
145
+ var out = raw ? new Uint8Array(i) : ''
143
146
 
144
147
  if (hasKey) {
145
148
  // HMAC
146
149
  let [bkey, keyByteLen] = inputToBinl(key, 0)
147
- let opad = []
148
150
  if (keyByteLen > 64) {
149
151
  bkey = binlMD5(bkey, keyByteLen)
150
152
  }
151
153
  for (; i;) {
152
154
  // (0x36363636 ^ 0x5c5c5c5c) == 0x6a6a6a6a
153
- opad[--i] = 0x6a6a6a6a ^ (bdata[i] = 0x36363636 ^ bkey[i])
155
+ temp[--i] = 0x6a6a6a6a ^ (bdata[i] = 0x36363636 ^ bkey[i])
154
156
  }
155
157
  i = 16
156
- bdata = opad.concat(binlMD5(bdata, 64 + dataByteLen))
158
+ bdata = temp.concat(binlMD5(bdata, 64 + dataByteLen))
157
159
  dataByteLen = 80
158
160
  }
159
161
 
160
162
  bdata = binlMD5(bdata, dataByteLen)
161
163
 
162
- // binl to bytes
163
- for (; i;) {
164
- out[--i] = bdata[i >> 2] >>> i % 4 * 8
164
+ // binl to bytes or hex
165
+ for (; i;
166
+ raw
167
+ ? out[i] = temp
168
+ : out = (temp >> 4 && '') + temp.toString(16) + out
169
+ ) {
170
+ temp = bdata[--i >> 2] >> i * 8 & 0xff
165
171
  }
166
172
 
167
- return raw
168
- ? out
169
- : out.reduce((p, v) => p + (v >> 4 && '') + v.toString(16), '')
173
+ return out
170
174
  }
171
175
 
172
176
  export default md5
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "tinyhmacmd5",
3
- "version": "0.1.5",
4
- "description": "A tiny, fully compliant HMAC-MD5 implementation for JavaScript: browser.min.js is only 1045 bytes.",
3
+ "version": "0.1.6",
4
+ "description": "A tiny, fully compliant HMAC-MD5 implementation for JavaScript: browser.min.js is only 1017 bytes.",
5
5
  "author": "bddjr",
6
6
  "license": "MIT",
7
7
  "type": "module",
@@ -17,20 +17,35 @@
17
17
  "keywords": [
18
18
  "md5",
19
19
  "hash",
20
+ "hashing",
20
21
  "hmac",
21
22
  "hmacmd5",
22
23
  "hmac-md5",
23
24
  "tiny",
25
+ "tiny-hmac-md5",
26
+ "small",
27
+ "lightweight",
28
+ "minimal",
24
29
  "hex",
25
30
  "crypto",
26
31
  "encryption",
27
32
  "cryptography",
33
+ "message-digest",
34
+ "cryptographic-hash",
35
+ "web",
36
+ "pure-javascript",
37
+ "esm",
38
+ "javascript",
39
+ "typescript",
40
+ "frontend",
41
+ "front-end",
28
42
  "blueimp",
29
43
  "blueimp-md5",
30
44
  "js-md5",
31
45
  "crypto-js",
32
- "javascript",
33
- "typescript"
46
+ "tiny-hashes",
47
+ "tiny-js-md5",
48
+ "spark-md5"
34
49
  ],
35
50
  "repository": {
36
51
  "type": "git",