tiny-sha1
Version:
Tiny SHA-1 hasher for Node and browsers
155 lines (126 loc) • 3.82 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define('tiny-sha1', factory) :
(global.sha1 = factory());
}(this, function () { 'use strict';
var systemLittleEndian = new Uint16Array(new Uint8Array([0x7F, 0xFF]).buffer)[0] === 0xFF7F;
function swap4(num) {
return num >> 24 & 0xff | num >> 8 & 0xff00 | num << 8 & 0xff0000 | num << 24 & 0xff000000;
}
function align(address, alignment) {
var tmp = alignment - 1;
return address + tmp & ~tmp;
}
/** Convert a uint32 to an 8-character big-endian hex string. */
function hexify(n) {
var s = '';
var i = 8;
while (i--) {
s += (n >>> (i << 2) & 0xf).toString(16);
}
return s;
}
function choice(x, y, z) {
return x & y ^ ~x & z;
}
function parity(x, y, z) {
return x ^ y ^ z;
}
function majority(x, y, z) {
return x & y ^ x & z ^ y & z;
}
function rotateLeft(value, bits) {
return value << bits | value >>> 32 - bits;
}
var w = new Uint32Array(80);
function sha1(bytes) {
if (!(bytes instanceof Uint8Array)) {
throw new TypeError('Input data must be a Uint8Array.');
}
// Allocate a buffer to fit the message data,
// the padding byte and the 64-bit message bit length
var buffer = new ArrayBuffer(align(bytes.byteLength + 9, 64));
var data = new Uint32Array(buffer);
// Copy the message data and set the padding byte
var dataU8 = new Uint8Array(buffer);
dataU8.set(bytes);
dataU8[bytes.byteLength] = 0x80;
// Swap bytes if neeeded
if (systemLittleEndian) {
for (var _i = 0, len = data.length; _i < len; ++_i) {
data[_i] = swap4(data[_i]);
}
}
var bitLength = 8 * bytes.byteLength;
// Store the message bit length as a 64-bit value
data[data.length - 2] = bitLength / Math.pow(2, 32);
data[data.length - 1] = bitLength;
// Set the initial hash state
var h0 = 0x67452301;
var h1 = 0xefcdab89;
var h2 = 0x98badcfe;
var h3 = 0x10325476;
var h4 = 0xc3d2e1f0;
/* eslint-disable one-var, one-var-declaration-per-line */
var i = void 0,
a = void 0,
b = void 0,
c = void 0,
d = void 0,
e = void 0,
tmp = void 0;
for (var offset = 0, _len = data.length; offset < _len; offset += 16) {
for (i = 0; i < 16; ++i) {
w[i] = data[offset + i];
}
for (i = 16; i < 80; ++i) {
w[i] = rotateLeft(w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16], 1);
}
a = h0;
b = h1;
c = h2;
d = h3;
e = h4;
for (i = 0; i < 20; ++i) {
tmp = rotateLeft(a, 5) + choice(b, c, d) + e + 0x5a827999 + w[i] | 0;
e = d;
d = c;
c = rotateLeft(b, 30);
b = a;
a = tmp;
}
for (i = 20; i < 40; ++i) {
tmp = rotateLeft(a, 5) + parity(b, c, d) + e + 0x6ed9eba1 + w[i] | 0;
e = d;
d = c;
c = rotateLeft(b, 30);
b = a;
a = tmp;
}
for (i = 40; i < 60; ++i) {
tmp = rotateLeft(a, 5) + majority(b, c, d) + e + 0x8f1bbcdc + w[i] | 0;
e = d;
d = c;
c = rotateLeft(b, 30);
b = a;
a = tmp;
}
for (i = 60; i < 80; ++i) {
tmp = rotateLeft(a, 5) + parity(b, c, d) + e + 0xca62c1d6 + w[i] | 0;
e = d;
d = c;
c = rotateLeft(b, 30);
b = a;
a = tmp;
}
h0 = h0 + a | 0;
h1 = h1 + b | 0;
h2 = h2 + c | 0;
h3 = h3 + d | 0;
h4 = h4 + e | 0;
}
return '' + hexify(h0) + hexify(h1) + hexify(h2) + hexify(h3) + hexify(h4);
}
return sha1;
}));
//# sourceMappingURL=tiny-sha1.js.map