summaryrefslogtreecommitdiff
path: root/plugins/Dbx_mmap_SA/Cryptors/Athena
diff options
context:
space:
mode:
authorVadim Dashevskiy <watcherhd@gmail.com>2012-05-15 10:38:20 +0000
committerVadim Dashevskiy <watcherhd@gmail.com>2012-05-15 10:38:20 +0000
commit48540940b6c28bb4378abfeb500ec45a625b37b6 (patch)
tree2ef294c0763e802f91d868bdef4229b6868527de /plugins/Dbx_mmap_SA/Cryptors/Athena
parent5c350913f011e119127baeb32a6aedeb4f0d33bc (diff)
initial commit
git-svn-id: http://svn.miranda-ng.org/main/trunk@2 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'plugins/Dbx_mmap_SA/Cryptors/Athena')
-rw-r--r--plugins/Dbx_mmap_SA/Cryptors/Athena/How to build Athena.txt11
-rw-r--r--plugins/Dbx_mmap_SA/Cryptors/Athena/UAthena.pas176
-rw-r--r--plugins/Dbx_mmap_SA/Cryptors/Athena/athena.cfg38
-rw-r--r--plugins/Dbx_mmap_SA/Cryptors/Athena/athena.dof136
-rw-r--r--plugins/Dbx_mmap_SA/Cryptors/Athena/athena.dpr112
-rw-r--r--plugins/Dbx_mmap_SA/Cryptors/Athena/athena.rc28
-rw-r--r--plugins/Dbx_mmap_SA/Cryptors/Athena/athena.resbin0 -> 916 bytes
-rw-r--r--plugins/Dbx_mmap_SA/Cryptors/Athena/make.bat13
-rw-r--r--plugins/Dbx_mmap_SA/Cryptors/Athena/md5_mod256_unit.pas64
-rw-r--r--plugins/Dbx_mmap_SA/Cryptors/Athena/md5_unit.pas212
10 files changed, 790 insertions, 0 deletions
diff --git a/plugins/Dbx_mmap_SA/Cryptors/Athena/How to build Athena.txt b/plugins/Dbx_mmap_SA/Cryptors/Athena/How to build Athena.txt
new file mode 100644
index 0000000000..deae9e767c
--- /dev/null
+++ b/plugins/Dbx_mmap_SA/Cryptors/Athena/How to build Athena.txt
@@ -0,0 +1,11 @@
+1. Obtain sources from http://delphi-miranda-plugins.googlecode.com/svn/trunk with your favorite SVN client.
+
+2. Copy Athena folder to the root directory of the abovementioned sources.
+
+3. Open Command prompt, navigate to Athena folder.
+
+4. Type: "make" (without quotes) - to build 32-bit version with Delphi 5,
+ "make fpc" - to build Free Pascal 32-bit version,
+ "make fpc64" - to build Free Pascal 64-bit version,
+ "make xe2" - to build Delphi XE2 32-bit version,
+ "make xe64" - to build Delphi XE2 64-bit version. \ No newline at end of file
diff --git a/plugins/Dbx_mmap_SA/Cryptors/Athena/UAthena.pas b/plugins/Dbx_mmap_SA/Cryptors/Athena/UAthena.pas
new file mode 100644
index 0000000000..15a9674e0c
--- /dev/null
+++ b/plugins/Dbx_mmap_SA/Cryptors/Athena/UAthena.pas
@@ -0,0 +1,176 @@
+unit UAthena;
+{
+ Athena: cryptor module for Miranda SecuredMMAP Database driver
+ Copyright 2007-2008 Klyde
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+}
+
+
+interface
+uses
+ md5_unit, windows;
+Type
+ Arr = array of byte;
+ PArr = ^Arr;
+
+ Function MD5_Mod(const s: AnsiString; block_count: byte): AnsiString;
+ Procedure MakeKey(key: PArr; len: word; const pwd: AnsiString);
+ Procedure EncryptData(key: PArr; data: PByte; size: LongWord);
+ Procedure DecryptData(key: PArr; data: PByte; size: LongWord);
+
+implementation
+//==============================================================================
+Function str_back(const s: AnsiString): AnsiString;
+Var
+ i: integer;
+Begin
+ result := '';
+ for i := Length(s) downto 1 do result := result + s[i];
+end;
+//==============================================================================
+Function MD5_Mod(const s: AnsiString; block_count: byte): AnsiString;
+Var
+ s1, s2, sb : AnsiString;
+ k : word;
+Begin
+ sb := str_back(s);
+ s2 := '';
+ For k := 1 to block_count do
+ Begin
+ s1 := md5(s + sb);
+ s2 := str_back(s2 + md5(s1+sb+s2));
+ End;
+ result := s2;
+end;
+//==============================================================================
+Procedure MakeKey(key: PArr; len: word; const pwd: AnsiString);
+Var
+ s : AnsiString;
+ i : word;
+ dummy: integer;
+Begin
+ if len > 64 then Len := ((Len div 16) + 1)*16 else Len := 64;
+ SetLength(key^, Len);
+ s := MD5_mod(pwd, len div 16);
+ for i := 1 to length(s) div 2 do
+ begin
+ val('$' + copy(s, i*2 - 1, 2),key^[i-1],dummy);
+ end;
+end;
+//==============================================================================
+Procedure GetNENum(key: arr; var n1, n2: LongWord);
+Var
+ i: LongWord;
+Begin
+ n1 := 0;
+ n2 := 0;
+ for i := 0 to Length(key) - 1 do
+ Begin
+ n1 := n1 + key[i] + (i + 1)*(n1+1);
+ n2 := n2 + key[i] - (i + 1)*(n2+1);
+ end;
+ n1 := n1*2 + 1;
+ n2 := n2*2 + 3;
+end;
+
+//==============================================================================
+Procedure SimGamm(key: PArr; data: PByte; size: LongWord);
+Var
+ kg : Arr;
+ i, n1, n2 : LongWord;
+ lk, k1, k2 : word;
+Begin
+ lk := Length(key^);
+ SetLength(kg, lk);
+ for i := 0 to lk - 1 do kg[i] := key^[i];
+ GetNENum(kg, n1, n2);
+ For i := 1 to size - 1 do
+ Begin
+ if (i mod lk) = 0 then GetNENum(kg, n1, n2);
+ k1 := (i+n1+7)*n2 mod lk;
+ k2 := (i+n2+3)*n1 mod lk;
+
+ PByte(uint_ptr(data)+i)^ := PByte(uint_ptr(data)+i)^ xor kg[k1] xor kg[k2];
+
+ kg[k1] := kg[k1]*k1 + kg[k2] + i*k2;
+ kg[k2] := kg[k2]*k2 + kg[k1] + i*k1;
+ end;
+end;
+//==============================================================================
+Procedure Left(key: PArr; data: PByte; size: LongWord);
+Var
+ k : Arr;
+ i, n1, n2 : LongWord;
+ lk, k1, k2 : word;
+
+Begin
+ lk := Length(key^);
+
+ SetLength(k, lk);
+ for i := 0 to lk - 1 do k[i] := key^[i];
+ GetNENum(k, n1, n2);
+ //---------------------------------------------------------------------------
+ k1 := (n2 + lk)*n1 mod lk;
+ k2 := (n1 + lk)*n2 mod lk;
+ data^ := data^ xor k[k1] xor k[k2];
+
+ //---------------------------------------------------------------------------
+ For i := 1 to size - 1 do
+ Begin
+ k1 := (i+n1)*n2 mod lk;
+ k2 := (i+n2)*n1 mod lk;
+
+ PByte(uint_ptr(data)+i)^ := PByte(uint_ptr(data)+i)^ xor ((PByte(uint_ptr(data)+i-1)^ xor k[k1]) xor k[k2]);
+ end;
+end;
+//==============================================================================
+Procedure Right(key: PArr; data: PByte; size: LongWord);
+Var
+ k : Arr;
+ i, n1, n2 : LongWord;
+ lk, k1, k2 : word;
+Begin
+ lk := Length(key^);
+ SetLength(k, lk);
+ for i := 0 to lk - 1 do k[i] := key^[i];
+ GetNENum(k, n1, n2);
+ //---------------------------------------------------------------------------
+ For i := size - 1 downto 1 do
+ Begin
+ k1 := (i+n1)*n2 mod lk;
+ k2 := (i+n2)*n1 mod lk;
+ PByte(uint_ptr(data) + i)^ := PByte(uint_ptr(data)+i)^ xor ((PByte(uint_ptr(data) + i - 1)^ xor k[k1]) xor k[k2]);
+ end;
+ //---------------------------------------------------------------------------
+ k1 := (n2 + lk)*n1 mod lk;
+ k2 := (n1 + lk)*n2 mod lk;
+ data^ := data^ xor k[k1] xor k[k2];
+end;
+//==============================================================================
+Procedure EncryptData(key: PArr; data: PByte; size: LongWord);
+Begin
+ Left(key, data, size);
+ SimGamm(key, data, size);
+end;
+//==============================================================================
+Procedure DecryptData(key: PArr; data: PByte; size: LongWord);
+Begin
+ SimGamm(key, data, size);
+ Right(key, data, size);
+end;
+//==============================================================================
+end.
+
diff --git a/plugins/Dbx_mmap_SA/Cryptors/Athena/athena.cfg b/plugins/Dbx_mmap_SA/Cryptors/Athena/athena.cfg
new file mode 100644
index 0000000000..273efb4bc2
--- /dev/null
+++ b/plugins/Dbx_mmap_SA/Cryptors/Athena/athena.cfg
@@ -0,0 +1,38 @@
+-$A8
+-$B-
+-$C+
+-$D+
+-$E-
+-$F-
+-$G+
+-$H+
+-$I+
+-$J-
+-$K-
+-$L+
+-$M-
+-$N+
+-$O+
+-$P+
+-$Q-
+-$R-
+-$S-
+-$T-
+-$U-
+-$V+
+-$W-
+-$X+
+-$YD
+-$Z1
+-cg
+-AWinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;
+-H+
+-W+
+-M
+-$M16384,1048576
+-K$00400000
+-LE"d:\program files\borland\delphi7\Projects\Bpl"
+-LN"d:\program files\borland\delphi7\Projects\Bpl"
+-w-UNSAFE_TYPE
+-w-UNSAFE_CODE
+-w-UNSAFE_CAST
diff --git a/plugins/Dbx_mmap_SA/Cryptors/Athena/athena.dof b/plugins/Dbx_mmap_SA/Cryptors/Athena/athena.dof
new file mode 100644
index 0000000000..d43219d29e
--- /dev/null
+++ b/plugins/Dbx_mmap_SA/Cryptors/Athena/athena.dof
@@ -0,0 +1,136 @@
+[FileVersion]
+Version=7.0
+[Compiler]
+A=8
+B=0
+C=1
+D=1
+E=0
+F=0
+G=1
+H=1
+I=1
+J=0
+K=0
+L=1
+M=0
+N=1
+O=1
+P=1
+Q=0
+R=0
+S=0
+T=0
+U=0
+V=1
+W=0
+X=1
+Y=1
+Z=1
+ShowHints=1
+ShowWarnings=1
+UnitAliases=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;
+NamespacePrefix=
+SymbolDeprecated=1
+SymbolLibrary=1
+SymbolPlatform=1
+UnitLibrary=1
+UnitPlatform=1
+UnitDeprecated=1
+HResultCompat=1
+HidingMember=1
+HiddenVirtual=1
+Garbage=1
+BoundsError=1
+ZeroNilCompat=1
+StringConstTruncated=1
+ForLoopVarVarPar=1
+TypedConstVarPar=1
+AsgToTypedConst=1
+CaseLabelRange=1
+ForVariable=1
+ConstructingAbstract=1
+ComparisonFalse=1
+ComparisonTrue=1
+ComparingSignedUnsigned=1
+CombiningSignedUnsigned=1
+UnsupportedConstruct=1
+FileOpen=1
+FileOpenUnitSrc=1
+BadGlobalSymbol=1
+DuplicateConstructorDestructor=1
+InvalidDirective=1
+PackageNoLink=1
+PackageThreadVar=1
+ImplicitImport=1
+HPPEMITIgnored=1
+NoRetVal=1
+UseBeforeDef=1
+ForLoopVarUndef=1
+UnitNameMismatch=1
+NoCFGFileFound=1
+MessageDirective=1
+ImplicitVariants=1
+UnicodeToLocale=1
+LocaleToUnicode=1
+ImagebaseMultiple=1
+SuspiciousTypecast=1
+PrivatePropAccessor=1
+UnsafeType=0
+UnsafeCode=0
+UnsafeCast=0
+[Linker]
+MapFile=0
+OutputObjs=0
+ConsoleApp=1
+DebugInfo=0
+RemoteSymbols=0
+MinStackSize=16384
+MaxStackSize=1048576
+ImageBase=4194304
+ExeDescription=
+[Directories]
+OutputDir=
+UnitOutputDir=
+PackageDLLOutputDir=
+PackageDCPOutputDir=
+SearchPath=
+Packages=
+Conditionals=
+DebugSourceDirs=
+UsePackages=0
+[Parameters]
+RunParams=
+HostApplication=
+Launcher=
+UseLauncher=0
+DebugCWD=
+[Language]
+ActiveLang=
+ProjectLang=
+RootDir=
+[Version Info]
+IncludeVerInfo=0
+AutoIncBuild=0
+MajorVer=1
+MinorVer=0
+Release=0
+Build=0
+Debug=0
+PreRelease=0
+Special=0
+Private=0
+DLL=0
+Locale=1049
+CodePage=1251
+[Version Info Keys]
+CompanyName=
+FileDescription=
+FileVersion=1.0.0.0
+InternalName=
+LegalCopyright=
+LegalTrademarks=
+OriginalFilename=
+ProductName=
+ProductVersion=1.0.0.0
+Comments=
diff --git a/plugins/Dbx_mmap_SA/Cryptors/Athena/athena.dpr b/plugins/Dbx_mmap_SA/Cryptors/Athena/athena.dpr
new file mode 100644
index 0000000000..4824b9b01f
--- /dev/null
+++ b/plugins/Dbx_mmap_SA/Cryptors/Athena/athena.dpr
@@ -0,0 +1,112 @@
+library athena;
+
+{
+ Athena: cryptor module for Miranda SecuredMMAP Database driver
+ Copyright 2007-2008 Klyde
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+}
+
+uses
+ UAthena,
+ WIndows;
+
+{$R *.res}
+
+type
+ TGenerateKey = function(key: PAnsiChar): PArr; stdcall;
+ TFreeKey = procedure(key: PArr); stdcall;
+ TEncryptMem = procedure(data: PByte; size: LongWord; key: PArr); stdcall;
+
+ PCryptorInfo = ^TCryptorInfo;
+ TCryptorInfo = record
+ GenerateKey: TGenerateKey;
+ FreeKey: TFreeKey;
+
+ EncryptMem: TEncryptMem;
+ DecryptMem: TEncryptMem;
+
+ Name: PAnsiChar;
+ Info: PAnsiChar;
+ Author: PAnsiChar;
+ Site: PAnsiChar;
+ Email: PAnsiChar;
+
+ version: dword;
+
+ uid: word;
+ end;
+
+var
+ Info: TCryptorInfo;
+
+
+function PLUGIN_MAKE_VERSION(a,b,c,d: Cardinal): integer;
+begin
+ Result := (a shl 24) or (b shl 16) or (c shl 8) or d;
+end;
+
+function GenerateKey(pwd: PAnsiChar): PArr; stdcall;
+var
+ a: PArr;
+begin
+
+ new(a);
+ MakeKey(a, 512, pwd);
+ result := a;
+
+end;
+
+procedure FreeKey(key: PArr); stdcall;
+begin
+ FreeMem(key);
+end;
+
+procedure EncryptMem(data: PByte; size: LongWord; key: PArr); stdcall;
+begin
+ if size <= 0 then exit;
+ EncryptData(key, data, size);
+end;
+
+procedure DecryptMem(data: PByte; size: LongWord; key: PArr); stdcall;
+begin
+ if size <= 0 then exit;
+ DecryptData(key, data, size);
+end;
+
+function GetCryptor: PCryptorInfo; stdcall;
+begin
+ Info.Name := 'Athena';
+ Info.Author := 'Klyde';
+ Info.Site := 'http://cityopen.ru/forum/journal.php?user=151';
+ Info.Email := 'xxxmara@mail.ru';
+ Info.Info := 'Secure alghoritm developed in russian universities';
+
+ Info.version := PLUGIN_MAKE_VERSION(0,0,3,0);
+
+ Info.UID := $FEA8;
+
+ Info.GenerateKey := GenerateKey;
+ Info.FreeKey := FreeKey;
+ Info.EncryptMem := EncryptMem;
+ Info.DecryptMem := DecryptMem;
+
+ result := @Info;
+end;
+
+exports GetCryptor;
+
+begin
+end.
diff --git a/plugins/Dbx_mmap_SA/Cryptors/Athena/athena.rc b/plugins/Dbx_mmap_SA/Cryptors/Athena/athena.rc
new file mode 100644
index 0000000000..bc035ab02a
--- /dev/null
+++ b/plugins/Dbx_mmap_SA/Cryptors/Athena/athena.rc
@@ -0,0 +1,28 @@
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 0,0,3,0
+ PRODUCTVERSION 0,0,3,0
+ FILEFLAGSMASK $3F
+ FILEOS 4
+ FILETYPE 2
+ FILESUBTYPE 0
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "000004b0"
+ BEGIN
+ VALUE "CompanyName",""
+ VALUE "Comments", "Secure alghoritm developed in russian universities"0
+ VALUE "FileDescription", "Secure alghoritm developed in russian universities"0
+ VALUE "FileVersion", "0, 0, 3, 0 "0
+ VALUE "InternalName", "Athena"0
+ VALUE "OriginalFilename", "Athena.dll"0
+ VALUE "ProductName", "Athena"0
+ VALUE "ProductVersion", "0, 0, 3, 0 "0
+ VALUE "SpecialBuild", ".04.2010 "0
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation",0,1200
+ END
+END \ No newline at end of file
diff --git a/plugins/Dbx_mmap_SA/Cryptors/Athena/athena.res b/plugins/Dbx_mmap_SA/Cryptors/Athena/athena.res
new file mode 100644
index 0000000000..908733f3de
--- /dev/null
+++ b/plugins/Dbx_mmap_SA/Cryptors/Athena/athena.res
Binary files differ
diff --git a/plugins/Dbx_mmap_SA/Cryptors/Athena/make.bat b/plugins/Dbx_mmap_SA/Cryptors/Athena/make.bat
new file mode 100644
index 0000000000..bccf7a792a
--- /dev/null
+++ b/plugins/Dbx_mmap_SA/Cryptors/Athena/make.bat
@@ -0,0 +1,13 @@
+@echo off
+..\delphi\brcc32.exe athena.rc -foathena.res
+if /i '%1' == 'fpc' (
+ ..\FPC\bin\fpc.exe athena.dpr %2 %3 %4 %5 %6 %7 %8 %9
+) else if /i '%1' == 'fpc64' (
+ ..\FPC\bin64\ppcrossx64.exe athena.dpr %2 %3 %4 %5 %6 %7 %8 %9
+) else if /i '%1' == 'xe2' (
+ ..\XE2\BIN\dcc32.exe athena.dpr %2 %3 %4 %5 %6 %7 %8 %9
+) else if /i '%1' == 'xe64' (
+ ..\XE2\BIN\dcc64.exe athena.dpr %2 %3 %4 %5 %6 %7 %8 %9
+) else (
+ ..\delphi\dcc32 athena.dpr %1 %2 %3 %4 %5 %6 %7 %8 %9
+) \ No newline at end of file
diff --git a/plugins/Dbx_mmap_SA/Cryptors/Athena/md5_mod256_unit.pas b/plugins/Dbx_mmap_SA/Cryptors/Athena/md5_mod256_unit.pas
new file mode 100644
index 0000000000..53b2d996da
--- /dev/null
+++ b/plugins/Dbx_mmap_SA/Cryptors/Athena/md5_mod256_unit.pas
@@ -0,0 +1,64 @@
+unit md5_mod256_unit;
+interface
+
+Uses
+ MD5_Unit, sysutils, classes, windows;
+Const
+ MSize = 256;
+Type
+ tiAr = array [0..255] of integer;
+
+Function MD5_Mod(s: String): String;
+Function MD5_Matrix(s: string): tArr;
+Function str_back(s: String): String;
+
+implementation
+//==============================================================================
+Function str_back(s: String): String;
+Var
+ i: integer;
+Begin
+ result := '';
+ for i := Length(s) downto 1 do result := result + s[i];
+end;
+//==============================================================================
+Function MD5_Mod_back(s: String): String;
+Var
+ s1, s2 : String;
+ k : word;
+Begin
+ s1 := str_back(s)+s;
+ s2 := md5(str_back(s)+str_back(md5(s))+
+ str_back(md5(s+s))+
+ str_back(md5(s+s+s))+
+ str_back(md5(s+s+s+s))+
+ str_back(md5(s+s+s+'asddsa'+s)));
+ For k:=1 to trunc(sqrt(MSize))-1 do
+ Begin
+ s1 := md5(s1 + s2 + md5(s1+s1+s2+s) + md5(s2+s2+s1+s) + s);
+ s2 := str_back(s2 + str_back(md5(s1+s2+md5(s))));
+ End;
+ result:=s2;
+end;
+//==============================================================================
+Function MD5_Mod(s: String): String;
+Var
+ s1, s2 : String;
+ k : word;
+Begin
+ s1 := s + AnsiUpperCase(s) + AnsiLowerCase(s);
+ s2 := md5(s+md5(s)+md5(s+s)+md5(s+AnsiUpperCase(s)+s)+md5(s+AnsiLowerCase(s+s)+s)+md5(s+s+str_back(s+s+'qweewq')));
+ For k:=1 to trunc(sqrt(MSize))-1 do
+ Begin
+ s1 := md5(s1 + str_back(s2) + md5(s1+s1+s2+s) + str_back(md5(s2+s2+s1+s)) + s);
+ s2 := str_back(s2 + md5(s1+AnsiUpperCase(s2+md5(s))));
+ End;
+ result:=s2;
+end;
+//==============================================================================
+
+//==============================================================================
+end.
+
+
+
diff --git a/plugins/Dbx_mmap_SA/Cryptors/Athena/md5_unit.pas b/plugins/Dbx_mmap_SA/Cryptors/Athena/md5_unit.pas
new file mode 100644
index 0000000000..f9a130b729
--- /dev/null
+++ b/plugins/Dbx_mmap_SA/Cryptors/Athena/md5_unit.pas
@@ -0,0 +1,212 @@
+unit md5_unit;
+
+interface
+
+uses Windows;
+Type
+ TMD5 = Array [0..15] of byte;
+
+function MD5(const s: AnsiString): AnsiString;
+function MD5_arr(const s: AnsiString): TMD5;
+
+implementation
+//==============================================================================
+const
+ HexDigitChr : array [0..15] of AnsiChar = ('0','1','2','3','4','5','6','7',
+ '8','9','A','B','C','D','E','F');
+
+function Int2Hex(Value:dword;Digits:integer=0):AnsiString;
+var
+ i:cardinal;
+ buf:array [0..31] of AnsiChar;
+begin
+ if Digits<=0 then
+ begin
+ Digits:=0;
+ i:=Value;
+ repeat
+ i:=i shr 4;
+ inc(Digits);
+ until i=0;
+ end;
+
+ buf[Digits]:=#0;
+ repeat
+ Dec(Digits);
+ buf[Digits]:=AnsiChar(HexDigitChr[Value and $F]);
+ Value:=Value shr 4;
+ until Digits=0;
+ result:=buf;
+end;
+//==============================================================================
+function MD5_arr(const s: AnsiString): TMD5;
+var
+ a : TMD5;
+ LenHi, LenLo: longword;
+ Index: DWord;
+ HashBuffer : array[0..63] of byte;
+ CurrentHash : array[0..3] of DWord;
+
+ procedure Burn;
+ begin
+ LenHi:= 0; LenLo:= 0;
+ Index:= 0;
+ FillChar(HashBuffer,Sizeof(HashBuffer),0);
+ FillChar(CurrentHash,Sizeof(CurrentHash),0);
+ end;
+
+ procedure Init;
+ begin
+ Burn;
+ CurrentHash[0]:= $67452301;
+ CurrentHash[1]:= $efcdab89;
+ CurrentHash[2]:= $98badcfe;
+ CurrentHash[3]:= $10325476;
+ end;
+
+ function LRot32(a, b: longword): longword;
+ begin
+ Result:= (a shl b) or (a shr (32-b));
+ end;
+
+ procedure Compress;
+ var
+ Data : array[0..15] of dword;
+ A, B, C, D: dword;
+ begin
+ Move(HashBuffer,Data,Sizeof(Data));
+ A:= CurrentHash[0];
+ B:= CurrentHash[1];
+ C:= CurrentHash[2];
+ D:= CurrentHash[3];
+
+ A:= B + LRot32(A + (D xor (B and (C xor D))) + Data[ 0] + $d76aa478,7);
+ D:= A + LRot32(D + (C xor (A and (B xor C))) + Data[ 1] + $e8c7b756,12);
+ C:= D + LRot32(C + (B xor (D and (A xor B))) + Data[ 2] + $242070db,17);
+ B:= C + LRot32(B + (A xor (C and (D xor A))) + Data[ 3] + $c1bdceee,22);
+ A:= B + LRot32(A + (D xor (B and (C xor D))) + Data[ 4] + $f57c0faf,7);
+ D:= A + LRot32(D + (C xor (A and (B xor C))) + Data[ 5] + $4787c62a,12);
+ C:= D + LRot32(C + (B xor (D and (A xor B))) + Data[ 6] + $a8304613,17);
+ B:= C + LRot32(B + (A xor (C and (D xor A))) + Data[ 7] + $fd469501,22);
+ A:= B + LRot32(A + (D xor (B and (C xor D))) + Data[ 8] + $698098d8,7);
+ D:= A + LRot32(D + (C xor (A and (B xor C))) + Data[ 9] + $8b44f7af,12);
+ C:= D + LRot32(C + (B xor (D and (A xor B))) + Data[10] + $ffff5bb1,17);
+ B:= C + LRot32(B + (A xor (C and (D xor A))) + Data[11] + $895cd7be,22);
+ A:= B + LRot32(A + (D xor (B and (C xor D))) + Data[12] + $6b901122,7);
+ D:= A + LRot32(D + (C xor (A and (B xor C))) + Data[13] + $fd987193,12);
+ C:= D + LRot32(C + (B xor (D and (A xor B))) + Data[14] + $a679438e,17);
+ B:= C + LRot32(B + (A xor (C and (D xor A))) + Data[15] + $49b40821,22);
+
+ A:= B + LRot32(A + (C xor (D and (B xor C))) + Data[ 1] + $f61e2562,5);
+ D:= A + LRot32(D + (B xor (C and (A xor B))) + Data[ 6] + $c040b340,9);
+ C:= D + LRot32(C + (A xor (B and (D xor A))) + Data[11] + $265e5a51,14);
+ B:= C + LRot32(B + (D xor (A and (C xor D))) + Data[ 0] + $e9b6c7aa,20);
+ A:= B + LRot32(A + (C xor (D and (B xor C))) + Data[ 5] + $d62f105d,5);
+ D:= A + LRot32(D + (B xor (C and (A xor B))) + Data[10] + $02441453,9);
+ C:= D + LRot32(C + (A xor (B and (D xor A))) + Data[15] + $d8a1e681,14);
+ B:= C + LRot32(B + (D xor (A and (C xor D))) + Data[ 4] + $e7d3fbc8,20);
+ A:= B + LRot32(A + (C xor (D and (B xor C))) + Data[ 9] + $21e1cde6,5);
+ D:= A + LRot32(D + (B xor (C and (A xor B))) + Data[14] + $c33707d6,9);
+ C:= D + LRot32(C + (A xor (B and (D xor A))) + Data[ 3] + $f4d50d87,14);
+ B:= C + LRot32(B + (D xor (A and (C xor D))) + Data[ 8] + $455a14ed,20);
+ A:= B + LRot32(A + (C xor (D and (B xor C))) + Data[13] + $a9e3e905,5);
+ D:= A + LRot32(D + (B xor (C and (A xor B))) + Data[ 2] + $fcefa3f8,9);
+ C:= D + LRot32(C + (A xor (B and (D xor A))) + Data[ 7] + $676f02d9,14);
+ B:= C + LRot32(B + (D xor (A and (C xor D))) + Data[12] + $8d2a4c8a,20);
+
+ A:= B + LRot32(A + (B xor C xor D) + Data[ 5] + $fffa3942,4);
+ D:= A + LRot32(D + (A xor B xor C) + Data[ 8] + $8771f681,11);
+ C:= D + LRot32(C + (D xor A xor B) + Data[11] + $6d9d6122,16);
+ B:= C + LRot32(B + (C xor D xor A) + Data[14] + $fde5380c,23);
+ A:= B + LRot32(A + (B xor C xor D) + Data[ 1] + $a4beea44,4);
+ D:= A + LRot32(D + (A xor B xor C) + Data[ 4] + $4bdecfa9,11);
+ C:= D + LRot32(C + (D xor A xor B) + Data[ 7] + $f6bb4b60,16);
+ B:= C + LRot32(B + (C xor D xor A) + Data[10] + $bebfbc70,23);
+ A:= B + LRot32(A + (B xor C xor D) + Data[13] + $289b7ec6,4);
+ D:= A + LRot32(D + (A xor B xor C) + Data[ 0] + $eaa127fa,11);
+ C:= D + LRot32(C + (D xor A xor B) + Data[ 3] + $d4ef3085,16);
+ B:= C + LRot32(B + (C xor D xor A) + Data[ 6] + $04881d05,23);
+ A:= B + LRot32(A + (B xor C xor D) + Data[ 9] + $d9d4d039,4);
+ D:= A + LRot32(D + (A xor B xor C) + Data[12] + $e6db99e5,11);
+ C:= D + LRot32(C + (D xor A xor B) + Data[15] + $1fa27cf8,16);
+ B:= C + LRot32(B + (C xor D xor A) + Data[ 2] + $c4ac5665,23);
+
+ A:= B + LRot32(A + (C xor (B or (not D))) + Data[ 0] + $f4292244,6);
+ D:= A + LRot32(D + (B xor (A or (not C))) + Data[ 7] + $432aff97,10);
+ C:= D + LRot32(C + (A xor (D or (not B))) + Data[14] + $ab9423a7,15);
+ B:= C + LRot32(B + (D xor (C or (not A))) + Data[ 5] + $fc93a039,21);
+ A:= B + LRot32(A + (C xor (B or (not D))) + Data[12] + $655b59c3,6);
+ D:= A + LRot32(D + (B xor (A or (not C))) + Data[ 3] + $8f0ccc92,10);
+ C:= D + LRot32(C + (A xor (D or (not B))) + Data[10] + $ffeff47d,15);
+ B:= C + LRot32(B + (D xor (C or (not A))) + Data[ 1] + $85845dd1,21);
+ A:= B + LRot32(A + (C xor (B or (not D))) + Data[ 8] + $6fa87e4f,6);
+ D:= A + LRot32(D + (B xor (A or (not C))) + Data[15] + $fe2ce6e0,10);
+ C:= D + LRot32(C + (A xor (D or (not B))) + Data[ 6] + $a3014314,15);
+ B:= C + LRot32(B + (D xor (C or (not A))) + Data[13] + $4e0811a1,21);
+ A:= B + LRot32(A + (C xor (B or (not D))) + Data[ 4] + $f7537e82,6);
+ D:= A + LRot32(D + (B xor (A or (not C))) + Data[11] + $bd3af235,10);
+ C:= D + LRot32(C + (A xor (D or (not B))) + Data[ 2] + $2ad7d2bb,15);
+ B:= C + LRot32(B + (D xor (C or (not A))) + Data[ 9] + $eb86d391,21);
+
+ Inc(CurrentHash[0],A);
+ Inc(CurrentHash[1],B);
+ Inc(CurrentHash[2],C);
+ Inc(CurrentHash[3],D);
+ Index:= 0;
+ FillChar(HashBuffer,Sizeof(HashBuffer),0);
+ end;
+
+procedure Update(const Buffer; Size: longword);
+var
+ PBuf: ^byte;
+begin
+ Inc(LenHi,Size shr 29);
+ Inc(LenLo,Size*8);
+ if LenLo < (Size*8) then Inc(LenHi);
+ PBuf:= @Buffer;
+ while Size> 0 do
+ begin
+ if (Sizeof(HashBuffer)-Index)<= DWord(Size) then
+ begin
+ Move(PBuf^,HashBuffer[Index],Sizeof(HashBuffer)-Index);
+ Dec(Size,Sizeof(HashBuffer)-Index);
+ Inc(PBuf,Sizeof(HashBuffer)-Index);
+ Compress;
+ end else
+ begin
+ Move(PBuf^,HashBuffer[Index],Size);
+ Inc(Index,Size);
+ Size:= 0;
+ end;
+ end;
+end;
+
+procedure Final(var Digest);
+begin
+ HashBuffer[Index] := $80;
+ if Index >= 56 then Compress;
+ PDWord(@HashBuffer[56])^ := LenLo;
+ PDWord(@HashBuffer[60])^ := LenHi;
+ Compress;
+ Move(CurrentHash, Digest, Sizeof(CurrentHash));
+ Burn;
+end;
+
+begin
+ Init;
+ Update(s[1], Length(s));
+ Final(a);
+ result := a;
+end;
+//==============================================================================
+function MD5(const s: AnsiString): AnsiString;
+var
+ a : TMD5;
+ i : integer;
+begin
+ a := MD5_arr(s);
+ result := '';
+ for i := 0 to 15 do result := result + Int2Hex(a[i], 2);
+end;
+
+end.