| Name | Message | Date |
|---|---|---|
| 📁 ui | 10 hours ago | |
| 📄 api.ts | 10 hours ago | |
| 📄 auth.ts | 10 hours ago | |
| 📄 content.ts | 10 hours ago | |
| 📄 errors.ts | 10 hours ago | |
| 📄 hash.ts | 10 hours ago | |
| 📄 md5.ts | 10 hours ago | |
| 📄 selectors.ts | 10 hours ago | |
| 📄 titles.ts | 10 hours ago |
📄
src/md5.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
/**
* Minimal, dependency-free MD5 (RFC 1321).
*
* Only used to compute the media CDN "hotlink" hash (see hash.ts) — not for
* anything security sensitive.
*/
const SHIFTS = new Uint8Array([
7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14,
20, 5, 9, 14, 20, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 6, 10, 15, 21, 6,
10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21,
]);
const SINE_TABLE = new Uint32Array(64);
for (let i = 0; i < 64; i++) {
SINE_TABLE[i] = Math.floor(Math.abs(Math.sin(i + 1)) * 2 ** 32);
}
export function md5(message: string): string {
const messageBytes = new TextEncoder().encode(message);
const messageLength = messageBytes.length;
// Padded message: data + 0x80 + zeros + 64-bit little-endian bit length.
const paddedLength = (((messageLength + 8) >>> 6) + 1) << 6;
const padded = new Uint8Array(paddedLength);
padded.set(messageBytes);
padded[messageLength] = 0x80;
const view = new DataView(padded.buffer);
view.setUint32(paddedLength - 8, messageLength << 3, true);
view.setUint32(paddedLength - 4, Math.floor(messageLength / 2 ** 29), true);
let a0 = 0x67452301;
let b0 = 0xefcdab89;
let c0 = 0x98badcfe;
let d0 = 0x10325476;
const words = new Uint32Array(16);
for (let offset = 0; offset < paddedLength; offset += 64) {
for (let i = 0; i < 16; i++) {
words[i] = view.getUint32(offset + i * 4, true);
}
let a = a0;
let b = b0;
let c = c0;
let d = d0;
for (let i = 0; i < 64; i++) {
let f: number;
let g: number;
if (i < 16) {
f = (b & c) | (~b & d);
g = i;
} else if (i < 32) {
f = (d & b) | (~d & c);
g = (5 * i + 1) % 16;
} else if (i < 48) {
f = b ^ c ^ d;
g = (3 * i + 5) % 16;
} else {
f = c ^ (b | ~d);
g = (7 * i) % 16;
}
const temp = d;
d = c;
c = b;
const sum = (f + a + SINE_TABLE[i]! + words[g]!) >>> 0;
const shift = SHIFTS[i]!;
b = (b + ((sum << shift) | (sum >>> (32 - shift)))) >>> 0;
a = temp;
}
a0 = (a0 + a) >>> 0;
b0 = (b0 + b) >>> 0;
c0 = (c0 + c) >>> 0;
d0 = (d0 + d) >>> 0;
}
const digest = new DataView(new ArrayBuffer(16));
digest.setUint32(0, a0, true);
digest.setUint32(4, b0, true);
digest.setUint32(8, c0, true);
digest.setUint32(12, d0, true);
let hex = '';
for (let i = 0; i < 16; i++) {
hex += digest.getUint8(i).toString(16).padStart(2, '0');
}
return hex;
}