Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@yannickcr
Created November 23, 2010 23:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yannickcr/712736 to your computer and use it in GitHub Desktop.
Save yannickcr/712736 to your computer and use it in GitHub Desktop.
Hash a string with the SHA-1 algorithm (using MooTools)
/*
---
script: String.SHA1.js
description: Hash a string with the SHA-1 algorithm
license: MIT-style license.
authors: Yannick Croissant
inspiration:
- [SHA-1 pseudocode](http://en.wikipedia.org/wiki/SHA-1#SHA-1_pseudocode)
requires:
core/1.3: '*'
more/1.3.1: [String.Extras]
provides: [String.SHA1]
...
*/
String.implement({
SHA1:function(){
// Initialize variables
var h0 = 1732584193,
h1 = 4023233417,
h2 = 2562383102,
h3 = 271733878,
h4 = 3285377520,
p = '',
s = this.length,
// A little function to convert a number into hexadecimal
hex = function(num){
for(var a = 7, b=''; a >= 0; a--) b += ((num >>> (a * 4)) & 15).toString(16);
return b;
};
// Convert the string into binary
for (var i = 0; i < s ; i++) p += ('0000000' + this.charCodeAt(i).toString(2)).substr(-8);
p += 1; // Append the bit '1' to the message
// Append 0 <= k < 512 bits '0', so that the resulting message length (in bits) is congruent to 448 = -64 (mod 512)
var k = (p.length - 448) % 512;
p += '0'.repeat(k < 0 ? -1 * k : 512 - k);
// Append length of message (before pre-processing), in bits, as 64-bit big-endian integer
p += ('0'.repeat(63) + parseInt(s * 8, 10).toString(2)).substr(-64);
var v = [],
m,
t = p.length / 512;
// Break message into 512-bit chunks
for (i = k = 0; m = p.substr(i, 512); i = i + 512) v[k++] = m;
for (var o = 0; o < t; o++){
var w = [],
j;
// Break chunk into sixteen 32-bit big-endian words w[i], 0 = i = 15
for (i = k = 0; j = v[o].substr(k, 32); k += 32) w[i++] = parseInt(parseInt(j, 2), 10);
// Extend the sixteen 32-bit words into eighty 32-bit words
for (i = 16; i < 80; i++){
w[i] = w[i - 3]^w[i - 8]^w[i - 14]^w[i - 16];
w[i] = (w[i] << 1) | (w[i] >>> (32 - 1))
}
// Initialize hash value for this chunk
var a = h0,
b = h1,
c = h2,
d = h3,
e = h4,
f,
k,
temp;
// Main loop
for (i = 0; i < 80; i++){
if (i >= 0 && i <= 19){
f = (b & c) | (~b & d);
k = 1518500249;
} else if (i >= 20 && i <= 39){
f = b^c^d;
k = 1859775393;
} else if (i>= 40 && i <= 59){
f = (b & c) | (b & d) | (c & d);
k = 2400959708;
} else if (i >= 60 && i <= 79){
f = b^c^d;
k = 3395469782;
}
temp = ((a << 5) | (a >>> (32 - 5))) + f + e + k + w[i];
e = d;
d = c;
c = (b << 30) | (b >>> (32 - 30));
b = a;
a = temp;
}
// Add this chunk's hash to result so far
h0 = h0 + a;
h1 = h1 + b;
h2 = h2 + c;
h3 = h3 + d;
h4 = h4 + e;
}
// Produce the final hash value (big-endian)
return hex(h0) + hex(h1) + hex(h2) + hex(h3) + hex(h4);
}
});
@yannickcr
Copy link
Author

Yep, mine is just an old code I wrote one year ago that I updated/cleaned/commented recently for the latest Mootools version.

But, yeah, his code does exactly the same job as mine ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment