tinyhmacmd5 0.0.7 → 0.1.1
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 +9 -1
- package/browser.min.js +1 -1
- package/main.d.ts +12 -4
- package/main.js +63 -51
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -2,10 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
A tiny JavaScript HMAC-MD5 implementation.
|
|
4
4
|
|
|
5
|
-
The minified browser bundle ([`browser.min.js`](browser.min.js)) is only
|
|
5
|
+
The minified browser bundle ([`browser.min.js`](browser.min.js)) is only 1057 bytes.
|
|
6
6
|
|
|
7
7
|
Preview: https://bddjr.github.io/tinyhmacmd5/
|
|
8
8
|
|
|
9
|
+
> [!WARNING]
|
|
10
|
+
> MD5 is cryptographically broken and unsafe for security-sensitive applications.
|
|
11
|
+
> Do not rely on it for password hashing, digital signatures, or certificate verification.
|
|
12
|
+
|
|
9
13
|
## Setup
|
|
10
14
|
|
|
11
15
|
### npm
|
|
@@ -30,6 +34,10 @@ See https://www.jsdelivr.com/package/npm/tinyhmacmd5
|
|
|
30
34
|
|
|
31
35
|
## Example
|
|
32
36
|
|
|
37
|
+
> [!WARNING]
|
|
38
|
+
> Please make sure on your own that the types of input parameters conform to the definitions in [`main.d.ts`](main.d.ts).
|
|
39
|
+
> If you pass wrong types, it may not throw an error and may produce incorrect results.
|
|
40
|
+
|
|
33
41
|
HMAC-MD5:
|
|
34
42
|
|
|
35
43
|
```js
|
package/browser.min.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/** @license https://bddjr.github.io/tinyhmacmd5/lic */
|
|
2
|
-
{let r=1732584193,e=271733878,
|
|
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,i=[],u=(u,d,h=0,c=l(d),g,s,w,y,A=[r,t,n,e],v=[...A])=>{for(u[c-1]=0|8*d/o,u[c-2]=0|8*d,u[a(d/4)]|=128<<d%4*8;h<u.length;h+=16){for(y=c=0;c<64;)A[3&y]=0|((g=0|(g=A[3&++y],s=A[3&++y],w=A[3&++y],((d=c>>4<<2)?d>4?d>8?s^(g|~w):g^s^w:g&w|s&~w:g&s|~g&w)+(0|u[h+(c*(29521>>d)+(1296>>d)&15)])+(s=31&"',16%).4$+07&*/5".charCodeAt(d+c%4),i[63-c++]??=0|o*f.abs(f.sin(c)))+A[y+1&3]))<<s|g>>>32-s)+A[y+2&3];for(y=4;y;)v[--y]=A[y]=0|v[y]+A[y]}return A},d=(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]=d(r,o*t),l=new Uint8Array(t);if(o){let[r,n]=d(e,0),o=[];for(n>64&&(r=u(r,n));t;)f[--t]=909522486^r[t],o[t]=1549556828^r[t];t=16,(f=u(f,64+a)).unshift(...o),a=80}for(f=u(f,a);t;)l[--t]=f[t>>2]>>>t%4*8;return n?l:l.reduce((r,e)=>r+(e>>4&&"")+e.toString(16),"")}}
|
package/main.d.ts
CHANGED
|
@@ -4,13 +4,21 @@
|
|
|
4
4
|
* By default, returns the hash as a lowercase hexadecimal string.
|
|
5
5
|
* If `raw` is true, returns a Uint8Array.
|
|
6
6
|
*
|
|
7
|
-
* @param {string | Uint8Array} data The input data to hash. Strings are UTF‑8 encoded.
|
|
8
|
-
* @param {string | Uint8Array | null} [key] Optional HMAC key. When given, HMAC‑MD5 is calculated instead of plain MD5.
|
|
7
|
+
* @param {string | Uint8Array | Uint8ClampedArray} data The input data to hash. Strings are UTF‑8 encoded.
|
|
8
|
+
* @param {string | Uint8Array | Uint8ClampedArray | null} [key] Optional HMAC key. When given, HMAC‑MD5 is calculated instead of plain MD5.
|
|
9
9
|
* @param {boolean} [raw] If true, the hash is returned as raw bytes (Uint8Array); otherwise, as a hex string.
|
|
10
10
|
* @returns {string | Uint8Array<ArrayBuffer>} The MD5 (or HMAC‑MD5) digest, either as a hex string or a Uint8Array.
|
|
11
11
|
*/
|
|
12
12
|
declare var md5: {
|
|
13
|
-
(
|
|
14
|
-
|
|
13
|
+
(
|
|
14
|
+
data: string | Uint8Array | Uint8ClampedArray,
|
|
15
|
+
key?: string | Uint8Array | Uint8ClampedArray | null,
|
|
16
|
+
raw?: false
|
|
17
|
+
): string;
|
|
18
|
+
(
|
|
19
|
+
data: string | Uint8Array | Uint8ClampedArray,
|
|
20
|
+
key: string | Uint8Array | Uint8ClampedArray | null | undefined,
|
|
21
|
+
raw: true
|
|
22
|
+
): Uint8Array<ArrayBuffer>;
|
|
15
23
|
};
|
|
16
24
|
export default md5;
|
package/main.js
CHANGED
|
@@ -7,14 +7,23 @@ let A = 1732584193
|
|
|
7
7
|
, C = ~A
|
|
8
8
|
, B = ~D
|
|
9
9
|
|
|
10
|
+
let $2_32 = 2 ** 32
|
|
11
|
+
|
|
12
|
+
let $Math = Math
|
|
13
|
+
|
|
14
|
+
let floor = $Math.floor
|
|
15
|
+
|
|
16
|
+
/** @param {number} byteLen */
|
|
17
|
+
let toBinlLen = (byteLen) => floor((byteLen + 8) / 64) * 16 + 16
|
|
18
|
+
|
|
10
19
|
/** @type {number[]} MD5 constants cached in memory */
|
|
11
20
|
let K = []
|
|
12
21
|
|
|
13
22
|
/**
|
|
14
23
|
* Calculate the MD5 of an array of little-endian words, and a bit length.
|
|
15
24
|
*
|
|
16
|
-
* @param {number[]} x Array of little-endian words
|
|
17
|
-
* @param {number} l
|
|
25
|
+
* @param {Int32Array | number[]} x Array of little-endian words
|
|
26
|
+
* @param {number} l Byte length
|
|
18
27
|
*
|
|
19
28
|
* @param {number} [j]
|
|
20
29
|
* @param {number} [t0]
|
|
@@ -29,31 +38,29 @@ let binlMD5 = (
|
|
|
29
38
|
l,
|
|
30
39
|
// var:
|
|
31
40
|
i = 0,
|
|
32
|
-
j,
|
|
41
|
+
j = toBinlLen(l),
|
|
33
42
|
t0,
|
|
34
43
|
t1,
|
|
35
44
|
t2,
|
|
36
45
|
oi,
|
|
37
46
|
output = [A, B, C, D],
|
|
38
47
|
oldOutput = [...output],
|
|
39
|
-
o = (
|
|
40
|
-
/** @param {*} [_] */
|
|
41
|
-
_ => output[++oi & 3]
|
|
42
|
-
),
|
|
43
48
|
) => {
|
|
49
|
+
// console.time("binlMD5")
|
|
44
50
|
|
|
45
51
|
// append padding
|
|
46
|
-
x[
|
|
47
|
-
x[
|
|
52
|
+
x[j - 1] = 0 | l * 8 / $2_32;
|
|
53
|
+
x[j - 2] = 0 | l * 8;
|
|
54
|
+
x[floor(l / 4)] |= 0x80 << l % 4 * 8;
|
|
48
55
|
|
|
49
56
|
for (; i < x.length; i += 16) {
|
|
50
|
-
for (oi = j = 0; j < 64;
|
|
57
|
+
for (oi = j = 0; j < 64;) {
|
|
51
58
|
output[oi & 3] = (
|
|
52
59
|
t0 = 0 | (
|
|
53
60
|
(
|
|
54
|
-
t0 =
|
|
55
|
-
t1 =
|
|
56
|
-
t2 =
|
|
61
|
+
t0 = output[++oi & 3],
|
|
62
|
+
t1 = output[++oi & 3],
|
|
63
|
+
t2 = output[++oi & 3],
|
|
57
64
|
(l = j >> 4 << 2)
|
|
58
65
|
? l > 4
|
|
59
66
|
? l > 8
|
|
@@ -66,60 +73,67 @@ let binlMD5 = (
|
|
|
66
73
|
0 | x[i + (j * (0x7351 >> l) + (0x0510 >> l) & 15)]
|
|
67
74
|
) +
|
|
68
75
|
(
|
|
69
|
-
t1 = "',16%).4$+07&*/5".charCodeAt(l + j % 4)
|
|
70
|
-
K[63 - j++] ??= 0 |
|
|
76
|
+
t1 = "',16%).4$+07&*/5".charCodeAt(l + j % 4) & 31,
|
|
77
|
+
K[63 - j++] ??= 0 | $2_32 * $Math.abs($Math.sin(j))
|
|
71
78
|
) +
|
|
72
|
-
|
|
79
|
+
output[oi + 1 & 3]
|
|
73
80
|
),
|
|
74
|
-
0 | (t0 << t1 | t0 >>> 32 - t1) +
|
|
81
|
+
0 | (t0 << t1 | t0 >>> 32 - t1) + output[oi + 2 & 3]
|
|
75
82
|
)
|
|
76
83
|
}
|
|
77
84
|
for (oi = 4; oi;) {
|
|
78
85
|
oldOutput[--oi] = output[oi] = 0 | oldOutput[oi] + output[oi]
|
|
79
86
|
}
|
|
80
87
|
}
|
|
88
|
+
// console.timeEnd("binlMD5")
|
|
81
89
|
return output
|
|
82
90
|
}
|
|
83
91
|
|
|
84
92
|
/**
|
|
85
93
|
* Convert bytes to an array of little-endian words
|
|
86
94
|
*
|
|
87
|
-
* @param {
|
|
88
|
-
* @param {number}
|
|
95
|
+
* @param {*} input
|
|
96
|
+
* @param {number} j pad int32 length
|
|
89
97
|
*
|
|
90
|
-
* @
|
|
91
|
-
*
|
|
92
|
-
* @returns {[number[], number]}
|
|
98
|
+
* @returns {[Int32Array<ArrayBuffer> | number[], number]}
|
|
93
99
|
*/
|
|
94
100
|
let inputToBinl = (
|
|
95
101
|
input,
|
|
96
|
-
|
|
102
|
+
j,
|
|
97
103
|
// var:
|
|
98
|
-
|
|
104
|
+
byteLen = (
|
|
99
105
|
typeof input == 'string'
|
|
100
106
|
? input = new TextEncoder().encode(input)
|
|
101
107
|
: input
|
|
102
108
|
).length,
|
|
103
|
-
|
|
104
|
-
|
|
109
|
+
// Using Array would fail to handle large files, so Int32Array must be used.
|
|
110
|
+
output = new Int32Array(toBinlLen(j * 4 + byteLen)),
|
|
111
|
+
i = 0,
|
|
105
112
|
) => {
|
|
106
|
-
|
|
107
|
-
|
|
113
|
+
// console.time("inputToBinl")
|
|
114
|
+
for (; i < byteLen;) {
|
|
115
|
+
output[j++] = (
|
|
116
|
+
input[i++] |
|
|
117
|
+
input[i++] << 8 |
|
|
118
|
+
input[i++] << 16 |
|
|
119
|
+
input[i++] << 24
|
|
120
|
+
)
|
|
108
121
|
}
|
|
109
|
-
|
|
122
|
+
// console.timeEnd("inputToBinl")
|
|
123
|
+
return [output, byteLen]
|
|
110
124
|
}
|
|
111
125
|
|
|
112
126
|
/**
|
|
113
127
|
* @overload
|
|
114
|
-
* @param {string | Uint8Array} data
|
|
115
|
-
* @param {string | Uint8Array | null} [key]
|
|
128
|
+
* @param {string | Uint8Array | Uint8ClampedArray} data
|
|
129
|
+
* @param {string | Uint8Array | Uint8ClampedArray | null} [key]
|
|
116
130
|
* @param {false} [raw]
|
|
117
131
|
* @returns {string}
|
|
118
132
|
*/
|
|
119
133
|
/**
|
|
120
134
|
* @overload
|
|
121
|
-
* @param {string | Uint8Array} data
|
|
122
|
-
* @param {string | Uint8Array | null | undefined} key
|
|
135
|
+
* @param {string | Uint8Array | Uint8ClampedArray} data
|
|
136
|
+
* @param {string | Uint8Array | Uint8ClampedArray | null | undefined} key
|
|
123
137
|
* @param {true} raw
|
|
124
138
|
* @returns {Uint8Array<ArrayBuffer>}
|
|
125
139
|
*/
|
|
@@ -129,37 +143,35 @@ let inputToBinl = (
|
|
|
129
143
|
* By default, returns the hash as a lowercase hexadecimal string.
|
|
130
144
|
* If `raw` is true, returns a Uint8Array.
|
|
131
145
|
*
|
|
132
|
-
* @param {string | Uint8Array} data The input data to hash. Strings are UTF‑8 encoded.
|
|
133
|
-
* @param {string | Uint8Array | null} [key] Optional HMAC key. When given, HMAC‑MD5 is calculated instead of plain MD5.
|
|
146
|
+
* @param {string | Uint8Array | Uint8ClampedArray} data The input data to hash. Strings are UTF‑8 encoded.
|
|
147
|
+
* @param {string | Uint8Array | Uint8ClampedArray | null} [key] Optional HMAC key. When given, HMAC‑MD5 is calculated instead of plain MD5.
|
|
134
148
|
* @param {boolean} [raw] If true, the hash is returned as raw bytes (Uint8Array); otherwise, as a hex string.
|
|
135
149
|
* @returns {string | Uint8Array<ArrayBuffer>} The MD5 (or HMAC‑MD5) digest, either as a hex string or a Uint8Array.
|
|
136
150
|
*/
|
|
137
151
|
var md5 = (data, key, raw) => {
|
|
138
152
|
var i = 16
|
|
139
153
|
, hasKey = key != null
|
|
140
|
-
, [bdata,
|
|
154
|
+
, [bdata, dataByteLen] = inputToBinl(data, /**@type {*}*/(hasKey) * i)
|
|
141
155
|
, out = new Uint8Array(i)
|
|
142
156
|
|
|
143
157
|
if (hasKey) {
|
|
144
158
|
// HMAC
|
|
145
|
-
let [bkey,
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
bkey = binlMD5(bkey, keyBitlen)
|
|
159
|
+
let [bkey, keyByteLen] = inputToBinl(key, 0)
|
|
160
|
+
let opad = []
|
|
161
|
+
if (keyByteLen > 64) {
|
|
162
|
+
bkey = binlMD5(bkey, keyByteLen)
|
|
163
|
+
}
|
|
164
|
+
for (; i;) {
|
|
165
|
+
bdata[--i] = 0x36363636 ^ bkey[i] // ipad
|
|
166
|
+
opad[i] = 0x5c5c5c5c ^ bkey[i]
|
|
154
167
|
}
|
|
155
|
-
|
|
156
|
-
bdata = binlMD5(bdata,
|
|
157
|
-
bdata.unshift(...
|
|
158
|
-
|
|
159
|
-
bitLen = 640
|
|
168
|
+
i = 16
|
|
169
|
+
bdata = binlMD5(bdata, 64 + dataByteLen)
|
|
170
|
+
bdata.unshift(...opad)
|
|
171
|
+
dataByteLen = 80
|
|
160
172
|
}
|
|
161
173
|
|
|
162
|
-
bdata = binlMD5(bdata,
|
|
174
|
+
bdata = binlMD5(bdata, dataByteLen)
|
|
163
175
|
|
|
164
176
|
// binl to bytes
|
|
165
177
|
for (; i;) {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tinyhmacmd5",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "A tiny JavaScript HMAC-MD5 implementation. The minified browser bundle is only
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "A tiny JavaScript HMAC-MD5 implementation. The minified browser bundle is only 1057 bytes.",
|
|
5
5
|
"author": "bddjr",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"type": "module",
|