129 lines
6.2 KiB
TypeScript
129 lines
6.2 KiB
TypeScript
/**
|
|
* 计算 MD5 摘要。
|
|
* 服务端当前要求登录密码以小写 32 位 MD5 字符串传输。
|
|
*/
|
|
export function md5(value: string): string {
|
|
const bytes = unescape(encodeURIComponent(value))
|
|
const words: number[] = []
|
|
const bitLength = bytes.length * 8
|
|
|
|
for (let index = 0; index < bytes.length; index++) {
|
|
words[index >> 2] = (words[index >> 2] || 0) | (bytes.charCodeAt(index) << ((index % 4) * 8))
|
|
}
|
|
words[bitLength >> 5] = (words[bitLength >> 5] || 0) | (0x80 << (bitLength % 32))
|
|
words[(((bitLength + 64) >>> 9) << 4) + 14] = bitLength
|
|
|
|
let a = 0x67452301
|
|
let b = 0xefcdab89
|
|
let c = 0x98badcfe
|
|
let d = 0x10325476
|
|
|
|
for (let offset = 0; offset < words.length; offset += 16) {
|
|
const oldA = a
|
|
const oldB = b
|
|
const oldC = c
|
|
const oldD = d
|
|
|
|
a = md5Round(a, b, c, d, words[offset] || 0, 7, -680876936)
|
|
d = md5Round(d, a, b, c, words[offset + 1] || 0, 12, -389564586)
|
|
c = md5Round(c, d, a, b, words[offset + 2] || 0, 17, 606105819)
|
|
b = md5Round(b, c, d, a, words[offset + 3] || 0, 22, -1044525330)
|
|
a = md5Round(a, b, c, d, words[offset + 4] || 0, 7, -176418897)
|
|
d = md5Round(d, a, b, c, words[offset + 5] || 0, 12, 1200080426)
|
|
c = md5Round(c, d, a, b, words[offset + 6] || 0, 17, -1473231341)
|
|
b = md5Round(b, c, d, a, words[offset + 7] || 0, 22, -45705983)
|
|
a = md5Round(a, b, c, d, words[offset + 8] || 0, 7, 1770035416)
|
|
d = md5Round(d, a, b, c, words[offset + 9] || 0, 12, -1958414417)
|
|
c = md5Round(c, d, a, b, words[offset + 10] || 0, 17, -42063)
|
|
b = md5Round(b, c, d, a, words[offset + 11] || 0, 22, -1990404162)
|
|
a = md5Round(a, b, c, d, words[offset + 12] || 0, 7, 1804603682)
|
|
d = md5Round(d, a, b, c, words[offset + 13] || 0, 12, -40341101)
|
|
c = md5Round(c, d, a, b, words[offset + 14] || 0, 17, -1502002290)
|
|
b = md5Round(b, c, d, a, words[offset + 15] || 0, 22, 1236535329)
|
|
|
|
a = md5Round2(a, b, c, d, words[offset + 1] || 0, 5, -165796510)
|
|
d = md5Round2(d, a, b, c, words[offset + 6] || 0, 9, -1069501632)
|
|
c = md5Round2(c, d, a, b, words[offset + 11] || 0, 14, 643717713)
|
|
b = md5Round2(b, c, d, a, words[offset] || 0, 20, -373897302)
|
|
a = md5Round2(a, b, c, d, words[offset + 5] || 0, 5, -701558691)
|
|
d = md5Round2(d, a, b, c, words[offset + 10] || 0, 9, 38016083)
|
|
c = md5Round2(c, d, a, b, words[offset + 15] || 0, 14, -660478335)
|
|
b = md5Round2(b, c, d, a, words[offset + 4] || 0, 20, -405537848)
|
|
a = md5Round2(a, b, c, d, words[offset + 9] || 0, 5, 568446438)
|
|
d = md5Round2(d, a, b, c, words[offset + 14] || 0, 9, -1019803690)
|
|
c = md5Round2(c, d, a, b, words[offset + 3] || 0, 14, -187363961)
|
|
b = md5Round2(b, c, d, a, words[offset + 8] || 0, 20, 1163531501)
|
|
a = md5Round2(a, b, c, d, words[offset + 13] || 0, 5, -1444681467)
|
|
d = md5Round2(d, a, b, c, words[offset + 2] || 0, 9, -51403784)
|
|
c = md5Round2(c, d, a, b, words[offset + 7] || 0, 14, 1735328473)
|
|
b = md5Round2(b, c, d, a, words[offset + 12] || 0, 20, -1926607734)
|
|
|
|
a = md5Round3(a, b, c, d, words[offset + 5] || 0, 4, -378558)
|
|
d = md5Round3(d, a, b, c, words[offset + 8] || 0, 11, -2022574463)
|
|
c = md5Round3(c, d, a, b, words[offset + 11] || 0, 16, 1839030562)
|
|
b = md5Round3(b, c, d, a, words[offset + 14] || 0, 23, -35309556)
|
|
a = md5Round3(a, b, c, d, words[offset + 1] || 0, 4, -1530992060)
|
|
d = md5Round3(d, a, b, c, words[offset + 4] || 0, 11, 1272893353)
|
|
c = md5Round3(c, d, a, b, words[offset + 7] || 0, 16, -155497632)
|
|
b = md5Round3(b, c, d, a, words[offset + 10] || 0, 23, -1094730640)
|
|
a = md5Round3(a, b, c, d, words[offset + 13] || 0, 4, 681279174)
|
|
d = md5Round3(d, a, b, c, words[offset] || 0, 11, -358537222)
|
|
c = md5Round3(c, d, a, b, words[offset + 3] || 0, 16, -722521979)
|
|
b = md5Round3(b, c, d, a, words[offset + 6] || 0, 23, 76029189)
|
|
a = md5Round3(a, b, c, d, words[offset + 9] || 0, 4, -640364487)
|
|
d = md5Round3(d, a, b, c, words[offset + 12] || 0, 11, -421815835)
|
|
c = md5Round3(c, d, a, b, words[offset + 15] || 0, 16, 530742520)
|
|
b = md5Round3(b, c, d, a, words[offset + 2] || 0, 23, -995338651)
|
|
|
|
a = md5Round4(a, b, c, d, words[offset] || 0, 6, -198630844)
|
|
d = md5Round4(d, a, b, c, words[offset + 7] || 0, 10, 1126891415)
|
|
c = md5Round4(c, d, a, b, words[offset + 14] || 0, 15, -1416354905)
|
|
b = md5Round4(b, c, d, a, words[offset + 5] || 0, 21, -57434055)
|
|
a = md5Round4(a, b, c, d, words[offset + 12] || 0, 6, 1700485571)
|
|
d = md5Round4(d, a, b, c, words[offset + 3] || 0, 10, -1894986606)
|
|
c = md5Round4(c, d, a, b, words[offset + 10] || 0, 15, -1051523)
|
|
b = md5Round4(b, c, d, a, words[offset + 1] || 0, 21, -2054922799)
|
|
a = md5Round4(a, b, c, d, words[offset + 8] || 0, 6, 1873313359)
|
|
d = md5Round4(d, a, b, c, words[offset + 15] || 0, 10, -30611744)
|
|
c = md5Round4(c, d, a, b, words[offset + 6] || 0, 15, -1560198380)
|
|
b = md5Round4(b, c, d, a, words[offset + 13] || 0, 21, 1309151649)
|
|
a = md5Round4(a, b, c, d, words[offset + 4] || 0, 6, -145523070)
|
|
d = md5Round4(d, a, b, c, words[offset + 11] || 0, 10, -1120210379)
|
|
c = md5Round4(c, d, a, b, words[offset + 2] || 0, 15, 718787259)
|
|
b = md5Round4(b, c, d, a, words[offset + 9] || 0, 21, -343485551)
|
|
|
|
a = (a + oldA) | 0
|
|
b = (b + oldB) | 0
|
|
c = (c + oldC) | 0
|
|
d = (d + oldD) | 0
|
|
}
|
|
|
|
return [a, b, c, d].map((word) => {
|
|
let result = ''
|
|
for (let index = 0; index < 4; index++) {
|
|
result += ((word >> (index * 8)) & 0xff).toString(16).padStart(2, '0')
|
|
}
|
|
return result
|
|
}).join('')
|
|
}
|
|
|
|
function md5Round(a: number, b: number, c: number, d: number, value: number, shift: number, constant: number): number {
|
|
return md5Rotate((a + ((b & c) | (~b & d)) + value + constant) | 0, shift) + b | 0
|
|
}
|
|
|
|
function md5Round2(a: number, b: number, c: number, d: number, value: number, shift: number, constant: number): number {
|
|
return md5Rotate((a + ((b & d) | (c & ~d)) + value + constant) | 0, shift) + b | 0
|
|
}
|
|
|
|
function md5Round3(a: number, b: number, c: number, d: number, value: number, shift: number, constant: number): number {
|
|
return md5Rotate((a + (b ^ c ^ d) + value + constant) | 0, shift) + b | 0
|
|
}
|
|
|
|
function md5Round4(a: number, b: number, c: number, d: number, value: number, shift: number, constant: number): number {
|
|
return md5Rotate((a + (c ^ (b | ~d)) + value + constant) | 0, shift) + b | 0
|
|
}
|
|
|
|
function md5Rotate(value: number, shift: number): number {
|
|
return (value << shift) | (value >>> (32 - shift))
|
|
}
|