Sources
Delphi Russian Knowledge Base
DRKB - это самая большая и удобная в использовании база знаний по Дельфи в рунете, составленная Виталием Невзоровым

Шифрование SHA-1

01.01.2007
unit main;
 
interface
 
uses
 
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, StdCtrls,
 
Dialogs;
 
type
  TForm1
= class(TForm)
    Memo1
: TMemo;
    Button1
: TButton;
    Button2
: TButton;
    Button3
: TButton;
    Button4
: TButton;
    CheckBox1
: TCheckBox;
    CheckBox2
: TCheckBox;
    CheckBox3
: TCheckBox;
   
BStop: TButton;
    SaveDialog1
: TSaveDialog;
    OpenDialog1
: TOpenDialog;
    procedure
FormCreate(Sender: TObject);
    procedure Button1Click
(Sender: TObject);
    procedure Button2Click
(Sender: TObject);
    procedure
FormResize(Sender: TObject);
    procedure Button3Click
(Sender: TObject);
    procedure Button4Click
(Sender: TObject);
    procedure
BStopClick(Sender: TObject);
 
private   { Private declarations }
 
public    { Public declarations }
 
end;
var
  Form1
: TForm1;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const
  HC0
=$67452301;
  HC1
=$EFCDAB89;
  HC2
=$98BADCFE;
  HC3
=$10325476;
  HC4
=$C3D2E1F0;
 
  K1
=$5A827999;
  K2
=$6ED9EBA1;
  K3
=$8F1BBCDC;
  K4
=$CA62C1D6;
 
 
var H0,H1,H2,H3,H4:integer;  Hout:string;  //Hout - результат
   
StopScan:boolean;
implementation
{$R *.DFM}
 
function rol(const x:integer;const y:byte):integer ;     //сдвиг числа x на y бит влево
begin
 
asm
    mov  eax
,x
    mov  cl
, y
    rol  eax
,cl
    mov  x
, eax
 
end;
  result
:=x;
end;
 
procedure INIT
;        //Инициализация - присвоить пересенным значения констант
begin
  H0
:=HC0;//$67452301;
  H1
:=HC1;//$EFCDAB89;
  H2
:=HC2;//$98BADCFE;
  H3
:=HC3;//$10325476;
  H4
:=HC4;//$C3D2E1F0;
 
Hout:='';
end;
 
function PADDING(s:string;FS:integer):string;     //добавление одного бита (1000000=128) и добавление нулей до кратности 64 байтам
var size,i:integer;
begin
size
:=Length(s)*8;   //size -входной размер в битах
s
:=s+char(128);    //добавление одного бита  (1000000=128)
 
while (Length(s) mod 64) <>0 do s:=s+#0;     //добавление нулей до кратности 64  байтам
 
//############   #############    //   IF  ((size) >= 448) then // OLD
 
IF  
((size mod 512) >= 448) then         // если хвост превышает 48 байт то добавить пустой блок из 64 нулей
                   
begin
                      s
:=s+#0;                                 //добавление нулей до кратности 64
                     
while (Length(s) mod 64) <>0 do s:=s+#0;
                   
end;
 
      i
:=Length(s);size:=FS*8;
     
while size > 0 do             //запись в конец строки её размер
     
begin
      s
[i]:=char(byte(size));      //получение младшего байта
      size
:=size shr 8;            //сдвиг вправо на 8 бит - перенос старшего байта на место младшего
      i
:=i-1;
     
end;
Result:=s;
end;
 
 
Procedure START(const S_IN:string);
var    A,B,C,D,E,TEMP:integer;    t,i:byte;    W:array[0..79] of integer;  
begin
 
  t
:=1;
 
for i:=1 to ((Length(S_IN)) div 4) do
 
begin
   
// W[i-1]:=ord(S_IN[t])*256*256*256+ord(S_IN[t+1])*256*256+ord(S_IN[t+2])*256+ord(S_IN[t+3]);
    W
[i-1]:=(ord(S_IN[t]) shl 24) +(ord(S_IN[t+1]) shl 16)+(ord(S_IN[t+2]) shl 8)+ord(S_IN[t+3]);
    t
:=t+4;
 
end;
 
 
 
For t:=16 to 79 do W[t]:=ROL(W[t-3] XOR W[t-8] XOR W[t-14] XOR W[t-16],1);
 
  A
:=H0;B:=H1;C:=H2;D:=H3;E:=H4;
 
{  for t:=0 to 79 do                            // Разделить на 4 цикла !!!  * * * * * * * * * * * * * * *
   
begin
       
if (t>=0)  AND (t<=19) then  TEMP:=ROL(A,5)+((B AND C) OR ((NOT B) AND D))       +E+K1+W[t];
       
if (t>=20) AND (t<=39) then  TEMP:=ROL(A,5)+(B XOR C XOR D)                      +E+K2+W[t];
       
if (t>=40) AND (t<=59) then  TEMP:=ROL(A,5)+((B AND C) OR (B AND D) OR (C AND D))+E+K3+W[t];
       
if (t>=60) AND (t<=79) then  TEMP:=ROL(A,5)+(B XOR C XOR D)                      +E+K4+W[t];
 
        E
:=D;  D:=C;  C:=ROL(B,30);  B:=A;  A:=TEMP;
   
end;
 
}
   
for t:=0 to 19 do
   
begin
      TEMP
:=ROL(A,5)+((B AND C) OR ((NOT B) AND D))       +E+K1+W[t];
      E
:=D;  D:=C;  C:=ROL(B,30);  B:=A;  A:=TEMP;
   
end;
   
for t:=20 to 39 do
   
begin
      TEMP
:=ROL(A,5)+(B XOR C XOR D)                      +E+K2+W[t];
      E
:=D;  D:=C;  C:=ROL(B,30);  B:=A;  A:=TEMP;
   
end;
   
for t:=40 to 59 do
   
begin
      TEMP
:=ROL(A,5)+((B AND C) OR (B AND D) OR (C AND D))+E+K3+W[t];
      E
:=D;  D:=C;  C:=ROL(B,30);  B:=A;  A:=TEMP;
   
end;
   
for t:=60 to 79 do
   
begin
      TEMP
:=ROL(A,5)+(B XOR C XOR D)                      +E+K4+W[t];
      E
:=D;  D:=C;  C:=ROL(B,30);  B:=A;  A:=TEMP;
   
end;
 
   H0
:=A+H0; H1:=B+H1; H2:=C+H2; H3:=D+H3; H4:=E+H4;
//Form1.memo1.Lines.Add(inttohex(H0,8)+' '+inttohex(H1,8)+' '+inttohex(H2,8)+' '+inttohex(H3,8)+' '+inttohex(H4,8));
end;
 
 
procedure TForm1
.FormCreate(Sender: TObject);
begin
 
WindowState:=wsMaximized;
  Form1
.Memo1.Clear;
  Button2
.Enabled:=false ;
  Form1
.SaveDialog1.Filter := 'Text Files (*.txt)|*.TXT|All Files (*.*)|*.*';
  CheckBox1
.Checked:=true;
  CheckBox2
.Checked:=true;
 
Application.Title:='SHA-1';
 
Caption:='SHA-1';
end;
 
 
 
procedure
Work(Z:string);
var s,s1:string;    i,L,FS:integer;        F:file;  n:integer; Buf: array[1..65536] of char;
begin
   
Application.ProcessMessages;
   IF
StopScan then exit;
   s
:='';
   
AssignFile(F,Z);
   
FileMode := FmOpenRead;
   
Reset(F,1);
   FS
:=FileSize(F);
INIT
;
   repeat
     
BlockRead(F,Buf,sizeOf(Buf),n);
     
SetLength(s1,n);
     
For i:=1 to n do s1[i]:=Buf[i];
     
// s:=s+s1;
     s
:=s1;
     L
:=length(s1);
     IF
((L<65536) and (L>0)) then
     
begin
          s1
:= PADDING(s,FS) ;
                 i
:=1;
                 L
:=length(s1);
                 
while i<L do
                 
begin
                 START
(copy(s1,i,64));
                 i
:=i+64;
                 
end;
     
end;
 
     IF L
=65536  then begin
                 i
:=1;
                 L
:=length(s1);
                 
while i<L do
                 
begin
                 START
(copy(s1,i,64));
                 i
:=i+64;
                 
end;
 
                 
end;
 
 
     
until n=0;
   
CloseFile(F);
 
 
{
INIT
;
s
:=PADDING(s,FS) ;
L
:=length(s);
 
i
:=1;
while i<L do
     
begin
      START
(copy(s,i,64));
      i
:=i+64;
     
end;
     
}
     
Hout:=inttohex(H0,8)+' '+inttohex(H1,8)+' '+inttohex(H2,8)+' '+inttohex(H3,8)+' '+inttohex(H4,8);
      s1
:=Hout;
     
If (Form1.CheckBox1.Checked AND Form1.CheckBox2.Checked) then
          Form1
.memo1.Lines.Add(s1+'        '+inttostr(FS)+'        '+ExtractFileName(Z));
     
If NOT ((Form1.CheckBox1.Checked AND Form1.CheckBox2.Checked)) then
          Form1
.memo1.Lines.Add(s1);
     
If (Form1.CheckBox1.Checked AND NOT Form1.CheckBox2.Checked) then
          Form1
.memo1.Lines.Add(s1+'        '+inttostr(FS));
     
If (NOT Form1.CheckBox1.Checked AND Form1.CheckBox2.Checked) then
          Form1
.memo1.Lines.Add(s1+'        '+ExtractFileName(Z));
 
// abc.....opq = 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
// abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopqW = 39958831d7dd0a53e9bfba578cdf45e5ec542e8c
//abc = A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D;
//abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnop = 47B17281 0795699F E739197D 1A1F5960 700242F1
 
end;
 
procedure TForm1
.Button1Click(Sender: TObject);
begin
if Form1.OpenDialog1.Execute then
   
begin
 
     
StopScan:=false;
     
Work(OpenDialog1.FileName);
      Button2
.Enabled:=true;
   
end;
end;
 
 
Function ScanDir(Dir:string):string;
var   SearchRec:TSearchRec; //scan_result :string;
begin
Application.ProcessMessages;
IF
StopScan then exit;
if Dir<>'' then if Dir[length(Dir)]<>'\' then Dir:=Dir+'\';
 
if FindFirst(Dir+'
*.*', faAnyFile, SearchRec)=0   then
repeat
  if (SearchRec.name='
.') or (SearchRec.name='..')   then continue;
  if  ( (SearchRec.Attr and faDirectory)<>0) then
                        begin
                          IF Form1.CheckBox3.Checked then ScanDir(Dir+SearchRec.name)
                        end
  else Work(Dir+SearchRec.name);
until FindNext(SearchRec)<>0;
FindClose(SearchRec);
 
end;
 
 
procedure TForm1.Button2Click(Sender: TObject);       //Scan Button pressed
begin
  IF  Button2.Enabled=false then exit;
  StopScan:=false;
  Caption:='
Scanning ...';
  ScanDir(ExtractFileDir(Form1.OpenDialog1.FileName));
  Caption:='
SHA-1';
end;
 
procedure TForm1.FormResize(Sender: TObject);
begin
  Memo1.Height:=Height-70;
end;
 
procedure TForm1.Button3Click(Sender: TObject);
begin
If SaveDialog1.Execute then
   begin
     If FileExists(SaveDialog1.FileName) then
           IF  MessageDlg('
File'+#13+SaveDialog1.FileName+#13+'already exists!'
               +#13+#13+'
Overwrite (Yes/No) ?',mtWarning, [mbYes, mbNo], 0) = mrNo then exit;
     Memo1.Lines.SaveToFile(SaveDialog1.FileName);
 
   end;
end;
 
procedure TForm1.Button4Click(Sender: TObject);
begin
  Form1.Memo1.Clear;
end;
 
procedure TForm1.BStopClick(Sender: TObject);
begin
StopScan:=true;
end;
 
end.