Created
April 25, 2023 01:47
-
-
Save shqld/7897e1997a13f738fae3c5bd20ca94c6 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* https://chromium.googlesource.com/chromium/src/third_party/WebKit/Source/devtools/+/eb375f3b31a67df908c93a827dd9e78d3212be60/front_end/product_registry_impl/sha1/sha1.js | |
*/ | |
/* | |
* A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined | |
* in FIPS 180-1 | |
* Version 2.2 Copyright Paul Johnston 2000 - 2009. | |
* Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet | |
* Distributed under the BSD License | |
* See http://pajhome.org.uk/crypt/md5 for details. | |
*/ | |
// clang-format off | |
/* eslint-disable */ | |
/** | |
* @param {string} str | |
* @return {string} | |
*/ | |
export function sha1(str: string) { | |
return rstr2hex(rstr_sha1(str2rstr_utf8(str))) | |
/** | |
* Calculate the SHA1 of a raw string | |
* @param {string} s | |
* @return {string} | |
*/ | |
function rstr_sha1(s: string) { | |
return binb2rstr(binb_sha1(rstr2binb(s), s.length * 8)) | |
} | |
/** | |
* Convert a raw string to a hex string | |
* @param {string} input | |
* @return {string} | |
*/ | |
function rstr2hex(input: string) { | |
let hex_tab = "0123456789abcdef" | |
let output = "" | |
let x | |
for (let i = 0; i < input.length; i++) { | |
x = input.charCodeAt(i) | |
output += hex_tab.charAt((x >>> 4) & 0x0f) + hex_tab.charAt(x & 0x0f) | |
} | |
return output | |
} | |
/** | |
* Encode a string as utf-8. | |
* For efficiency, this assumes the input is valid utf-16. | |
* @param {string} input | |
* @return {string} | |
*/ | |
function str2rstr_utf8(input: string) { | |
let output = "" | |
let i = -1 | |
let x, y | |
while (++i < input.length) { | |
/* Decode utf-16 surrogate pairs */ | |
x = input.charCodeAt(i) | |
y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0 | |
if (0xd800 <= x && x <= 0xdbff && 0xdc00 <= y && y <= 0xdfff) { | |
x = 0x10000 + ((x & 0x03ff) << 10) + (y & 0x03ff) | |
i++ | |
} | |
/* Encode output as utf-8 */ | |
if (x <= 0x7f) output += String.fromCharCode(x) | |
else if (x <= 0x7ff) | |
output += String.fromCharCode(0xc0 | ((x >>> 6) & 0x1f), 0x80 | (x & 0x3f)) | |
else if (x <= 0xffff) | |
output += String.fromCharCode( | |
0xe0 | ((x >>> 12) & 0x0f), | |
0x80 | ((x >>> 6) & 0x3f), | |
0x80 | (x & 0x3f), | |
) | |
else if (x <= 0x1fffff) | |
output += String.fromCharCode( | |
0xf0 | ((x >>> 18) & 0x07), | |
0x80 | ((x >>> 12) & 0x3f), | |
0x80 | ((x >>> 6) & 0x3f), | |
0x80 | (x & 0x3f), | |
) | |
} | |
return output | |
} | |
/** | |
* Convert a raw string to an array of big-endian words | |
* Characters >255 have their high-byte silently ignored. | |
* @param {string} input | |
* @return {!Array<number>} | |
*/ | |
function rstr2binb(input: string) { | |
let output = Array(input.length >> 2) | |
for (let i = 0; i < output.length; i++) output[i] = 0 | |
for (let i = 0; i < input.length * 8; i += 8) | |
output[i >> 5] |= (input.charCodeAt(i / 8) & 0xff) << (24 - (i % 32)) | |
return output | |
} | |
/** | |
* Convert an array of big-endian words to a string | |
* @param {!Array<number>} input | |
* @return {string} | |
*/ | |
function binb2rstr(input: Array<number>) { | |
let output = "" | |
for (let i = 0; i < input.length * 32; i += 8) { | |
let out = input[i >> 5] | |
if (out === undefined) throw new Error("Out of range index") | |
output += String.fromCharCode((out >>> (24 - (i % 32))) & 0xff) | |
} | |
return output | |
} | |
/** | |
* Calculate the SHA-1 of an array of big-endian words, and a bit length | |
* @param {!Array<number>} x | |
* @param {number} len | |
* @return {!Array<number>} | |
*/ | |
function binb_sha1(x: Array<number>, len: number) { | |
/* append padding */ | |
x[len >> 5] |= 0x80 << (24 - (len % 32)) | |
x[(((len + 64) >> 9) << 4) + 15] = len | |
let w = Array(80) | |
let a = 1732584193 | |
let b = -271733879 | |
let c = -1732584194 | |
let d = 271733878 | |
let e = -1009589776 | |
for (let i = 0; i < x.length; i += 16) { | |
let olda = a | |
let oldb = b | |
let oldc = c | |
let oldd = d | |
let olde = e | |
for (let j = 0; j < 80; j++) { | |
if (j < 16) w[j] = x[i + j] | |
else w[j] = bit_rol(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1) | |
let t = safe_add( | |
safe_add(bit_rol(a, 5), sha1_ft(j, b, c, d)), | |
safe_add(safe_add(e, w[j]), sha1_kt(j)), | |
) | |
e = d | |
d = c | |
c = bit_rol(b, 30) | |
b = a | |
a = t | |
} | |
a = safe_add(a, olda) | |
b = safe_add(b, oldb) | |
c = safe_add(c, oldc) | |
d = safe_add(d, oldd) | |
e = safe_add(e, olde) | |
} | |
return Array(a, b, c, d, e) | |
} | |
/** | |
* Perform the appropriate triplet combination function for the current | |
* iteration | |
* @param {number} t | |
* @param {number} b | |
* @param {number} c | |
* @param {number} d | |
* @return {number} | |
*/ | |
function sha1_ft(t: number, b: number, c: number, d: number) { | |
if (t < 20) return (b & c) | (~b & d) | |
if (t < 40) return b ^ c ^ d | |
if (t < 60) return (b & c) | (b & d) | (c & d) | |
return b ^ c ^ d | |
} | |
/** | |
* Determine the appropriate additive constant for the current iteration | |
* @param {number} t | |
* @return {number} | |
*/ | |
function sha1_kt(t: number) { | |
return t < 20 ? 1518500249 : t < 40 ? 1859775393 : t < 60 ? -1894007588 : -899497514 | |
} | |
/** | |
* Add integers, wrapping at 2^32. This uses 16-bit operations internally | |
* to work around bugs in some JS interpreters. | |
* @param {number} x | |
* @param {number} y | |
* @return {number} | |
*/ | |
function safe_add(x: number, y: number) { | |
let lsw = (x & 0xffff) + (y & 0xffff) | |
let msw = (x >> 16) + (y >> 16) + (lsw >> 16) | |
return (msw << 16) | (lsw & 0xffff) | |
} | |
/** | |
* Bitwise rotate a 32-bit number to the left. | |
* @param {number} num | |
* @param {number} cnt | |
* @return {number} | |
*/ | |
function bit_rol(num: number, cnt: number) { | |
return (num << cnt) | (num >>> (32 - cnt)) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment