init
This commit is contained in:
132
jdenticon-js/src/common/sha1.js
Normal file
132
jdenticon-js/src/common/sha1.js
Normal file
@@ -0,0 +1,132 @@
|
||||
/**
|
||||
* Jdenticon
|
||||
* https://github.com/dmester/jdenticon
|
||||
* Copyright © Daniel Mester Pirttijärvi
|
||||
*/
|
||||
|
||||
/**
|
||||
* Computes a SHA1 hash for any value and returns it as a hexadecimal string.
|
||||
*
|
||||
* This function is optimized for minimal code size and rather short messages.
|
||||
*
|
||||
* @param {string} message
|
||||
*/
|
||||
export function sha1(message) {
|
||||
const HASH_SIZE_HALF_BYTES = 40;
|
||||
const BLOCK_SIZE_WORDS = 16;
|
||||
|
||||
// Variables
|
||||
// `var` is used to be able to minimize the number of `var` keywords.
|
||||
var i = 0,
|
||||
f = 0,
|
||||
|
||||
// Use `encodeURI` to UTF8 encode the message without any additional libraries
|
||||
// We could use `unescape` + `encodeURI` to minimize the code, but that would be slightly risky
|
||||
// since `unescape` is deprecated.
|
||||
urlEncodedMessage = encodeURI(message) + "%80", // trailing '1' bit padding
|
||||
|
||||
// This can be changed to a preallocated Uint32Array array for greater performance and larger code size
|
||||
data = [],
|
||||
dataSize,
|
||||
|
||||
hashBuffer = [],
|
||||
|
||||
a = 0x67452301,
|
||||
b = 0xefcdab89,
|
||||
c = ~a,
|
||||
d = ~b,
|
||||
e = 0xc3d2e1f0,
|
||||
hash = [a, b, c, d, e],
|
||||
|
||||
blockStartIndex = 0,
|
||||
hexHash = "";
|
||||
|
||||
/**
|
||||
* Rotates the value a specified number of bits to the left.
|
||||
* @param {number} value Value to rotate
|
||||
* @param {number} shift Bit count to shift.
|
||||
*/
|
||||
function rotl(value, shift) {
|
||||
return (value << shift) | (value >>> (32 - shift));
|
||||
}
|
||||
|
||||
// Message data
|
||||
for ( ; i < urlEncodedMessage.length; f++) {
|
||||
data[f >> 2] = data[f >> 2] |
|
||||
(
|
||||
(
|
||||
urlEncodedMessage[i] == "%"
|
||||
// Percent encoded byte
|
||||
? parseInt(urlEncodedMessage.substring(i + 1, i += 3), 16)
|
||||
// Unencoded byte
|
||||
: urlEncodedMessage.charCodeAt(i++)
|
||||
)
|
||||
|
||||
// Read bytes in reverse order (big endian words)
|
||||
<< ((3 - (f & 3)) * 8)
|
||||
);
|
||||
}
|
||||
|
||||
// f is now the length of the utf8 encoded message
|
||||
// 7 = 8 bytes (64 bit) for message size, -1 to round down
|
||||
// >> 6 = integer division with block size
|
||||
dataSize = (((f + 7) >> 6) + 1) * BLOCK_SIZE_WORDS;
|
||||
|
||||
// Message size in bits.
|
||||
// SHA1 uses a 64 bit integer to represent the size, but since we only support short messages only the least
|
||||
// significant 32 bits are set. -8 is for the '1' bit padding byte.
|
||||
data[dataSize - 1] = f * 8 - 8;
|
||||
|
||||
// Compute hash
|
||||
for ( ; blockStartIndex < dataSize; blockStartIndex += BLOCK_SIZE_WORDS) {
|
||||
for (i = 0; i < 80; i++) {
|
||||
f = rotl(a, 5) + e + (
|
||||
// Ch
|
||||
i < 20 ? ((b & c) ^ ((~b) & d)) + 0x5a827999 :
|
||||
|
||||
// Parity
|
||||
i < 40 ? (b ^ c ^ d) + 0x6ed9eba1 :
|
||||
|
||||
// Maj
|
||||
i < 60 ? ((b & c) ^ (b & d) ^ (c & d)) + 0x8f1bbcdc :
|
||||
|
||||
// Parity
|
||||
(b ^ c ^ d) + 0xca62c1d6
|
||||
) + (
|
||||
hashBuffer[i] = i < BLOCK_SIZE_WORDS
|
||||
// Bitwise OR is used to coerse `undefined` to 0
|
||||
? (data[blockStartIndex + i] | 0)
|
||||
: rotl(hashBuffer[i - 3] ^ hashBuffer[i - 8] ^ hashBuffer[i - 14] ^ hashBuffer[i - 16], 1)
|
||||
);
|
||||
|
||||
e = d;
|
||||
d = c;
|
||||
c = rotl(b, 30);
|
||||
b = a;
|
||||
a = f;
|
||||
}
|
||||
|
||||
hash[0] = a = ((hash[0] + a) | 0);
|
||||
hash[1] = b = ((hash[1] + b) | 0);
|
||||
hash[2] = c = ((hash[2] + c) | 0);
|
||||
hash[3] = d = ((hash[3] + d) | 0);
|
||||
hash[4] = e = ((hash[4] + e) | 0);
|
||||
}
|
||||
|
||||
// Format hex hash
|
||||
for (i = 0; i < HASH_SIZE_HALF_BYTES; i++) {
|
||||
hexHash += (
|
||||
(
|
||||
// Get word (2^3 half-bytes per word)
|
||||
hash[i >> 3] >>>
|
||||
|
||||
// Append half-bytes in reverse order
|
||||
((7 - (i & 7)) * 4)
|
||||
)
|
||||
// Clamp to half-byte
|
||||
& 0xf
|
||||
).toString(16);
|
||||
}
|
||||
|
||||
return hexHash;
|
||||
}
|
||||
Reference in New Issue
Block a user