一:UTF8编码函数
function
URLEncode(Str){
if
(Str
==
null
||
Str
==
""
)
return
""
;
var
newStr
=
""
;
function
toCase(sStr){
return
sStr.toString(
16
).toUpperCase();
}
for
(
var
i
=
0
,icode,len
=
Str.length;i
<
len;i
++
){
icode
=
Str.charCodeAt(i);
if
( icode
<
0x10
)
newStr
+=
"
%0
"
+
icode.toString(
16
).toUpperCase();
else
if
(icode
<
0x80
){
if
(icode
==
0x20
)
newStr
+=
"
+
"
;
else
if
((icode
>=
0x30
&&
icode
<=
0x39
)
||
(icode
>=
0x41
&&
icode
<=
0x5A
)
||
(icode
>=
0x61
&&
icode
<=
0x7A
))
newStr
+=
Str.charAt(i);
else
newStr
+=
"
%
"
+
toCase(icode);
}
else
if
(icode
<
0x800
){
newStr
+=
"
%
"
+
toCase(
0xC0
+
(icode
>>
6
));
newStr
+=
"
%
"
+
toCase(
0x80
+
icode
%
0x40
);
}
else
{
newStr
+=
"
%
"
+
toCase(
0xE0
+
(icode
>>
12
));
newStr
+=
"
%
"
+
toCase(
0x80
+
(icode
>>
6
)
%
0x40
);
newStr
+=
"
%
"
+
toCase(
0x80
+
icode
%
0x40
);
}
}
return
newStr;
}
二:Base64编码,解码函数
var
base64EncodeChars
=
"
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
"
;
var
base64DecodeChars
=
new
Array(
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
62
,
-
1
,
-
1
,
-
1
,
63
,
52
,
53
,
54
,
55
,
56
,
57
,
58
,
59
,
60
,
61
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
0
,
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
,
10
,
11
,
12
,
13
,
14
,
15
,
16
,
17
,
18
,
19
,
20
,
21
,
22
,
23
,
24
,
25
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
26
,
27
,
28
,
29
,
30
,
31
,
32
,
33
,
34
,
35
,
36
,
37
,
38
,
39
,
40
,
41
,
42
,
43
,
44
,
45
,
46
,
47
,
48
,
49
,
50
,
51
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
);
function
base64encode(str) {
var
out, i, len;
var
c1, c2, c3;
len
=
str.length;
i
=
0
;
out
=
""
;
while
(i
<
len) {
c1
=
str.charCodeAt(i
++
)
&
0xff
;
if
(i
==
len)
{
out
+=
base64EncodeChars.charAt(c1
>>
2
);
out
+=
base64EncodeChars.charAt((c1
&
0x3
)
<<
4
);
out
+=
"
==
"
;
break
;
}
c2
=
str.charCodeAt(i
++
);
if
(i
==
len)
{
out
+=
base64EncodeChars.charAt(c1
>>
2
);
out
+=
base64EncodeChars.charAt(((c1
&
0x3
)
<<
4
)
|
((c2
&
0xF0
)
>>
4
));
out
+=
base64EncodeChars.charAt((c2
&
0xF
)
<<
2
);
out
+=
"
=
"
;
break
;
}
c3
=
str.charCodeAt(i
++
);
out
+=
base64EncodeChars.charAt(c1
>>
2
);
out
+=
base64EncodeChars.charAt(((c1
&
0x3
)
<<
4
)
|
((c2
&
0xF0
)
>>
4
));
out
+=
base64EncodeChars.charAt(((c2
&
0xF
)
<<
2
)
|
((c3
&
0xC0
)
>>
6
));
out
+=
base64EncodeChars.charAt(c3
&
0x3F
);
}
return
out;
}
function
base64decode(str) {
var
c1, c2, c3, c4;
var
i, len, out;
len
=
str.length;
i
=
0
;
out
=
""
;
while
(i
<
len) {
/*
c1
*/
do
{
c1
=
base64DecodeChars[str.charCodeAt(i
++
)
&
0xff
];
}
while
(i
<
len
&&
c1
==
-
1
);
if
(c1
==
-
1
)
break
;
/*
c2
*/
do
{
c2
=
base64DecodeChars[str.charCodeAt(i
++
)
&
0xff
];
}
while
(i
<
len
&&
c2
==
-
1
);
if
(c2
==
-
1
)
break
;
out
+=
String.fromCharCode((c1
<<
2
)
|
((c2
&
0x30
)
>>
4
));
/*
c3
*/
do
{
c3
=
str.charCodeAt(i
++
)
&
0xff
;
if
(c3
==
61
)
return
out;
c3
=
base64DecodeChars[c3];
}
while
(i
<
len
&&
c3
==
-
1
);
if
(c3
==
-
1
)
break
;
out
+=
String.fromCharCode(((c2
&
0XF
)
<<
4
)
|
((c3
&
0x3C
)
>>
2
));
/*
c4
*/
do
{
c4
=
str.charCodeAt(i
++
)
&
0xff
;
if
(c4
==
61
)
return
out;
c4
=
base64DecodeChars[c4];
}
while
(i
<
len
&&
c4
==
-
1
);
if
(c4
==
-
1
)
break
;
out
+=
String.fromCharCode(((c3
&
0x03
)
<<
6
)
|
c4);
}
return
out;
}
function
utf16to8(str) {
var
out, i, len, c;
out
=
""
;
len
=
str.length;
for
(i
=
0
; i
<
len; i
++
) {
c
=
str.charCodeAt(i);
if
((c
>=
0x0001
)
&&
(c
<=
0x007F
)) {
out
+=
str.charAt(i);
}
else
if
(c
>
0x07FF
) {
out
+=
String.fromCharCode(
0xE0
|
((c
>>
12
)
&
0x0F
));
out
+=
String.fromCharCode(
0x80
|
((c
>>
6
)
&
0x3F
));
out
+=
String.fromCharCode(
0x80
|
((c
>>
0
)
&
0x3F
));
}
else
{
out
+=
String.fromCharCode(
0xC0
|
((c
>>
6
)
&
0x1F
));
out
+=
String.fromCharCode(
0x80
|
((c
>>
0
)
&
0x3F
));
}
}
return
out;
}
function
utf8to16(str) {
var
out, i, len, c;
var
char2, char3;
out
=
""
;
len
=
str.length;
i
=
0
;
while
(i
<
len) {
c
=
str.charCodeAt(i
++
);
switch
(c
>>
4
)
{
case
0
:
case
1
:
case
2
:
case
3
:
case
4
:
case
5
:
case
6
:
case
7
:
//
0xxxxxxx
out
+=
str.charAt(i
-
1
);
break
;
case
12
:
case
13
:
//
110x xxxx 10xx xxxx
char2
=
str.charCodeAt(i
++
);
out
+=
String.fromCharCode(((c
&
0x1F
)
<<
6
)
|
(char2
&
0x3F
));
break
;
case
14
:
//
1110 xxxx 10xx xxxx 10xx xxxx
char2
=
str.charCodeAt(i
++
);
char3
=
str.charCodeAt(i
++
);
out
+=
String.fromCharCode(((c
&
0x0F
)
<<
12
)
|
((char2
&
0x3F
)
<<
6
)
|
((char3
&
0x3F
)
<<
0
));
break
;
}
}
return
out;
}
function
doit() {
var
f
=
document.f
f.output.value
=
base64encode(utf16to8(f.source.value))
f.decode.value
=
utf8to16(base64decode(f.output.value))
}
三:MD5
/*
* A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
* Digest Algorithm, as defined in RFC 1321.
* Version 2.1 Copyright (C) Paul Johnston 1999 - 2002.
* Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
* Distributed under the BSD License
* See http://pajhome.org.uk/crypt/md5 for more info.
*/
/*
* Configurable variables. You may need to tweak these to be compatible with
* the server-side, but the defaults work in most cases.
*/
var
hexcase
=
0
;
/*
hex output format. 0 - lowercase; 1 - uppercase
*/
var
b64pad
=
""
;
/*
base-64 pad character. "=" for strict RFC compliance
*/
var
chrsz
=
8
;
/*
bits per input character. 8 - ASCII; 16 - Unicode
*/
/*
* These are the functions you'll usually want to call
* They take string arguments and return either hex or base-64 encoded strings
*/
function
hex_md5(s){
return
binl2hex(core_md5(str2binl(s), s.length
*
chrsz));}
function
b64_md5(s){
return
binl2b64(core_md5(str2binl(s), s.length
*
chrsz));}
function
str_md5(s){
return
binl2str(core_md5(str2binl(s), s.length
*
chrsz));}
function
hex_hmac_md5(key, data) {
return
binl2hex(core_hmac_md5(key, data)); }
function
b64_hmac_md5(key, data) {
return
binl2b64(core_hmac_md5(key, data)); }
function
str_hmac_md5(key, data) {
return
binl2str(core_hmac_md5(key, data)); }
/*
* Perform a simple self-test to see if the VM is working
*/
function
md5_vm_test()
{
return
hex_md5(
"
abc
"
)
==
"
900150983cd24fb0d6963f7d28e17f72
"
;
}
/*
* Calculate the MD5 of an array of little-endian words, and a bit length
*/
function
core_md5(x, len)
{
/*
append padding
*/
x[len
>>
5
]
|=
0x80
<<
((len)
%
32
);
x[(((len
+
64
)
>>>
9
)
<<
4
)
+
14
]
=
len;
var
a
=
1732584193
;
var
b
=
-
271733879
;
var
c
=
-
1732584194
;
var
d
=
271733878
;
for
(
var
i
=
0
; i
<
x.length; i
+=
16
)
{
var
olda
=
a;
var
oldb
=
b;
var
oldc
=
c;
var
oldd
=
d;
a
=
md5_ff(a, b, c, d, x[i
+
0
],
7
,
-
680876936
);
d
=
md5_ff(d, a, b, c, x[i
+
1
],
12
,
-
389564586
);
c
=
md5_ff(c, d, a, b, x[i
+
2
],
17
,
606105819
);
b
=
md5_ff(b, c, d, a, x[i
+
3
],
22
,
-
1044525330
);
a
=
md5_ff(a, b, c, d, x[i
+
4
],
7
,
-
176418897
);
d
=
md5_ff(d, a, b, c, x[i
+
5
],
12
,
1200080426
);
c
=
md5_ff(c, d, a, b, x[i
+
6
],
17
,
-
1473231341
);
b
=
md5_ff(b, c, d, a, x[i
+
7
],
22
,
-
45705983
);
a
=
md5_ff(a, b, c, d, x[i
+
8
],
7
,
1770035416
);
d
=
md5_ff(d, a, b, c, x[i
+
9
],
12
,
-
1958414417
);
c
=
md5_ff(c, d, a, b, x[i
+
10
],
17
,
-
42063
);
b
=
md5_ff(b, c, d, a, x[i
+
11
],
22
,
-
1990404162
);
a
=
md5_ff(a, b, c, d, x[i
+
12
],
7
,
1804603682
);
d
=
md5_ff(d, a, b, c, x[i
+
13
],
12
,
-
40341101
);
c
=
md5_ff(c, d, a, b, x[i
+
14
],
17
,
-
1502002290
);
b
=
md5_ff(b, c, d, a, x[i
+
15
],
22
,
1236535329
);
a
=
md5_gg(a, b, c, d, x[i
+
1
],
5
,
-
165796510
);
d
=
md5_gg(d, a, b, c, x[i
+
6
],
9
,
-
1069501632
);
c
=
md5_gg(c, d, a, b, x[i
+
11
],
14
,
643717713
);
b
=
md5_gg(b, c, d, a, x[i
+
0
],
20
,
-
373897302
);
a
=
md5_gg(a, b, c, d, x[i
+
5
],
5
,
-
701558691
);
d
=
md5_gg(d, a, b, c, x[i
+
10
],
9
,
38016083
);
c
=
md5_gg(c, d, a, b, x[i
+
15
],
14
,
-
660478335
);
b
=
md5_gg(b, c, d, a, x[i
+
4
],
20
,
-
405537848
);
a
=
md5_gg(a, b, c, d, x[i
+
9
],
5
,
568446438
);
d
=
md5_gg(d, a, b, c, x[i
+
14
],
9
,
-
1019803690
);
c
=
md5_gg(c, d, a, b, x[i
+
3
],
14
,
-
187363961
);
b
=
md5_gg(b, c, d, a, x[i
+
8
],
20
,
1163531501
);
a
=
md5_gg(a, b, c, d, x[i
+
13
],
5
,
-
1444681467
);
d
=
md5_gg(d, a, b, c, x[i
+
2
],
9
,
-
51403784
);
c
=
md5_gg(c, d, a, b, x[i
+
7
],
14
,
1735328473
);
b
=
md5_gg(b, c, d, a, x[i
+
12
],
20
,
-
1926607734
);
a
=
md5_hh(a, b, c, d, x[i
+
5
],
4
,
-
378558
);
d
=
md5_hh(d, a, b, c, x[i
+
8
],
11
,
-
2022574463
);
c
=
md5_hh(c, d, a, b, x[i
+
11
],
16
,
1839030562
);
b
=
md5_hh(b, c, d, a, x[i
+
14
],
23
,
-
35309556
);
a
=
md5_hh(a, b, c, d, x[i
+
1
],
4
,
-
1530992060
);
d
=
md5_hh(d, a, b, c, x[i
+
4
],
11
,
1272893353
);
c
=
md5_hh(c, d, a, b, x[i
+
7
],
16
,
-
155497632
);
b
=
md5_hh(b, c, d, a, x[i
+
10
],
23
,
-
1094730640
);
a
=
md5_hh(a, b, c, d, x[i
+
13
],
4
,
681279174
);
d
=
md5_hh(d, a, b, c, x[i
+
0
],
11
,
-
358537222
);
c
=
md5_hh(c, d, a, b, x[i
+
3
],
16
,
-
722521979
);
b
=
md5_hh(b, c, d, a, x[i
+
6
],
23
,
76029189
);
a
=
md5_hh(a, b, c, d, x[i
+
9
],
4
,
-
640364487
);
d
=
md5_hh(d, a, b, c, x[i
+
12
],
11
,
-
421815835
);
c
=
md5_hh(c, d, a, b, x[i
+
15
],
16
,
530742520
);
b
=
md5_hh(b, c, d, a, x[i
+
2
],
23
,
-
995338651
);
a
=
md5_ii(a, b, c, d, x[i
+
0
],
6
,
-
198630844
);
d
=
md5_ii(d, a, b, c, x[i
+
7
],
10
,
1126891415
);
c
=
md5_ii(c, d, a, b, x[i
+
14
],
15
,
-
1416354905
);
b
=
md5_ii(b, c, d, a, x[i
+
5
],
21
,
-
57434055
);
a
=
md5_ii(a, b, c, d, x[i
+
12
],
6
,
1700485571
);
d
=
md5_ii(d, a, b, c, x[i
+
3
],
10
,
-
1894986606
);
c
=
md5_ii(c, d, a, b, x[i
+
10
],
15
,
-
1051523
);
b
=
md5_ii(b, c, d, a, x[i
+
1
],
21
,
-
2054922799
);
a
=
md5_ii(a, b, c, d, x[i
+
8
],
6
,
1873313359
);
d
=
md5_ii(d, a, b, c, x[i
+
15
],
10
,
-
30611744
);
c
=
md5_ii(c, d, a, b, x[i
+
6
],
15
,
-
1560198380
);
b
=
md5_ii(b, c, d, a, x[i
+
13
],
21
,
1309151649
);
a
=
md5_ii(a, b, c, d, x[i
+
4
],
6
,
-
145523070
);
d
=
md5_ii(d, a, b, c, x[i
+
11
],
10
,
-
1120210379
);
c
=
md5_ii(c, d, a, b, x[i
+
2
],
15
,
718787259
);
b
=
md5_ii(b, c, d, a, x[i
+
9
],
21
,
-
343485551
);
a
=
safe_add(a, olda);
b
=
safe_add(b, oldb);
c
=
safe_add(c, oldc);
d
=
safe_add(d, oldd);
}
return
Array(a, b, c, d);
}
/*
* These functions implement the four basic operations the algorithm uses.
*/
function
md5_cmn(q, a, b, x, s, t)
{
return
safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b);
}
function
md5_ff(a, b, c, d, x, s, t)
{
return
md5_cmn((b
&
c)
|
((
~
b)
&
d), a, b, x, s, t);
}
function
md5_gg(a, b, c, d, x, s, t)
{
return
md5_cmn((b
&
d)
|
(c
&
(
~
d)), a, b, x, s, t);
}
function
md5_hh(a, b, c, d, x, s, t)
{
return
md5_cmn(b
^
c
^
d, a, b, x, s, t);
}
function
md5_ii(a, b, c, d, x, s, t)
{
return
md5_cmn(c
^
(b
|
(
~
d)), a, b, x, s, t);
}
/*
* Calculate the HMAC-MD5, of a key and some data
*/
function
core_hmac_md5(key, data)
{
var
bkey
=
str2binl(key);
if
(bkey.length
>
16
) bkey
=
core_md5(bkey, key.length
*
chrsz);
var
ipad
=
Array(
16
), opad
=
Array(
16
);
for
(
var
i
=
0
; i
<
16
; i
++
)
{
ipad[i]
=
bkey[i]
^
0x36363636
;
opad[i]
=
bkey[i]
^
0x5C5C5C5C
;
}
var
hash
=
core_md5(ipad.concat(str2binl(data)),
512
+
data.length
*
chrsz);
return
core_md5(opad.concat(hash),
512
+
128
);
}
/*
* Add integers, wrapping at 2^32. This uses 16-bit operations internally
* to work around bugs in some JS interpreters.
*/
function
safe_add(x, y)
{
var
lsw
=
(x
&
0xFFFF
)
+
(y
&
0xFFFF
);
var
msw
=
(x
>>
16
)
+
(y
>>
16
)
+
(lsw
>>
16
);
return
(msw
<<
16
)
|
(lsw
&
0xFFFF
);
}
/*
* Bitwise rotate a 32-bit number to the left.
*/
function
bit_rol(num, cnt)
{
return
(num
<<
cnt)
|
(num
>>>
(
32
-
cnt));
}
/*
* Convert a string to an array of little-endian words
* If chrsz is ASCII, characters >255 have their hi-byte silently ignored.
*/
function
str2binl(str)
{
var
bin
=
Array();
var
mask
=
(
1
<<
chrsz)
-
1
;
for
(
var
i
=
0
; i
<
str.length
*
chrsz; i
+=
chrsz)
bin[i
>>
5
]
|=
(str.charCodeAt(i
/
chrsz)
&
mask)
<<
(i
%
32
);
return
bin;
}
/*
* Convert an array of little-endian words to a string
*/
function
binl2str(bin)
{
var
str
=
""
;
var
mask
=
(
1
<<
chrsz)
-
1
;
for
(
var
i
=
0
; i
<
bin.length
*
32
; i
+=
chrsz)
str
+=
String.fromCharCode((bin[i
>>
5
]
>>>
(i
%
32
))
&
mask);
return
str;
}
/*
* Convert an array of little-endian words to a hex string.
*/
function
binl2hex(binarray)
{
var
hex_tab
=
hexcase
?
"
0123456789ABCDEF
"
:
"
0123456789abcdef
"
;
var
str
=
""
;
for
(
var
i
=
0
; i
<
binarray.length
*
4
; i
++
)
{
str
+=
hex_tab.charAt((binarray[i
>>
2
]
>>
((i
%
4
)
*
8
+
4
))
&
0xF
)
+
hex_tab.charAt((binarray[i
>>
2
]
>>
((i
%
4
)
*
8
))
&
0xF
);
}
return
str;
}
/*
* Convert an array of little-endian words to a base-64 string
*/
function
binl2b64(binarray)
{
var
tab
=
"
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
"
;
var
str
=
""
;
for
(
var
i
=
0
; i
<
binarray.length
*
4
; i
+=
3
)
{
var
triplet
=
(((binarray[i
>>
2
]
>>
8
*
( i
%
4
))
&
0xFF
)
<<
16
)
|
(((binarray[i
+
1
>>
2
]
>>
8
*
((i
+
1
)
%
4
))
&
0xFF
)
<<
8
)
|
((binarray[i
+
2
>>
2
]
>>
8
*
((i
+
2
)
%
4
))
&
0xFF
);
for
(
var
j
=
0
; j
<
4
; j
++
)
{
if
(i
*
8
+
j
*
6
>
binarray.length
*
32
) str
+=
b64pad;
else
str
+=
tab.charAt((triplet
>>
6
*
(
3
-
j))
&
0x3F
);
}
}
return
str;
}
MD4算法
/*
* A JavaScript implementation of the RSA Data Security, Inc. MD4 Message
* Digest Algorithm, as defined in RFC 1320.
* Version 2.1 Copyright (C) Jerrad Pierce, Paul Johnston 1999 - 2002.
* Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
* Distributed under the BSD License
* See http://pajhome.org.uk/crypt/md5 for more info.
*/
/*
* Configurable variables. You may need to tweak these to be compatible with
* the server-side, but the defaults work in most cases.
*/
var
hexcase
=
0
;
/*
hex output format. 0 - lowercase; 1 - uppercase
*/
var
b64pad
=
""
;
/*
base-64 pad character. "=" for strict RFC compliance
*/
var
chrsz
=
8
;
/*
bits per input character. 8 - ASCII; 16 - Unicode
*/
/*
* These are the functions you'll usually want to call
*/
function
hex_md4(s){
return
binl2hex(core_md4(str2binl(s), s.length
*
chrsz));}
function
b64_md4(s){
return
binl2b64(core_md4(str2binl(s), s.length
*
chrsz));}
function
str_md4(s){
return
binl2str(core_md4(str2binl(s), s.length
*
chrsz));}
function
hex_hmac_md4(key, data) {
return
binl2hex(core_hmac_md4(key, data)); }
function
b64_hmac_md4(key, data) {
return
binl2b64(core_hmac_md4(key, data)); }
function
str_hmac_md4(key, data) {
return
binl2str(core_hmac_md4(key, data)); }
/*
* Perform a simple self-test to see if the VM is working
*/
function
md4_vm_test()
{
return
hex_md4(
"
abc
"
)
==
"
a448017aaf21d8525fc10ae87aa6729d
"
;
}
/*
* Calculate the MD4 of an array of little-endian words, and a bit length
*/
function
core_md4(x, len)
{
/*
append padding
*/
x[len
>>
5
]
|=
0x80
<<
(len
%
32
);
x[(((len
+
64
)
>>>
9
)
<<
4
)
+
14
]
=
len;
var
a
=
1732584193
;
var
b
=
-
271733879
;
var
c
=
-
1732584194
;
var
d
=
271733878
;
for
(
var
i
=
0
; i
<
x.length; i
+=
16
)
{
var
olda
=
a;
var
oldb
=
b;
var
oldc
=
c;
var
oldd
=
d;
a
=
md4_ff(a, b, c, d, x[i
+
0
],
3
);
d
=
md4_ff(d, a, b, c, x[i
+
1
],
7
);
c
=
md4_ff(c, d, a, b, x[i
+
2
],
11
);
b
=
md4_ff(b, c, d, a, x[i
+
3
],
19
);
a
=
md4_ff(a, b, c, d, x[i
+
4
],
3
);
d
=
md4_ff(d, a, b, c, x[i
+
5
],
7
);
c
=
md4_ff(c, d, a, b, x[i
+
6
],
11
);
b
=
md4_ff(b, c, d, a, x[i
+
7
],
19
);
a
=
md4_ff(a, b, c, d, x[i
+
8
],
3
);
d
=
md4_ff(d, a, b, c, x[i
+
9
],
7
);
c
=
md4_ff(c, d, a, b, x[i
+
10
],
11
);
b
=
md4_ff(b, c, d, a, x[i
+
11
],
19
);
a
=
md4_ff(a, b, c, d, x[i
+
12
],
3
);
d
=
md4_ff(d, a, b, c, x[i
+
13
],
7
);
c
=
md4_ff(c, d, a, b, x[i
+
14
],
11
);
b
=
md4_ff(b, c, d, a, x[i
+
15
],
19
);
a
=
md4_gg(a, b, c, d, x[i
+
0
],
3
);
d
=
md4_gg(d, a, b, c, x[i
+
4
],
5
);
c
=
md4_gg(c, d, a, b, x[i
+
8
],
9
);
b
=
md4_gg(b, c, d, a, x[i
+
12
],
13
);
a
=
md4_gg(a, b, c, d, x[i
+
1
],
3
);
d
=
md4_gg(d, a, b, c, x[i
+
5
],
5
);
c
=
md4_gg(c, d, a, b, x[i
+
9
],
9
);
b
=
md4_gg(b, c, d, a, x[i
+
13
],
13
);
a
=
md4_gg(a, b, c, d, x[i
+
2
],
3
);
d
=
md4_gg(d, a, b, c, x[i
+
6
],
5
);
c
=
md4_gg(c, d, a, b, x[i
+
10
],
9
);
b
=
md4_gg(b, c, d, a, x[i
+
14
],
13
);
a
=
md4_gg(a, b, c, d, x[i
+
3
],
3
);
d
=
md4_gg(d, a, b, c, x[i
+
7
],
5
);
c
=
md4_gg(c, d, a, b, x[i
+
11
],
9
);
b
=
md4_gg(b, c, d, a, x[i
+
15
],
13
);
a
=
md4_hh(a, b, c, d, x[i
+
0
],
3
);
d
=
md4_hh(d, a, b, c, x[i
+
8
],
9
);
c
=
md4_hh(c, d, a, b, x[i
+
4
],
11
);
b
=
md4_hh(b, c, d, a, x[i
+
12
],
15
);
a
=
md4_hh(a, b, c, d, x[i
+
2
],
3
);
d
=
md4_hh(d, a, b, c, x[i
+
10
],
9
);
c
=
md4_hh(c, d, a, b, x[i
+
6
],
11
);
b
=
md4_hh(b, c, d, a, x[i
+
14
],
15
);
a
=
md4_hh(a, b, c, d, x[i
+
1
],
3
);
d
=
md4_hh(d, a, b, c, x[i
+
9
],
9
);
c
=
md4_hh(c, d, a, b, x[i
+
5
],
11
);
b
=
md4_hh(b, c, d, a, x[i
+
13
],
15
);
a
=
md4_hh(a, b, c, d, x[i
+
3
],
3
);
d
=
md4_hh(d, a, b, c, x[i
+
11
],
9
);
c
=
md4_hh(c, d, a, b, x[i
+
7
],
11
);
b
=
md4_hh(b, c, d, a, x[i
+
15
],
15
);
a
=
safe_add(a, olda);
b
=
safe_add(b, oldb);
c
=
safe_add(c, oldc);
d
=
safe_add(d, oldd);
}
return
Array(a, b, c, d);
}
/*
* These functions implement the basic operation for each round of the
* algorithm.
*/
function
md4_cmn(q, a, b, x, s, t)
{
return
safe_add(rol(safe_add(safe_add(a, q), safe_add(x, t)), s), b);
}
function
md4_ff(a, b, c, d, x, s)
{
return
md4_cmn((b
&
c)
|
((
~
b)
&
d), a,
0
, x, s,
0
);
}
function
md4_gg(a, b, c, d, x, s)
{
return
md4_cmn((b
&
c)
|
(b
&
d)
|
(c
&
d), a,
0
, x, s,
1518500249
);
}
function
md4_hh(a, b, c, d, x, s)
{
return
md4_cmn(b
^
c
^
d, a,
0
, x, s,
1859775393
);
}
/*
* Calculate the HMAC-MD4, of a key and some data
*/
function
core_hmac_md4(key, data)
{
var
bkey
=
str2binl(key);
if
(bkey.length
>
16
) bkey
=
core_md4(bkey, key.length
*
chrsz);
var
ipad
=
Array(
16
), opad
=
Array(
16
);
for
(
var
i
=
0
; i
<
16
; i
++
)
{
ipad[i]
=
bkey[i]
^
0x36363636
;
opad[i]
=
bkey[i]
^
0x5C5C5C5C
;
}
var
hash
=
core_md4(ipad.concat(str2binl(data)),
512
+
data.length
*
chrsz);
return
core_md4(opad.concat(hash),
512
+
128
);
}
/*
* Add integers, wrapping at 2^32. This uses 16-bit operations internally
* to work around bugs in some JS interpreters.
*/
function
safe_add(x, y)
{
var
lsw
=
(x
&
0xFFFF
)
+
(y
&
0xFFFF
);
var
msw
=
(x
>>
16
)
+
(y
>>
16
)
+
(lsw
>>
16
);
return
(msw
<<
16
)
|
(lsw
&
0xFFFF
);
}
/*
* Bitwise rotate a 32-bit number to the left.
*/
function
rol(num, cnt)
{
return
(num
<<
cnt)
|
(num
>>>
(
32
-
cnt));
}
/*
* Convert a string to an array of little-endian words
* If chrsz is ASCII, characters >255 have their hi-byte silently ignored.
*/
function
str2binl(str)
{
var
bin
=
Array();
var
mask
=
(
1
<<
chrsz)
-
1
;
for
(
var
i
=
0
; i
<
str.length
*
chrsz; i
+=
chrsz)
bin[i
>>
5
]
|=
(str.charCodeAt(i
/
chrsz)
&
mask)
<<
(i
%
32
);
return
bin;
}
/*
* Convert an array of little-endian words to a string
*/
function
binl2str(bin)
{
var
str
=
""
;
var
mask
=
(
1
<<
chrsz)
-
1
;
for
(
var
i
=
0
; i
<
bin.length
*
32
; i
+=
chrsz)
str
+=
String.fromCharCode((bin[i
>>
5
]
>>>
(i
%
32
))
&
mask);
return
str;
}
/*
* Convert an array of little-endian words to a hex string.
*/
function
binl2hex(binarray)
{
var
hex_tab
=
hexcase
?
"
0123456789ABCDEF
"
:
"
0123456789abcdef
"
;
var
str
=
""
;
for
(
var
i
=
0
; i
<
binarray.length
*
4
; i
++
)
{
str
+=
hex_tab.charAt((binarray[i
>>
2
]
>>
((i
%
4
)
*
8
+
4
))
&
0xF
)
+
hex_tab.charAt((binarray[i
>>
2
]
>>
((i
%
4
)
*
8
))
&
0xF
);
}
return
str;
}
/*
* Convert an array of little-endian words to a base-64 string
*/
function
binl2b64(binarray)
{
var
tab
=
"
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
"
;
var
str
=
""
;
for
(
var
i
=
0
; i
<
binarray.length
*
4
; i
+=
3
)
{
var
triplet
=
(((binarray[i
>>
2
]
>>
8
*
( i
%
4
))
&
0xFF
)
<<
16
)
|
(((binarray[i
+
1
>>
2
]
>>
8
*
((i
+
1
)
%
4
))
&
0xFF
)
<<
8
)
|
((binarray[i
+
2
>>
2
]
>>
8
*
((i
+
2
)
%
4
))
&
0xFF
);
for
(
var
j
=
0
; j
<
4
; j
++
)
{
if
(i
*
8
+
j
*
6
>
binarray.length
*
32
) str
+=
b64pad;
else
str
+=
tab.charAt((triplet
>>
6
*
(
3
-
j))
&
0x3F
);
}
}
return
str;
}
SHA1算法
/*
* A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined
* in FIPS PUB 180-1
* Version 2.1a Copyright Paul Johnston 2000 - 2002.
* Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
* Distributed under the BSD License
* See http://pajhome.org.uk/crypt/md5 for details.
*/
/*
* Configurable variables. You may need to tweak these to be compatible with
* the server-side, but the defaults work in most cases.
*/
var
hexcase
=
0
;
/*
hex output format. 0 - lowercase; 1 - uppercase
*/
var
b64pad
=
""
;
/*
base-64 pad character. "=" for strict RFC compliance
*/
var
chrsz
=
8
;
/*
bits per input character. 8 - ASCII; 16 - Unicode
*/
/*
* These are the functions you'll usually want to call
* They take string arguments and return either hex or base-64 encoded strings
*/
function
hex_sha1(s){
return
binb2hex(core_sha1(str2binb(s),s.length
*
chrsz));}
function
b64_sha1(s){
return
binb2b64(core_sha1(str2binb(s),s.length
*
chrsz));}
function
str_sha1(s){
return
binb2str(core_sha1(str2binb(s),s.length
*
chrsz));}
function
hex_hmac_sha1(key, data){
return
binb2hex(core_hmac_sha1(key, data));}
function
b64_hmac_sha1(key, data){
return
binb2b64(core_hmac_sha1(key, data));}
function
str_hmac_sha1(key, data){
return
binb2str(core_hmac_sha1(key, data));}
/*
* Perform a simple self-test to see if the VM is working
*/
function
sha1_vm_test()
{
return
hex_sha1(
"
abc
"
)
==
"
a9993e364706816aba3e25717850c26c9cd0d89d
"
;
}
/*
* Calculate the SHA-1 of an array of big-endian words, and a bit length
*/
function
core_sha1(x, len)
{
/*
append padding
*/
x[len
>>
5
]
|=
0x80
<<
(
24
-
len
%
32
);
x[((len
+
64
>>
9
)
<<
4
)
+
15
]
=
len;
var
w
=
Array(
80
);
var
a
=
1732584193
;
var
b
=
-
271733879
;
var
c
=
-
1732584194
;
var
d
=
271733878
;
var
e
=
-
1009589776
;
for
(
var
i
=
0
; i
<
x.length; i
+=
16
)
{
var
olda
=
a;
var
oldb
=
b;
var
oldc
=
c;
var
oldd
=
d;
var
olde
=
e;
for
(
var
j
=
0
; j
<
80
; j
++
)
{
if
(j
<
16
) w[j]
=
x[i
+
j];
else
w[j]
=
rol(w[j
-
3
]
^
w[j
-
8
]
^
w[j
-
14
]
^
w[j
-
16
],
1
);
var
t
=
safe_add(safe_add(rol(a,
5
), sha1_ft(j, b, c, d)),
safe_add(safe_add(e, w[j]), sha1_kt(j)));
e
=
d;
d
=
c;
c
=
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
*/
function
sha1_ft(t, b, c, d)
{
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
*/
function
sha1_kt(t)
{
return
(t
<
20
)
?
1518500249
: (t
<
40
)
?
1859775393
:
(t
<
60
)
?
-
1894007588
:
-
899497514
;
}
/*
* Calculate the HMAC-SHA1 of a key and some data
*/
function
core_hmac_sha1(key, data)
{
var
bkey
=
str2binb(key);
if
(bkey.length
>
16
) bkey
=
core_sha1(bkey, key.length
*
chrsz);
var
ipad
=
Array(
16
), opad
=
Array(
16
);
for
(
var
i
=
0
; i
<
16
; i
++
)
{
ipad[i]
=
bkey[i]
^
0x36363636
;
opad[i]
=
bkey[i]
^
0x5C5C5C5C
;
}
var
hash
=
core_sha1(ipad.concat(str2binb(data)),
512
+
data.length
*
chrsz);
return
core_sha1(opad.concat(hash),
512
+
160
);
}
/*
* Add integers, wrapping at 2^32. This uses 16-bit operations internally
* to work around bugs in some JS interpreters.
*/
function
safe_add(x, y)
{
var
lsw
=
(x
&
0xFFFF
)
+
(y
&
0xFFFF
);
var
msw
=
(x
>>
16
)
+
(y
>>
16
)
+
(lsw
>>
16
);
return
(msw
<<
16
)
|
(lsw
&
0xFFFF
);
}
/*
* Bitwise rotate a 32-bit number to the left.
*/
function
rol(num, cnt)
{
return
(num
<<
cnt)
|
(num
>>>
(
32
-
cnt));
}
/*
* Convert an 8-bit or 16-bit string to an array of big-endian words
* In 8-bit function, characters >255 have their hi-byte silently ignored.
*/
function
str2binb(str)
{
var
bin
=
Array();
var
mask
=
(
1
<<
chrsz)
-
1
;
for
(
var
i
=
0
; i
<
str.length
*
chrsz; i
+=
chrsz)
bin[i
>>
5
]
|=
(str.charCodeAt(i
/
chrsz)
&
mask)
<<
(
32
-
chrsz
-
i
%
32
);
return
bin;
}
/*
* Convert an array of big-endian words to a string
*/
function
binb2str(bin)
{
var
str
=
""
;
var
mask
=
(
1
<<
chrsz)
-
1
;
for
(
var
i
=
0
; i
<
bin.length
*
32
; i
+=
chrsz)
str
+=
String.fromCharCode((bin[i
>>
5
]
>>>
(
32
-
chrsz
-
i
%
32
))
&
mask);
return
str;
}
/*
* Convert an array of big-endian words to a hex string.
*/
function
binb2hex(binarray)
{
var
hex_tab
=
hexcase
?
"
0123456789ABCDEF
"
:
"
0123456789abcdef
"
;
var
str
=
""
;
for
(
var
i
=
0
; i
<
binarray.length
*
4
; i
++
)
{
str
+=
hex_tab.charAt((binarray[i
>>
2
]
>>
((
3
-
i
%
4
)
*
8
+
4
))
&
0xF
)
+
hex_tab.charAt((binarray[i
>>
2
]
>>
((
3
-
i
%
4
)
*
8
))
&
0xF
);
}
return
str;
}
/*
* Convert an array of big-endian words to a base-64 string
*/
function
binb2b64(binarray)
{
var
tab
=
"
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
"
;
var
str
=
""
;
for
(
var
i
=
0
; i
<
binarray.length
*
4
; i
+=
3
)
{
var
triplet
=
(((binarray[i
>>
2
]
>>
8
*
(
3
-
i
%
4
))
&
0xFF
)
<<
16
)
|
(((binarray[i
+
1
>>
2
]
>>
8
*
(
3
-
(i
+
1
)
%
4
))
&
0xFF
)
<<
8
)
|
((binarray[i
+
2
>>
2
]
>>
8
*
(
3
-
(i
+
2
)
%
4
))
&
0xFF
);
for
(
var
j
=
0
; j
<
4
; j
++
)
{
if
(i
*
8
+
j
*
6
>
binarray.length
*
32
) str
+=
b64pad;
else
str
+=
tab.charAt((triplet
>>
6
*
(
3
-
j))
&
0x3F
);
}
}
return
str;
}