实际上这种办法是有缺陷的,但是需要的就是这个缺陷(没有办法)
今天我有提过md5.asp因为设计上的缺陷,在对双字节字符(比方说中文)进行加密的时候会和标准的md5算法(.Net /IndyHashMessageDigest5 / md5.pas,这三者计算结果相同,同为以字节为单位计算岀的结果)结果有出入。
其原因在于md5.asp使用mid函数,取出的是“字符”,而正确的做法应该是取出字节,可是论坛数据库(比方说dvbbs7)中的数据已经是md5.asp的加密结果,所以我们只能将错就错,为我们的程序重写一个和md5.asp一样的加密过程
>>>> 被广泛使用的MD5.asp中似乎存在缺陷
我今天总算是用Delphi写出来了
虽然不知道asc函数得到的结果是否正确代码——我的目标是和md5.asp结果一样,现在缺的不就是这个有缺陷的程序吗?
unit AMD5;
interface
////////////////////////////////////////////
// 文件名 : AMD5.pas //
// 功能 : 与md5.asp计算结果相同 //
// 作者 : 由ScriptBaby改编自md5.asp //
// 完成时间: 2004-07-21 //
////////////////////////////////////////////
//请转载者保留以上信息,谢谢//
uses
SysUtils;
type
arrlongword = array of longword;
type
sMD5 = class
class function RotateLeft(const lValue, Bits: longword): longword;
class function MD5(const sMessage: string; const sType: boolean = false): string;
class function ConvToWord(const sMessage: string): arrlongword; overload;
class function ConvToWord(const sMessage: WideString): arrlongword; overload;
class function WordToHex(const lValue: longword): string;
end;
implementation
const
BITS_TO_A_BYTE = 8;
BYTES_TO_A_WORD = 4;
BITS_TO_A_WORD = 32;
cAA = $67452301;
cBB = $EFCDAB89;
cCC = $98BADCFE;
cDD = $10325476;
MODULUS_BITS = 512;
CONGRUENT_BITS = 448;
{ sMD5 }
class function sMD5.ConvToWord(const sMessage: WideString): arrlongword;
var
lMessageLength,
lNumberOfWords,
lBytePosition,
lByteCount,
lWordCount: longword;
lWordArray: arrlongword;
{ Function }
function Asc(const t: WideChar): Smallint;
var
s: string;
a: Smallint;
begin
s := t;
a := Smallint(s[1]);
case Length(s) of
2:
begin
a := a shl 8;
a := a + Smallint(s[2]);
end
else ;
end;
Result := a;
end;
[page]
begin
lMessageLength := Length(sMessage);
lNumberOfWords := (((lMessageLength + ((MODULUS_BITS - CONGRUENT_BITS) div BITS_TO_A_BYTE)) div (MODULUS_BITS div BITS_TO_A_BYTE)) + 1) * (MODULUS_BITS div BITS_TO_A_WORD);
SetLength(lWordArray, lNumberOfWords);
lByteCount := 0;
While lByteCount < lMessageLength do begin
lWordCount := lByteCount div BYTES_TO_A_WORD;
lBytePosition := (lByteCount Mod BYTES_TO_A_WORD) * BITS_TO_A_BYTE;
lWordArray[lWordCount] := lWordArray[lWordCount] Or longword(Asc(sMessage[lByteCount + 1]) shl lBytePosition);
lByteCount := lByteCount + 1;
end;
lWordCount := lByteCount div BYTES_TO_A_WORD;
lBytePosition := (lByteCount Mod BYTES_TO_A_WORD) * BITS_TO_A_BYTE;
lWordArray[lWordCount] := lWordArray[lWordCount] or ($80 shl lBytePosition);
lWordArray[lNumberOfWords - 2] := lMessageLength shl 3;
lWordArray[lNumberOfWords - 1] := lMessageLength shr 29;
Result := lWordArray;
end;
class function sMD5.ConvToWord(const sMessage: string): arrlongword;
begin
Result := ConvToWord(WideString(sMessage));
end;
class function sMD5.MD5(const sMessage: string;
const sType: boolean = false): string;
const
S11 = 7;
S12 = 12;
S13 = 17;
S14 = 22;
S21 = 5;
S22 = 9;
S23 = 14;
S24 = 20;
S31 = 4;
S32 = 11;
S33 = 16;
S34 = 23;
S41 = 6;
S42 = 10;
S43 = 15;
S44 = 21;
[page]
var
k: integer;
AA, BB, CC, DD, a, b, c, d: longword;
x: arrlongword;
s: string;
{ functions }
function md5_F(const x, y, z: longword): longword;
begin
Result := (x And y) Or ((Not x) And z);
end;
function md5_G(const x, y, z: longword): longword;
begin
Result := (x And z) Or (y And (Not z));
end;
function md5_H(const x, y, z: longword): longword;
begin
Result := (x Xor y Xor z);
end;
function md5_I(const x, y, z: longword): longword;
begin
Result := (y Xor (x Or (Not z)));
end;
procedure md5_FF(var a: longword; const b, c, d, x, s, ac: longword);
begin
a := a + md5_F(b, c, d) + x + ac;
a := RotateLeft(a, s);
a := a + b;
end;
procedure md5_GG(var a: longword; const b, c, d, x, s, ac: longword);
begin
a := a + md5_G(b, c, d) + x + ac;
a := RotateLeft(a, s);
a := a + b;
end;
procedure md5_HH(var a: longword; const b, c, d, x, s, ac: longword);
begin
&nb