1 var Sha1
= {}; // SHA-1 namespace
3 // SHA-1 algorithm as described at http://en.wikipedia.org/wiki/SHA-1
4 // The implementation follows http://fr.wikipedia.org/wiki/Sp%C3%A9cifications_SHA-1 (in french).
5 // SHA-1 implementation of Chris Veness 2002-2010 [www.movable-type.co.uk] helped a lot for debugging,
6 // and for hacks like toHexStr(). See his script at http://www.movable-type.co.uk/scripts/sha1.html
7 Sha1
.Compute = function(subject
)
9 var i
, j
, tmp
, redIndex
, a
, b
, c
, d
, e
;
13 // note: no check on message length, since the 2^64 boundary is
14 // a lot longer than what would be allowed by HTML/PHP
16 // add trailing '1' bit (+ 0's padding) to string
17 subject
+= String
.fromCharCode(0x80);
19 // add 8 for two last reserved words to store message length
20 // 8 = 2 x 4, one 32-bits word is 4 characters (bytes) length.
21 var L
= subject
.length
+ 8;
23 // initialize 512-bits blocks representing the message, each containing 16 32-bits words.
24 // NOTE: one char is 8 bits, so one block in the initial string is 64 chars.
25 var countBlocks
= Math
.ceil(L
/ 64);
26 var blocks
= new Array(countBlocks
);
27 for (i
=0; i
<countBlocks
; i
++)
29 var words
= new Array(16);
32 tmp
= subject
.substr(64 * i
+ 4 * j
, 4);
33 // note: running off the end of msg is ok because bitwise ops on NaN return 0
34 words
[j
] = (1 << 24) * tmp
.charCodeAt(0) | (1 << 16) * tmp
.charCodeAt(1) | (1 << 8) * tmp
.charCodeAt(2) | tmp
.charCodeAt(3);
39 // note: 'subject' in our context will never be of length >= 2^32.
40 // therefore we don't need to fill before-last block.
41 blocks
[countBlocks
-1][15] = (subject
.length
-1) * 8;
43 // initialize parts of the final hash
50 // initialize constants array
51 var k
= [0x5a827999,0x6ed9eba1,0x8f1bbcdc,0xca62c1d6];
55 for (i
=0; i
<blocks
.length
; i
++)
58 var w
= new Array(80);
59 for (j
=0; j
<16; j
++) w
[j
] = blocks
[i
][j
];
61 w
[j
] = Sha1
.LeftRotate(w
[j
-3] ^ w
[j
-8] ^ w
[j
-14] ^ w
[j
-16], 1);
63 // initialize a,b,c,d,e variables
70 // iterations over a,b,c,d,e
73 // note: '& 0xffffffff' == 'modulo 2^32'.
74 redIndex
= Math
.floor(j
/20);
75 tmp
= (Sha1
.LeftRotate(a
, 5) + Sha1
.BitOp(b
, c
, d
, redIndex
) + e
+ k
[redIndex
] + w
[j
]) & 0xffffffff;
78 c
= Sha1
.LeftRotate(b
, 30);
83 // update intermediate hash values
84 h0
= (h0
+a
) & 0xffffffff;
85 h1
= (h1
+b
) & 0xffffffff;
86 h2
= (h2
+c
) & 0xffffffff;
87 h3
= (h3
+d
) & 0xffffffff;
88 h4
= (h4
+e
) & 0xffffffff;
91 return Sha1
.ToHexStr(h0
)+Sha1
.ToHexStr(h1
)+Sha1
.ToHexStr(h2
)+Sha1
.ToHexStr(h3
)+Sha1
.ToHexStr(h4
);
94 // auxiliary functions.
95 Sha1
.BitOp = function(x
, y
, z
, t
)
97 if (t
== 0) return (x
& y
) ^ (~x
& z
);
98 if (t
== 1) return x
^ y
^ z
;
99 if (t
== 2) return (x
& y
) ^ (x
& z
) ^ (y
& z
);
100 if (t
== 3) return x
^ y
^ z
;
103 // left rotation (within 32 bits).
104 Sha1
.LeftRotate = function(x
, n
)
106 return (x
<< n
) | (x
>>> (32 - n
));
109 // [copy-pasted from Chris Veness implementation]
110 // Hexadecimal representation of a number
111 // (note toString(16) is implementation-dependant, and
112 // in IE returns signed numbers when used on full words)
113 Sha1
.ToHexStr = function(x
)
116 for (var i
=7; i
>=0; i
--)
118 var v
= (x
>>> (i
*4)) & 0xf;
124 try { module
.exports
= Sha1
; } catch (err
) {}