电脑爱好者,提供IT资讯信息及各类编程知识文章介绍,欢迎大家来本站学习电脑知识。 最近更新 | 联系我们 RSS订阅本站最新文章
电脑爱好者
站内搜索: 
当前位置:首页>> delphi技术>>Delphi7 的 MD5 函数:

Delphi7 的 MD5 函数

来源:www.cncfan.com | 2006-1-9 | (有5960人读过)

前天在设计系统的用户管理时,突然想用玩 PHP 的老婆强烈眩耀 PHP 有同时嗤之以鼻咱 Delphi 没有的 MD5。于是按惯例到大富翁找……半天下来,始终没有我满意的!(是不是我太臭屎了?别扔砖头哦!)
  很不服气,但找了个 C++ 版的 16 位的 MD5 函数,自己动手改编成 Delphi 7 的函数(已验证),自以为是地认为,它是目前最快最好最NB的……哼!
  现无私奉献,供大家“修改”出更好的来:
====================================================================================
{:
Author: Shnafus Kisber
From: GD, China
Date: 2004-6-14
Email: kisber@163.net
Note: FFA
}
unit MD5Unit;

interface

function MD5(const iStr: string): string;

implementation

const
BUFFERSIZE = Cardinal(64); //must be 4 power size
BUFFERSIZE_D = Cardinal(BUFFERSIZE div 4);

function MD5(const iStr: string): string;
type
md5ctx = record
A, B, C, D: Cardinal; // state (ABCD)
Count: Int64;
Buffer: array[0..BUFFERSIZE - 1] of Byte; // input buffer
end;
const
MD5CTXSIZE = SizeOf(md5ctx);
COUNT_SIZE = SizeOf(Int64);
OFFSET_T = -SizeOf(Int64);
OFFSET_D = OFFSET_T-SizeOf(Cardinal);
OFFSET_C = OFFSET_D-SizeOf(Cardinal);
OFFSET_B = OFFSET_C-SizeOf(Cardinal);
OFFSET_A = OFFSET_B-SizeOf(Cardinal);

//:清除明文暂存区
procedure ClearBuffer;
//ebp: vCtx.Buffer
asm
PUSH EAX
PUSH EDI
PUSH ECX
XOR EAX,EAX
MOV EDI,EBP
MOV ECX,BUFFERSIZE_D
REP STOSD
POP ECX
POP EDI
POP EAX
end;

//:设置定长字符串
procedure MakeString(var s: string; Size: Integer);
begin
SetLength(s, Size);
end;

asm
JMP @@start

//-------------------------------------------------------------------
//索引
@@bIdxs:
DB 00,01,02,03,04,05,06,07,08,09,10,11,12,13,14,15
DB 01,06,11,00,05,10,15,04,09,14,03,08,13,02,07,12
DB 05,08,11,14,01,04,07,10,13,00,03,06,09,12,15,02
DB 00,07,14,05,12,03,10,01,08,15,06,13,04,11,02,09

//左循环移位量
@@bRots:
DB 07,12,17,22,07,12,17,22,07,12,17,22,07,12,17,22
DB 05,09,14,20,05,09,14,20,05,09,14,20,05,09,14,20
DB 04,11,16,23,04,11,16,23,04,11,16,23,04,11,16,23
DB 06,10,15,21,06,10,15,21,06,10,15,21,06,10,15,21

//加密计算位码
@@Magics:
DD $D76AA478, $E8C7B756, $242070DB, $C1BDCEEE
DD $F57C0FAF, $4787C62A, $A8304613, $FD469501
DD $698098D8, $8B44F7AF, $FFFF5BB1, $895CD7BE
DD $6B901122, $FD987193, $A679438E, $49B40821

DD $F61E2562, $C040B340, $265E5A51, $E9B6C7AA
DD $D62F105D, $02441453, $D8A1E681, $E7D3FBC8
DD $21E1CDE6, $C33707D6, $F4D50D87, $455A14ED
DD $A9E3E905, $FCEFA3F8, $676F02D9, $8D2A4C8A

DD $FFFA3942, $8771F681, $6D9D6122, $FDE5380C
DD $A4BEEA44, $4BDECFA9, $F6BB4B60, $BEBFBC70
DD $289B7EC6, $EAA127FA, $D4EF3085, $04881D05
DD $D9D4D039, $E6DB99E5, $1FA27CF8, $C4AC5665

DD $F4292244, $432AFF97, $AB9423A7, $FC93A039
DD $655B59C3, $8F0CCC92, $FFEFF47D, $85845DD1
DD $6FA87E4F, $FE2CE6E0, $A3014314, $4E0811A1
DD $F7537E82, $BD3AF235, $2AD7D2BB, $EB86D391
//-------------------------------------------------------------------
/////////// -1: fghi
@@fghi:
PUSH EDX //F

XOR EDX,EDX
MOV DL,BYTE PTR @@bIdxs[ESI]
SHL EDX,2
MOV EDX,[EBP][EDX] //(x)
SHL ESI,2
ADD EDX,DWORD PTR @@Magics[ESI] //(x) + (ac)
SHR ESI,2

ADD EAX,EDX //a += (x) + (ac)
POP EDX
ADD EAX,EDX //a += F

//#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
PUSH ECX
MOV CL,BYTE PTR @@bRots[ESI]
ROL EAX,CL //ROTATE_LEFT(a, s)
POP ECX

ADD EAX,EBX // a += b

//Adjust: a -> b -> c -> d -> a
XCHG EDI,ECX
XCHG ECX,EBX
XCHG EBX,EAX
INC ESI
RET

@@update:
PUSHAD
MOV EAX,[EBP][OFFSET_A] //a, state[0]
MOV EBX,[EBP][OFFSET_B] //b, state[1]
MOV ECX,[EBP][OFFSET_C] //c, state[2]
MOV EDI,[EBP][OFFSET_D] //d, state[3]
XOR ESI,ESI //index


(*
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
#define FF(a, b, c, d, x, s, ac) { \
(a) += F ((b), (c), (d)) + (x) + (WORD32)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
FF ( lA, lB, lC, lD, x[ 0], S11, 0xd76aa478); // 1
FF ( lD, lA, lB, lC, x[ 1], S12, 0xe8c7b756); // 2
FF ( lC, lD, lA, lB, x[ 2], S13, 0x242070db); // 3
FF ( lB, lC, lD, lA, x[ 3], S14, 0xc1bdceee); // 4
FF ( lA, lB, lC, lD, x[ 4], S11, 0xf57c0faf); // 5
FF ( lD, lA, lB, lC, x[ 5], S12, 0x4787c62a); // 6
FF ( lC, lD, lA, lB, x[ 6], S13, 0xa8304613); // 7
FF ( lB, lC, lD, lA, x[ 7], S14, 0xfd469501); // 8
FF ( lA, lB, lC, lD, x[ 8], S11, 0x698098d8); // 9
FF ( lD, lA, lB, lC, x[ 9], S12, 0x8b44f7af); // 10
FF ( lC, lD, lA, lB, x[10], S13, 0xffff5bb1); // 11
FF ( lB, lC, lD, lA, x[11], S14, 0x895cd7be); // 12
FF ( lA, lB, lC, lD, x[12], S11, 0x6b901122); // 13
FF ( lD, lA, lB, lC, x[13], S12, 0xfd987193); // 14
FF ( lC, lD, lA, lB, x[14], S13, 0xa679438e); // 15
FF ( lB, lC, lD, lA, x[15], S14, 0x49b40821); // 16
*)
@@ffst:
//F(x, y, z) (((x) & (y)) | ((~x) & (z))) = ebx & ecx | !ebx & edi
PUSH ECX
MOV EDX,EBX
NOT EDX
AND EDX,EDI
AND ECX,EBX
OR EDX,ECX
POP ECX

CALL @@fghi

TEST ESI,$F
JNZ @@ffst

(*
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
#define GG(a, b, c, d, x, s, ac) { \
(a) += G ((b), (c), (d)) + (x) + (WORD32)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
GG ( lA, lB, lC, lD, x[ 1], S21, 0xf61e2562); // 17
GG ( lD, lA, lB, lC, x[ 6], S22, 0xc040b340); // 18
GG ( lC, lD, lA, lB, x[11], S23, 0x265e5a51); // 19
GG ( lB, lC, lD, lA, x[ 0], S24, 0xe9b6c7aa); // 20
GG ( lA, lB, lC, lD, x[ 5], S21, 0xd62f105d); // 21
GG ( lD, lA, lB, lC, x[10], S22, 0x2441453); // 22
GG ( lC, lD, lA, lB, x[15], S23, 0xd8a1e681); // 23
GG ( lB, lC, lD, lA, x[ 4], S24, 0xe7d3fbc8); // 24
GG ( lA, lB, lC, lD, x[ 9], S21, 0x21e1cde6); // 25
GG ( lD, lA, lB, lC, x[14], S22, 0xc33707d6); // 26
GG ( lC, lD, lA, lB, x[ 3], S23, 0xf4d50d87); // 27
GG ( lB, lC, lD, lA, x[ 8], S24, 0x455a14ed); // 28
GG ( lA, lB, lC, lD, x[13], S21, 0xa9e3e905); // 29
GG ( lD, lA, lB, lC, x[ 2], S22, 0xfcefa3f8); // 30
GG ( lC, lD, lA, lB, x[ 7], S23, 0x676f02d9); // 31
GG ( lB, lC, lD, lA, x[12], S24, 0x8d2a4c8a); // 32
*)
@@ggst:
//G(x, y, z) (((x) & (z)) | ((y) & (~z))) = ebx & edi | ecx & !edi
PUSH ECX
MOV EDX,EDI
NOT EDX
AND ECX,EDX
MOV EDX,EBX
AND EDX,EDI
OR EDX,ECX
POP ECX

CALL @@fghi

TEST ESI,$F
JNZ @@ggst

//HH ( lA, lB, lC, lD, x[ 5], S31, 0xfffa3942); // 33
(*
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define HH(a, b, c, d, x, s, ac) { \
(a) += H ((b), (c), (d)) + (x) + (WORD32)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
HH ( lA, lB, lC, lD, x[ 5], S31, 0xfffa3942); // 33
HH ( lD, lA, lB, lC, x[ 8], S32, 0x8771f681); // 34
HH ( lC, lD, lA, lB, x[11], S33, 0x6d9d6122); // 35
HH ( lB, lC, lD, lA, x[14], S34, 0xfde5380c); // 36
HH ( lA, lB, lC, lD, x[ 1], S31, 0xa4beea44); // 37
HH ( lD, lA, lB, lC, x[ 4], S32, 0x4bdecfa9); // 38
HH ( lC, lD, lA, lB, x[ 7], S33, 0xf6bb4b60); // 39
HH ( lB, lC, lD, lA, x[10], S34, 0xbebfbc70); // 40
HH ( lA, lB, lC, lD, x[13], S31, 0x289b7ec6); // 41
HH ( lD, lA, lB, lC, x[ 0], S32, 0xeaa127fa); // 42
HH ( lC, lD, lA, lB, x[ 3], S33, 0xd4ef3085); // 43
HH ( lB, lC, lD, lA, x[ 6], S34, 0x4881d05); // 44
HH ( lA, lB, lC, lD, x[ 9], S31, 0xd9d4d039); // 45
HH ( lD, lA, lB, lC, x[12], S32, 0xe6db99e5); // 46
HH ( lC, lD, lA, lB, x[15], S33, 0x1fa27cf8); // 47
HH ( lB, lC, lD, lA, x[ 2], S34, 0xc4ac5665); // 48
*)
@@hhst:
//H(x, y, z) ((x) ^ (y) ^ (z)) = ebx ^ ecx ^ edi
MOV EDX,EBX
XOR EDX,ECX
XOR EDX,EDI

CALL @@fghi

TEST ESI,$F
JNZ @@hhst

//II ( lA, lB, lC, lD, x[ 0], S41, 0xf4292244); // 49
(*
#define I(x, y, z) ((y) ^ ((x) | (~z)))
#define II(a, b, c, d, x, s, ac) { \
(a) += I ((b), (c), (d)) + (x) + (WORD32)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
II ( lA, lB, lC, lD, x[ 0], S41, 0xf4292244); // 49
II ( lD, lA, lB, lC, x[ 7], S42, 0x432aff97); // 50
II ( lC, lD, lA, lB, x[14], S43, 0xab9423a7); // 51
II ( lB, lC, lD, lA, x[ 5], S44, 0xfc93a039); // 52
II ( lA, lB, lC, lD, x[12], S41, 0x655b59c3); // 53
II ( lD, lA, lB, lC, x[ 3], S42, 0x8f0ccc92); // 54
II ( lC, lD, lA, lB, x[10], S43, 0xffeff47d); // 55
II ( lB, lC, lD, lA, x[ 1], S44, 0x85845dd1); // 56
II ( lA, lB, lC, lD, x[ 8], S41, 0x6fa87e4f); // 57
II ( lD, lA, lB, lC, x[15], S42, 0xfe2ce6e0); // 58
II ( lC, lD, lA, lB, x[ 6], S43, 0xa3014314); // 59
II ( lB, lC, lD, lA, x[13], S44, 0x4e0811a1); // 60
II ( lA, lB, lC, lD, x[ 4], S41, 0xf7537e82); // 61
II ( lD, lA, lB, lC, x[11], S42, 0xbd3af235); // 62
II ( lC, lD, lA, lB, x[ 2], S43, 0x2ad7d2bb); // 63
II ( lB, lC, lD, lA, x[ 9], S44, 0xeb86d391); // 64
*)
@@iist:
//I(x, y, z) ((y) ^ ((x) | (~z))) = ecx ^ (ebx | !edi)
MOV EDX,EDI
NOT EDX
OR EDX,EBX
XOR EDX,ECX

CALL @@fghi

TEST ESI,$F
JNZ @@iist

{
state[0] += lA;
state[1] += lB;
state[2] += lC;
state[3] += lD;
}
ADD DWORD PTR [EBP][OFFSET_A],EAX
ADD DWORD PTR [EBP][OFFSET_B],EBX
ADD DWORD PTR [EBP][OFFSET_C],ECX
ADD DWORD PTR [EBP][OFFSET_D],EDI

POPAD
RET

//+++++++++++++++++++++++++++++++++++++++++++++++++++++
@@start:
PUSH EBX
PUSH EDX
PUSH ESI
PUSH EDI
PUSH EBP
MOV EBP,ESP
SUB ESP,MD5CTXSIZE //make md5ctx
SUB EBP,BUFFERSIZE //EBP: md5ctx.Buffer
OR EAX,EAX //if s = ''
JZ @@rrt //Result := ''
MOV ECX,[EAX-4]
OR ECX,ECX //if Length(s) = 0
JZ @@rt //Result := ''
CLD
MOV DWORD PTR [EBP][OFFSET_A],$67452301 //Init magic
MOV DWORD PTR [EBP][OFFSET_B],$EFCDAB89
MOV DWORD PTR [EBP][OFFSET_C],$98BADCFE
MOV DWORD PTR [EBP][OFFSET_D],$10325476
MOV DWORD PTR [EBP][OFFSET_T],0 //Size = 0
MOV DWORD PTR [EBP][OFFSET_T + 4],0

MOV EBX,EAX
@@domo: MOV ESI,EBX
MOV EDI,EBP
CMP ECX,BUFFERSIZE //if Size < BUFFERSIZE
JB @@finish //update it
PUSH ECX
MOV ECX,BUFFERSIZE_D
ADD [EBP][OFFSET_T],ECX
ADC [EBP][OFFSET_T + 4],0 //else
REP MOVSD //update block per BUFFERSIZE bytes
CALL @@update
POP ECX
ADD EBX,DWORD PTR BUFFERSIZE
SUB ECX,DWORD PTR BUFFERSIZE
JNC @@domo //loop
MOV ESI,EBX
MOV EDI,EBP
@@finish:
CALL CLEARBUFFER
ADD [EBP][OFFSET_T],ECX
ADC [EBP][OFFSET_T + 4],0
PUSH ECX
REP MOVSB //encode the left
POP ECX
MOV AL,$80 //push END-MESSAGE byte
STOSB
INC ECX
MOV EAX,BUFFERSIZE - COUNT_SIZE
CMP ECX,EAX //if free buffer less then COUNT_SIZE
JB @@sio
CALL @@update //update it first
MOV EDI,EBP
XOR ECX,ECX
@@sio: SUB EAX,ECX
XCHG EAX,ECX
MOV AL,0 //fill buffer full
REP STOSB
MOV EAX,[EBP][OFFSET_T] //message bits = count * 8
MOV EDX,[EBP][OFFSET_T + 4]
ROL EAX,3
SHL EDX,3
MOV CL,AL
AND AL,$F8
AND CL,7
OR DL,CL
MOV [EBP][BUFFERSIZE + OFFSET_T],EAX //save message bits
MOV [EBP][BUFFERSIZE + OFFSET_T + 4],EDX //to buffer
CALL @@update //and update
MOV EAX,EBP //that's ok
MOV [EAX],0
MOV EDX,32
CALL MAKESTRING //make a new string
MOV ECX,16
LEA ESI,[EBP][OFFSET_A]
MOV EDI,[EAX]
PUSH EDI
@@cp: LODSB //store md5 digest in HEX code
MOV AH,AL //to string
AND AX,$F00F
SHR AH,4
OR AX,$3030
CMP AL,$39
JBE @@pah
ADD AL,7
@@pah: CMP AH,$39
JBE @@sto
ADD AH,7
@@sto: XCHG AH,AL
STOSW
LOOP @@cp
POP ECX
@@rt: MOV EAX,ECX //return this string
@@rrt: ADD EBP,BUFFERSIZE
MOV ESP,EBP
POP EBP
POP EDI
POP ESI
POP EDX
POP EBX
MOV [EDX],EAX //is it what you want?
end;

end.
delphi技术热门文章排行
网站赞助商
购买此位置

 

关于我们 | 网站地图 | 文档一览 | 友情链接| 联系我们

Copyright © 2003-2024 电脑爱好者 版权所有 备案号:鲁ICP备09059398号