趁着放假,写了这个小东西。先看代码吧。

{******************************************************************************}
{------------------------------------------------------------------------------}
{- mzQQMD5 一个用于解决qq登录的MD5密文计算单元 -}
{------------------------------------------------------------------------------}
{- 作者:默之 -}
{- 邮箱:lofanmi@gmail.com -}
{------------------------------------------------------------------------------}
{- 代码写得很菜,冗余代码很多,由于个人水平有限,对js理解不深,又因为js -}
{- 里头的数组和delphi的数组不大一样只能写成这个样子了。如果以后有更新,大家 -}
{- 就Email我一份,在此先谢谢了。 -}
{------------------------------------------------------------------------------}
{******************************************************************************}

unit mzQQMD5;
{$WARNINGS OFF}
interface

uses
SysUtils;

function preprocess(A, B: string): string;

type
QQArray_LongInt_4 = array[0..3] of LongInt;
QQArray_LongInt_9 = array[0..8] of LongInt;
QQArray_LongInt_16 = array[0..15] of LongInt;

const
hexcase = True;
chrsz = 8;
mode = 32;

implementation

function charCodeAt(s: string; n: Byte): Integer;
var
c: array[0..1] of char;
h, l: string[2];
begin
StringToWideChar(s[n + 1], @(c[0]), 2);
h := IntToHex(Integer(c[1]), 2);
l := IntToHex(Integer(c[0]), 2);
Result := StrToInt('$' + h + l);
end;

function preQQArray_4(A: QQArray_LongInt_4): QQArray_LongInt_4;
var
i: Integer;
begin
for i := 0 to 3 do
begin
A[i] := 0;
end;
Result := A;
end;

function preQQArray_9(A: QQArray_LongInt_9): QQArray_LongInt_9;
var
i: Integer;
begin
for i := 0 to 8 do
begin
A[i] := 0;
end;
Result := A;
end;

function preQQArray_16(A: QQArray_LongInt_16): QQArray_LongInt_16;
var
i: Integer;
begin
for i := 0 to 15 do
begin
A[i] := 0;
end;
Result := A;
end;

function binl2hex_4(C: QQArray_LongInt_4): string;
var
A: Cardinal;
B: string;
D: string;
begin
if hexcase then
B := '0123456789ABCDEF'
else
B := '0123456789abcdef';
A := 0;
while A < Length(C) * 4 do
begin
D := D + B[((C[A shr 2] shr ((A mod 4) * 8 + 4)) and 15) + 1] + B[((C[A shr
2] shr ((A mod 4) * 8)) and 15) + 1];
A := A + 1;
end;
Result := D;
end;

function binl2hex_9(C: QQArray_LongInt_9): string;
var
A: Cardinal;
B: string;
D: string;
begin
if hexcase then
B := '0123456789ABCDEF'
else
B := '0123456789abcdef';
A := 0;
while A < Length(C) * 4 do
begin
if A = 16 then
Break;
D := D + B[((C[A shr 2] shr ((A mod 4) * 8 + 4)) and 15) + 1] + B[((C[A shr
2] shr ((A mod 4) * 8)) and 15) + 1];
A := A + 1;
end;
Result := D;
end;

function safe_add(A, D: LongInt): LongInt;
var
C, B: LongInt;
begin
C := (A and 65535) + (D and 65535);
B := (A shr 16) + (D shr 16) + (C shr 16);
Result := (B shl 16) or (C and 65535)
end;

function str2binl_4(D: string): QQArray_LongInt_4;
var
C: QQArray_LongInt_4;
B: Cardinal;
A: Byte;
begin
A := (1 shl chrsz) - 1;
C := preQQArray_4(C);
B := 0;
while B < Length(D) * chrsz do
begin
C[B shr 5] := C[B shr 5] or (charCodeAt(D, B div chrsz) and A) shl (B mod
32);
B := B + chrsz;
end;
Result := C;
end;

function str2binl_9(D: string): QQArray_LongInt_9;
var
C: QQArray_LongInt_9;
B: Cardinal;
A: Byte;
begin
A := (1 shl chrsz) - 1;
C := preQQArray_9(C);
B := 0;
while B < Length(D) * chrsz do
begin
C[B shr 5] := C[B shr 5] or (charCodeAt(D, B div chrsz) and A) shl (B mod
32);
B := B + chrsz;
end;
Result := C;
end;

function bit_rol(A: Cardinal; B: Byte): LongInt;
begin
Result := (A shl B) or (A shr (32 - B));
end;

function md5_cmn(F, C, B, A, E, D: LongInt): LongInt;
begin
Result := safe_add(bit_rol(safe_add(safe_add(C, F), safe_add(A, D)), E), B);
end;

function md5_ff(C, B, G, F, A: LongInt; E: Byte; D: LongInt): LongInt;
begin
Result := md5_cmn((B and G) or ((not B) and F), C, B, A, E, D)
end;

function md5_gg(C, B, G, F, A: LongInt; E: Byte; D: LongInt): LongInt;
begin
Result := md5_cmn((B and F) or (G and (not F)), C, B, A, E, D)
end;

function md5_hh(C, B, G, F, A: LongInt; E: Byte; D: LongInt): LongInt;
begin
Result := md5_cmn(B xor G xor F, C, B, A, E, D)
end;

function md5_ii(C, B, G, F, A: LongInt; E: Byte; D: LongInt): LongInt;
begin
Result := md5_cmn(G xor (B or (not F)), C, B, A, E, D);
end;

function core_md5_4(KK: QQArray_LongInt_4; F: Byte): QQArray_LongInt_4;
var
C: Cardinal;
J, I, H, G: LongInt;
E, D, B, A: LongInt;
K: QQArray_LongInt_16;
n: Integer;
begin
K := preQQArray_16(K);
for n := 0 to 3 do
begin
K[n] := KK[n];
end;
K[F shr 5] := (128 shl (F mod 32)) or K[F shr 5];
K[(((F + 64) shr 9) shl 4) + 14] := F;
J := 1732584193;
I := -271733879;
H := -1732584194;
G := 271733878;
C := 0;
// while C < Length(K) - 1 do
while C < 15 do
begin
E := J;
D := I;
B := H;
A := G;
J := md5_ff(J, I, H, G, K[C + 0], 7, -680876936);
G := md5_ff(G, J, I, H, K[C + 1], 12, -389564586);
H := md5_ff(H, G, J, I, K[C + 2], 17, 606105819);
I := md5_ff(I, H, G, J, K[C + 3], 22, -1044525330);
J := md5_ff(J, I, H, G, K[C + 4], 7, -176418897);
G := md5_ff(G, J, I, H, K[C + 5], 12, 1200080426);
H := md5_ff(H, G, J, I, K[C + 6], 17, -1473231341);
I := md5_ff(I, H, G, J, K[C + 7], 22, -45705983);
J := md5_ff(J, I, H, G, K[C + 8], 7, 1770035416);
G := md5_ff(G, J, I, H, K[C + 9], 12, -1958414417);
H := md5_ff(H, G, J, I, K[C + 10], 17, -42063);
I := md5_ff(I, H, G, J, K[C + 11], 22, -1990404162);
J := md5_ff(J, I, H, G, K[C + 12], 7, 1804603682);
G := md5_ff(G, J, I, H, K[C + 13], 12, -40341101);
H := md5_ff(H, G, J, I, K[C + 14], 17, -1502002290);
I := md5_ff(I, H, G, J, K[C + 15], 22, 1236535329);
J := md5_gg(J, I, H, G, K[C + 1], 5, -165796510);
G := md5_gg(G, J, I, H, K[C + 6], 9, -1069501632);
H := md5_gg(H, G, J, I, K[C + 11], 14, 643717713);
I := md5_gg(I, H, G, J, K[C + 0], 20, -373897302);
J := md5_gg(J, I, H, G, K[C + 5], 5, -701558691);
G := md5_gg(G, J, I, H, K[C + 10], 9, 38016083);
H := md5_gg(H, G, J, I, K[C + 15], 14, -660478335);
I := md5_gg(I, H, G, J, K[C + 4], 20, -405537848);
J := md5_gg(J, I, H, G, K[C + 9], 5, 568446438);
G := md5_gg(G, J, I, H, K[C + 14], 9, -1019803690);
H := md5_gg(H, G, J, I, K[C + 3], 14, -187363961);
I := md5_gg(I, H, G, J, K[C + 8], 20, 1163531501);
J := md5_gg(J, I, H, G, K[C + 13], 5, -1444681467);
G := md5_gg(G, J, I, H, K[C + 2], 9, -51403784);
H := md5_gg(H, G, J, I, K[C + 7], 14, 1735328473);
I := md5_gg(I, H, G, J, K[C + 12], 20, -1926607734);
J := md5_hh(J, I, H, G, K[C + 5], 4, -378558);
G := md5_hh(G, J, I, H, K[C + 8], 11, -2022574463);
H := md5_hh(H, G, J, I, K[C + 11], 16, 1839030562);
I := md5_hh(I, H, G, J, K[C + 14], 23, -35309556);
J := md5_hh(J, I, H, G, K[C + 1], 4, -1530992060);
G := md5_hh(G, J, I, H, K[C + 4], 11, 1272893353);
H := md5_hh(H, G, J, I, K[C + 7], 16, -155497632);
I := md5_hh(I, H, G, J, K[C + 10], 23, -1094730640);
J := md5_hh(J, I, H, G, K[C + 13], 4, 681279174);
G := md5_hh(G, J, I, H, K[C + 0], 11, -358537222);
H := md5_hh(H, G, J, I, K[C + 3], 16, -722521979);
I := md5_hh(I, H, G, J, K[C + 6], 23, 76029189);
J := md5_hh(J, I, H, G, K[C + 9], 4, -640364487);
G := md5_hh(G, J, I, H, K[C + 12], 11, -421815835);
H := md5_hh(H, G, J, I, K[C + 15], 16, 530742520);
I := md5_hh(I, H, G, J, K[C + 2], 23, -995338651);
J := md5_ii(J, I, H, G, K[C + 0], 6, -198630844);
G := md5_ii(G, J, I, H, K[C + 7], 10, 1126891415);
H := md5_ii(H, G, J, I, K[C + 14], 15, -1416354905);
I := md5_ii(I, H, G, J, K[C + 5], 21, -57434055);
J := md5_ii(J, I, H, G, K[C + 12], 6, 1700485571);
G := md5_ii(G, J, I, H, K[C + 3], 10, -1894986606);
H := md5_ii(H, G, J, I, K[C + 10], 15, -1051523);
I := md5_ii(I, H, G, J, K[C + 1], 21, -2054922799);
J := md5_ii(J, I, H, G, K[C + 8], 6, 1873313359);
G := md5_ii(G, J, I, H, K[C + 15], 10, -30611744);
H := md5_ii(H, G, J, I, K[C + 6], 15, -1560198380);
I := md5_ii(I, H, G, J, K[C + 13], 21, 1309151649);
J := md5_ii(J, I, H, G, K[C + 4], 6, -145523070);
G := md5_ii(G, J, I, H, K[C + 11], 10, -1120210379);
H := md5_ii(H, G, J, I, K[C + 2], 15, 718787259);
I := md5_ii(I, H, G, J, K[C + 9], 21, -343485551);
J := safe_add(J, E);
I := safe_add(I, D);
H := safe_add(H, B);
G := safe_add(G, A);
C := C + 16;
end;
Result[0] := J;
Result[1] := I;
Result[2] := H;
Result[3] := G;
end;

function core_md5_9(KK: QQArray_LongInt_9; F: Word): QQArray_LongInt_9;
var
C: Cardinal;
J, I, H, G: LongInt;
E, D, B, A: LongInt;
K: QQArray_LongInt_16;
n: Integer;
begin
K := preQQArray_16(K);
for n := 0 to 8 do
begin
K[n] := KK[n];
end;
K[F shr 5] := (128 shl (F mod 32)) or K[F shr 5];
K[(((F + 64) shr 9) shl 4) + 14] := F;
J := 1732584193;
I := -271733879;
H := -1732584194;
G := 271733878;
C := 0;
// while C < Length(K) - 1 do
while C < 15 do
begin
E := J;
D := I;
B := H;
A := G;
J := md5_ff(J, I, H, G, K[C + 0], 7, -680876936);
G := md5_ff(G, J, I, H, K[C + 1], 12, -389564586);
H := md5_ff(H, G, J, I, K[C + 2], 17, 606105819);
I := md5_ff(I, H, G, J, K[C + 3], 22, -1044525330);
J := md5_ff(J, I, H, G, K[C + 4], 7, -176418897);
G := md5_ff(G, J, I, H, K[C + 5], 12, 1200080426);
H := md5_ff(H, G, J, I, K[C + 6], 17, -1473231341);
I := md5_ff(I, H, G, J, K[C + 7], 22, -45705983);
J := md5_ff(J, I, H, G, K[C + 8], 7, 1770035416);
G := md5_ff(G, J, I, H, K[C + 9], 12, -1958414417);
H := md5_ff(H, G, J, I, K[C + 10], 17, -42063);
I := md5_ff(I, H, G, J, K[C + 11], 22, -1990404162);
J := md5_ff(J, I, H, G, K[C + 12], 7, 1804603682);
G := md5_ff(G, J, I, H, K[C + 13], 12, -40341101);
H := md5_ff(H, G, J, I, K[C + 14], 17, -1502002290);
I := md5_ff(I, H, G, J, K[C + 15], 22, 1236535329);
J := md5_gg(J, I, H, G, K[C + 1], 5, -165796510);
G := md5_gg(G, J, I, H, K[C + 6], 9, -1069501632);
H := md5_gg(H, G, J, I, K[C + 11], 14, 643717713);
I := md5_gg(I, H, G, J, K[C + 0], 20, -373897302);
J := md5_gg(J, I, H, G, K[C + 5], 5, -701558691);
G := md5_gg(G, J, I, H, K[C + 10], 9, 38016083);
H := md5_gg(H, G, J, I, K[C + 15], 14, -660478335);
I := md5_gg(I, H, G, J, K[C + 4], 20, -405537848);
J := md5_gg(J, I, H, G, K[C + 9], 5, 568446438);
G := md5_gg(G, J, I, H, K[C + 14], 9, -1019803690);
H := md5_gg(H, G, J, I, K[C + 3], 14, -187363961);
I := md5_gg(I, H, G, J, K[C + 8], 20, 1163531501);
J := md5_gg(J, I, H, G, K[C + 13], 5, -1444681467);
G := md5_gg(G, J, I, H, K[C + 2], 9, -51403784);
H := md5_gg(H, G, J, I, K[C + 7], 14, 1735328473);
I := md5_gg(I, H, G, J, K[C + 12], 20, -1926607734);
J := md5_hh(J, I, H, G, K[C + 5], 4, -378558);
G := md5_hh(G, J, I, H, K[C + 8], 11, -2022574463);
H := md5_hh(H, G, J, I, K[C + 11], 16, 1839030562);
I := md5_hh(I, H, G, J, K[C + 14], 23, -35309556);
J := md5_hh(J, I, H, G, K[C + 1], 4, -1530992060);
G := md5_hh(G, J, I, H, K[C + 4], 11, 1272893353);
H := md5_hh(H, G, J, I, K[C + 7], 16, -155497632);
I := md5_hh(I, H, G, J, K[C + 10], 23, -1094730640);
J := md5_hh(J, I, H, G, K[C + 13], 4, 681279174);
G := md5_hh(G, J, I, H, K[C + 0], 11, -358537222);
H := md5_hh(H, G, J, I, K[C + 3], 16, -722521979);
I := md5_hh(I, H, G, J, K[C + 6], 23, 76029189);
J := md5_hh(J, I, H, G, K[C + 9], 4, -640364487);
G := md5_hh(G, J, I, H, K[C + 12], 11, -421815835);
H := md5_hh(H, G, J, I, K[C + 15], 16, 530742520);
I := md5_hh(I, H, G, J, K[C + 2], 23, -995338651);
J := md5_ii(J, I, H, G, K[C + 0], 6, -198630844);
G := md5_ii(G, J, I, H, K[C + 7], 10, 1126891415);
H := md5_ii(H, G, J, I, K[C + 14], 15, -1416354905);
I := md5_ii(I, H, G, J, K[C + 5], 21, -57434055);
J := md5_ii(J, I, H, G, K[C + 12], 6, 1700485571);
G := md5_ii(G, J, I, H, K[C + 3], 10, -1894986606);
H := md5_ii(H, G, J, I, K[C + 10], 15, -1051523);
I := md5_ii(I, H, G, J, K[C + 1], 21, -2054922799);
J := md5_ii(J, I, H, G, K[C + 8], 6, 1873313359);
G := md5_ii(G, J, I, H, K[C + 15], 10, -30611744);
H := md5_ii(H, G, J, I, K[C + 6], 15, -1560198380);
I := md5_ii(I, H, G, J, K[C + 13], 21, 1309151649);
J := md5_ii(J, I, H, G, K[C + 4], 6, -145523070);
G := md5_ii(G, J, I, H, K[C + 11], 10, -1120210379);
H := md5_ii(H, G, J, I, K[C + 2], 15, 718787259);
I := md5_ii(I, H, G, J, K[C + 9], 21, -343485551);
J := safe_add(J, E);
I := safe_add(I, D);
H := safe_add(H, B);
G := safe_add(G, A);
C := C + 16;
end;
Result[0] := J;
Result[1] := I;
Result[2] := H;
Result[3] := G;
end;

function hex_md5(A: string): string;
begin
Result := binl2hex_9(core_md5_9(str2binl_9(A), Length(A) * chrsz));
end;

function md5(A: string): string;
begin
Result := hex_md5(A);
end;

function md5_3(B: string): string;
var
A: QQArray_LongInt_4;
begin
A := core_md5_4(str2binl_4(B), Length(B) * chrsz);
A := core_md5_4(A, 16 * chrsz);
A := core_md5_4(A, 16 * chrsz);
Result := binl2hex_4(A);
end;

function preprocess(A, B: string): string;
begin
Result := md5(md5_3(A) + B);
end;

end.


    写这个单元文件,学了不少。我对js接触不多,平时念书,没时间学习js。这次懂了,js里面的数组,下标不但可以是正数,还可以是负数,小数,字符串!而delphi 的数组就不一样了,它只能是连续的自然数。js里面的数组如果不连续,“断“了的部分自动初始化为0。长度不一的数组可以相互传递赋值,delphi对类型要求严格,并不支持!所以上面的代码惨不忍睹。正如你所看到的,“4、9、16”, 我的水平有限,只能到如此地步了,恳请大家出谋划策。另外,在函数charCodeAt中,Delphi 7 运行错误,应该是它不支持$0070类似字符串到整形数字的转换,代码我是在XE(自己感觉XE调试棒一些,对于变量的跟踪比较顺手)编译运行的,完全通过,没有报告错误,大家也可以扩展一下,或者做成类。我读书的时间不多,今天正赶上高三一模,我才能做好它,花费了一天半的时间。这个单元的完成,离不开百度谷歌,还有火狐的js调试器,感谢你们。还有,密码要是有"\"字符的,小心在其它环境变成转义,包括js! QQ的密码是支持的,我想是它特殊处理了,不过这个并不重要,因为在delphi中“\”没有转义。在火狐调试脚本的时候,我忘了这一点,还郁闷了许久。

 

附:pas文件及调试用的html