unit SHA;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
function hex(num:dword):string;
function add(x,y:dword):dword;
function rol(num:dword;cnt:integer):dword;
function ft(t:integer;b,c,d:dword):dword;
function kt(t:integer):dword;
procedure SHA_EXTEND(var sourcestream:tmemorystream);
function SHA_EXE(sourcestream:tmemorystream;var deststream:tmemorystream):string;
implementation
function hex(num:dword):string;
var
strchar:array[0..15] of char;
strtemp:string;
inttemp:integer;
begin
strchar:='0123456789ABCDEF';
strtemp:='';
for inttemp:=7 downto 0 do
strtemp:=strtemp+strchar[(num shr (inttemp*4)) and$F];
result:=strtemp;
end;
function add(x,y:dword):dword;
var
lsw,msw:dword;
begin
lsw:=(x and $FFFF)+(y and $FFFF);
msw:=(x shr 16)+(y shr 16) +(lsw shr 16);
result:=(msw shl 16) or (lsw and $FFFF);
end;
function rol(num:dword;cnt:integer):dword;
begin
result:=(num shl cnt) or (num shr (32-cnt));
end;
function ft(t:integer;b,c,d:dword):dword;
var
temp:dword;
begin
temp:=0;
case t of
0..19:temp:=(b and c) or((not b) and d);
20..39:temp:=b xor c xor d;
40..59:temp:=(b and c) or (b and d) or (c and d);
60..79:temp:=b xor c xor d;
end;
result:=temp;
end;
function kt(t:integer):dword;
var
temp:dword;
begin
temp:=0;
case t of
0..19:temp:=$5A827999;
20..39:temp:=$6ED9EBA1;
40..59:temp:=$8F1BBCDC;
60..79:temp:=$CA62C1D6;
end;
result:=temp;
end;
procedure SHA_EXTEND(var sourcestream:tmemorystream);
var
intsourcestreambytelength:int64;//sourcestream的字节长度
intsourcestreambitlength:int64;//sourcestream的位长度
intsourcestreammod:integer; //sourcestream对56取模后剩下的字节数
intrest:integer;//需要填补$80,$00...的字节数
inttemp:integer;
bytetemp:byte;
begin
sourcestream.seek(0,sofromend);
intsourcestreambytelength:=sourcestream.position;
intsourcestreammod:=intsourcestreambytelength mod 64;
if intsourcestreammod<=56 then //用于计算所要填充的字节数
intrest:=56-intsourcestreammod
else
intrest:=64-intsourcestreammod+56;
sourcestream.SetSize(intsourcestreambytelength+intrest+8);//扩展sourcestream的空间,使其为64的整数倍
sourcestream.Seek(-intrest-8,sofromend);
bytetemp:=$80;
sourcestream.WriteBuffer(bytetemp,1);
bytetemp:=$00;
for inttemp:=0 to intrest-2 do
sourcestream.WriteBuffer(bytetemp,1);
intsourcestreambitlength:=intsourcestreambytelength*8;
sourcestream.WriteBuffer(intsourcestreambitlength,8);
end;
function SHA_EXE(sourcestream:tmemorystream;var deststream:tmemorystream):string;
var
a,b,c,d,e:dword;
olda,oldb,oldc,oldd,olde:dword;
w:array[0..79] of dword;
x:array[0..15] of dword;
intcount:integer;
i,j,t:integer;
begin
sourcestream.Seek(0,sofromend);
intcount:=sourcestream.Position div 64;
sourcestream.Position:=0;
sourcestream.SaveToFile('c:\xq.hex');
a:=$67452301;
b:=$EFCDAB89;
c:=$98BADCFE;
d:=$10325476;
e:=$C3D2E1F0;
for i:=0 to intcount-1 do
begin
sourcestream.ReadBuffer(x,64);
olda:=a;
oldb:=b;
oldc:=c;
oldd:=d;
olde:=e;
for j:=0 to 79 do
begin
if j<16 then
w[j]:=x[j]
else
w[j]:=rol(w[j-3] xor w[j-8] xor w[j-14] xor w[j-16],1);
t:=add(add(rol(a,5),ft(j,b,c,d)),add(add(e,w[j]),kt(j)));
e:=d;
d:=c;
c:=rol(b,30);
b:=a;
a:=t;
end;
a:=add(a,olda);
b:=add(b,oldb);
c:=add(c,oldc);
d:=add(d,oldd);
e:=add(e,olde);
end;
deststream.Position:=0;
deststream.WriteBuffer(a,4);
deststream.WriteBuffer(b,4);
deststream.WriteBuffer(c,4);
deststream.WriteBuffer(d,4);
deststream.WriteBuffer(e,4);
deststream.Position:=0;
result:=hex(a)+hex(b)+hex(c)+hex(d)+hex(e);
end;
end.
//以下为调用的程序:
unit USHA;