次のようにコードをコピーします。
ユニットMD5;
インタフェース
用途
ウィンドウ、メッセージ、SysUtils、バリアント、クラス、グラフィックス、コントロール、フォーム、
ダイアログ、StdCtrls;
タイプ
MD5Count = DWORD の配列 [0 .. 1];
MD5State = DWORD の配列 [0 .. 3];
MD5Block = DWORD の配列 [0 .. 15];
MD5CBits = バイトの配列 [0 .. 7]。
MD5Digest = バイトの配列 [0 .. 15]。
MD5Buffer = バイトの配列 [0 .. 63]。
MD5Context = レコード
状態: MD5状態;
カウント: MD5カウント;
バッファ: MD5バッファ;
終わり;
プロシージャ MD5Init(var Context: MD5Context);
プロシージャ MD5Update(var コンテキスト: MD5Context; 入力: PAnsiChar;
長さ: ロングワード);
プロシージャ MD5Final(var Context: MD5Context; var Digest: MD5Digest);
関数 MD5File(N: 文字列): MD5Digest;
関数 MD5Print(D: MD5Digest): AnsiString;
関数 MD5F(ファイル名: AnsiString): AnsiString;
関数 MD5S(Str: AnsiString): AnsiString;
// MD5F はファイルの MD5 値を計算するために使用され、MD5S は文字列の MD5 値を計算するために使用されます。
変数
パディング: MD5Buffer = ($80, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
$00、$00、$00、$00、$00、$00、$00、$00、$00、$00、$00、$00、$00、$00、$00、
$00、$00、$00、$00、$00、$00、$00、$00、$00、$00、$00、$00、$00、$00、$00、
$00、$00、$00、$00、$00、$00、$00、$00、$00、$00、$00、$00、$00、$00、$00、
$00、$00、$00、$00、$00、$00、$00、$00);
実装
関数 F(x, y, z: DWORD): DWORD;
始める
結果:= (x と y) または ((x と z ではない);
終わり;
関数 G(x, y, z: DWORD): DWORD;
始める
結果:= (x と z) または (y と (z ではない));
終わり;
関数 H(x, y, z: DWORD): DWORD;
始める
結果:= x xor y xor z;
終わり;
関数 I(x, y, z: DWORD): DWORD;
始める
結果 := y xor (x or (z ではない));
終わり;
プロシージャ rot(var x: DWORD; N: バイト);
始める
x := (x shl N) または (x shr (32 - N));
終わり;
プロシージャ FF(var a: DWORD; b, c, D, x: DWORD; s: バイト; ac: DWORD);
始める
inc(a, F(b, c, D) + x + ac);
rot(a, s);
inc(a, b);
終わり;
プロシージャ GG(var a: DWORD; b, c, D, x: DWORD; s: バイト; ac: DWORD);
始める
inc(a, G(b, c, D) + x + ac);
rot(a, s);
inc(a, b);
終わり;
プロシージャ HH(var a: DWORD; b, c, D, x: DWORD; s: バイト; ac: DWORD);
始める
inc(a, H(b, c, D) + x + ac);
rot(a, s);
inc(a, b);
終わり;
プロシージャ II(var a: DWORD; b, c, D, x: DWORD; s: バイト; ac: DWORD);
始める
inc(a, I(b, c, D) + x + ac);
rot(a, s);
inc(a, b);
終わり;
プロシージャ Encode(ソース、ターゲット: ポインタ; カウント: ロングワード);
変数
s:Pバイト;
T: PDワード;
私:ロングワード。
始める
s := ソース;
T := ターゲット;
for I := 1 to Count div 4 do
始める
T^ := s^;
株式会社;
T^ := T^ または (s^ shl 8);
株式会社;
T^ := T^ または (s^ shl 16);
株式会社;
T^ := T^ または (s^ shl 24);
株式会社;
inc(T);
終わり;
終わり;
プロシージャ Decode(ソース、ターゲット: ポインタ; カウント: ロングワード);
変数
s: PDWORD;
T: Pバイト;
私:ロングワード。
始める
s := ソース;
T := ターゲット;
for I := 1 から Count do
始める
T^ := s^ と $FF;
inc(T);
T^ := (s^ shr 8) および $FF;
inc(T);
T^ := (s^ shr 16) および $FF;
inc(T);
T^ := (s^ shr 24) および $FF;
inc(T);
株式会社;
終わり;
終わり;
プロシージャ Transform(バッファ: ポインタ; var State: MD5State);
変数
a、b、c、D: DWORD;
ブロック: MD5ブロック;
始める
エンコード(バッファ、@ブロック、64);
a := 状態[0];
b := 状態[1];
c := 状態[2];
D := 状態[3];
FF(a, b, c, D, ブロック[0], 7, $D76AA478);
FF(D, a, b, c, ブロック[1], 12, $E8C7B756);
FF(c, D, a, b, ブロック[2], 17, $242070DB);
FF(b, c, D, a, ブロック[3], 22, $C1BDCEEE);
FF(a, b, c, D, ブロック[4], 7, $F57C0FAF);
FF(D, a, b, c, ブロック[5], 12, $4787C62A);
FF(c, D, a, b, ブロック[6], 17, $A8304613);
FF(b, c, D, a, ブロック[7], 22, $FD469501);
FF(a, b, c, D, ブロック[8], 7, $698098D8);
FF(D, a, b, c, ブロック[9], 12, $8B44F7AF);
FF(c, D, a, b, ブロック[10], 17, $FFFF5BB1);
FF(b, c, D, a, ブロック[11], 22, $895CD7BE);
FF(a, b, c, D, ブロック[12], 7, $6B901122);
FF(D, a, b, c, ブロック[13], 12, $FD987193);
FF(c, D, a, b, ブロック[14], 17, $A679438E);
FF(b, c, D, a, ブロック[15], 22, $49B40821);
GG(a, b, c, D, ブロック[1], 5, $F61E2562);
GG(D, a, b, c, ブロック[6], 9, $C040B340);
GG(c, D, a, b, ブロック[11], 14, $265E5A51);
GG(b, c, D, a, ブロック[0], 20, $E9B6C7AA);
GG(a, b, c, D, ブロック[5], 5, $D62F105D);
GG(D, a, b, c, ブロック[10], 9, $2441453);
GG(c, D, a, b, ブロック[15], 14, $D8A1E681);
GG(b, c, D, a, ブロック[4], 20, $E7D3FBC8);
GG(a, b, c, D, ブロック[9], 5, $21E1CDE6);
GG(D, a, b, c, ブロック[14], 9, $C33707D6);
GG(c, D, a, b, ブロック[3], 14, $F4D50D87);
GG(b, c, D, a, ブロック[8], 20, $455A14ED);
GG(a, b, c, D, ブロック[13], 5, $A9E3E905);
GG(D, a, b, c, ブロック[2], 9, $FCEFA3F8);
GG(c, D, a, b, ブロック[7], 14, $676F02D9);
GG(b, c, D, a, ブロック[12], 20, $8D2A4C8A);
HH(a, b, c, D, ブロック[5], 4, $FFFA3942);
HH(D, a, b, c, ブロック[8], 11, $8771F681);
HH(c, D, a, b, ブロック[11], 16, $6D9D6122);
HH(b, c, D, a, ブロック[14], 23, $FDE5380C);
HH(a, b, c, D, ブロック[1], 4, $A4BEEA44);
HH(D, a, b, c, ブロック[4], 11, $4BDECFA9);
HH(c, D, a, b, ブロック[7], 16, $F6BB4B60);
HH(b, c, D, a, ブロック[10], 23, $BEBFBC70);
HH(a, b, c, D, ブロック[13], 4, $289B7EC6);
HH(D, a, b, c, ブロック[0], 11, $EAA127FA);
HH(c, D, a, b, ブロック[3], 16, $D4EF3085);
HH(b, c, D, a, ブロック[6], 23, $4881D05);
HH(a, b, c, D, ブロック[9], 4, $D9D4D039);
HH(D, a, b, c, ブロック[12], 11, $E6DB99E5);
HH(c, D, a, b, ブロック[15], 16, $1FA27CF8);
HH(b, c, D, a, ブロック[2], 23, $C4AC5665);
II(a, b, c, D, ブロック[0], 6, $F4292244);
II(D, a, b, c, ブロック[7], 10, $432AFF97);
II(c, D, a, b, ブロック[14], 15, $AB9423A7);
II(b, c, D, a, ブロック[5], 21, $FC93A039);
II(a, b, c, D, ブロック[12], 6, $655B59C3);
II(D, a, b, c, ブロック[3], 10, $8F0CCC92);
II(c, D, a, b, ブロック[10], 15, $FFEFF47D);
II(b, c, D, a, ブロック[1], 21, $85845DD1);
II(a、b、c、D、ブロック[8]、6、$6FA87E4F);
II(D, a, b, c, ブロック[15], 10, $FE2CE6E0);
II(c, D, a, b, ブロック[6], 15, $A3014314);
II(b, c, D, a, ブロック[13], 21, $4E0811A1);
II(a, b, c, D, ブロック[4], 6, $F7537E82);
II(D, a, b, c, ブロック[11], 10, $BD3AF235);
II(c, D, a, b, ブロック[2], 15, $2AD7D2BB);
II(b, c, D, a, ブロック[9], 21, $EB86D391);
inc(状態[0], a);
inc(状態[1], b);
inc(状態[2], c);
inc(状態[3], D);
終わり;
プロシージャ MD5Init(var Context: MD5Context);
始める
コンテキストを使用して行う
始める
状態[0] := $67452301;
状態[1] := $EFCDAB89;
状態[2] := $98BADCFE;
状態[3] := $10325476;
カウント[0] := 0;
カウント[1] := 0;
ZeroMemory(@Buffer, SizeOf(MD5Buffer));
終わり;
終わり;
プロシージャ MD5Update(var コンテキスト: MD5Context; 入力: PAnsiChar;
長さ: ロングワード);
変数
インデックス: ロングワード;
PartLen: ロングワード;
私:ロングワード。
始める
コンテキストを使用して行う
始める
インデックス := (Count[0] shr 3) および $3F;
inc(カウント[0], 長さshl 3);
if Count[0] < (長さ shl 3) then
inc(カウント[1]);
inc(カウント[1], 長さ 29);
終わり;
PartLen := 64 - インデックス;
長さ >= PartLen の場合
始める
CopyMemory(@Context.Buffer[インデックス], 入力, PartLen);
Transform(@Context.Buffer, Context.State);
I := PartLen;
while I + 63 < 長さ do
始める
Transform(@Input[I], Context.State);
inc(I, 64);
終わり;
インデックス := 0;
終わり
それ以外
I := 0;
CopyMemory(@Context.Buffer[インデックス], @Input[I], 長さ - I);
終わり;
プロシージャ MD5Final(var Context: MD5Context; var Digest: MD5Digest);
変数
ビット: MD5CBits;
インデックス: ロングワード;
PadLen: ロングワード;
始める
デコード(@Context.Count, @Bits, 2);
インデックス := (Context.Count[0] shr 3) および $3F;
インデックス < 56 の場合
PadLen := 56 - インデックス
それ以外
PadLen := 120 - インデックス;
MD5Update(コンテキスト、@PADDING、PadLen);
MD5Update(コンテキスト、@ビット、8);
デコード(@Context.State, @Digest, 4);
ZeroMemory(@Context, SizeOf(MD5Context));
終わり;
関数 MD5String(M: AnsiString): MD5Digest;
変数
コンテキスト: MD5コンテキスト;
始める
MD5Init(コンテキスト);
MD5Update(コンテキスト、PAnsiChar(M)、長さ(M));
MD5Final(コンテキスト、結果);
終わり;
関数 MD5File(N: 文字列): MD5Digest;
変数
ファイルハンドル: THandle;
マップハンドル: THandle;
ViewPointer: ポインタ;
コンテキスト: MD5コンテキスト;
始める
MD5Init(コンテキスト);
FileHandle := CreateFile(P WideChar( WideString(N)) 、 GENERIC_READ 、
FILE_SHARE_READ または FILE_SHARE_WRITE、nil、OPEN_EXISTING、
FILE_ATTRIBUTE_NORMAL または FILE_FLAG_SEQUENTIAL_SCAN、0);
if ファイルハンドル <> INVALID_HANDLE_VALUE then
試す
MapHandle := CreateFileMapping(FileHandle, nil, PAGE_READONLY, 0, 0, nil);
if MapHandle <> 0 then
試す
ViewPointer := MapViewOfFile(MapHandle, FILE_MAP_READ, 0, 0, 0);
ViewPointer <> nil の場合
試す
MD5Update(Context, ViewPointer, GetFileSize(FileHandle, nil));
ついに
UnmapViewOfFile(ViewPointer);
終わり;
ついに
CloseHandle(MapHandle);
終わり;
ついに
CloseHandle(ファイルハンドル);
終わり;
MD5Final(コンテキスト、結果);
終わり;
関数 MD5Print(D: MD5Digest): AnsiString;
変数
私:バイト。
定数
数字: Ansichar の配列 [0 .. 15] = ('0', '1', '2', '3', '4', '5', '6', '7',
'8'、'9'、'a'、'b'、'c'、'd'、'e'、'f');
始める
結果 := '';
for I := 0 ~ 15 を実行します
結果 := 結果 + 桁[(D[I] shr 4) および $0F] + 桁[D[I] および $0F];
終わり;
関数 MD5Match(D1, D2: MD5Digest): ブール値;
変数
私:バイト。
始める
I := 0;
結果 := TRUE;
while 結果と (I < 16) do
始める
結果 := D1[I] = D2[I];
株式会社(I);
終わり;
終わり;
関数 MD5S(Str: AnsiString): AnsiString;
始める
結果 := MD5Print(MD5String(Str));
終わり;
関数 MD5F(ファイル名: AnsiString): AnsiString;
始める
結果 := MD5Print(MD5File(string(FileName)));
終わり;