From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=1.0 required=5.0 tests=BAYES_00,FILL_THIS_FORM_LOAN autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,b667898b16e99a9d X-Google-Attributes: gid103376,public From: Rolf Ebert Subject: Re: MD5 Function in Ada Date: 1997/06/04 Message-ID: X-Deja-AN: 246151434 References: <5n232a$h8s$1@news.hal-pc.org> Organization: Rolf Ebert from home Newsgroups: comp.lang.ada Date: 1997-06-04T00:00:00+00:00 List-Id: >>>>> "JG" == Jonathan Guthrie writes: JG> Is there any available source for calculating MD5 hashes in Ada? Yes, I hereby release the following code to the public domain. Run the message through gnatchop and then gnatmake md5-test. The following code is a hand coded translation to Ada of the md5 sample implementation in C from rfc1321. It is still very close to the C code with Ada syntax. I did that primarily as an excercise to learn more about Ada95 modular types and shift operations. If you want to use this code for any serious work, you should carefully reread every single line and test it extensively. Currently its speed is about 50% of the C implementation. In both versions (C and Ada) there are quite a few possibilities to improve the performance. Rolf ebert@waporo.muc.de P.S. Any feed back is welcome. -- -*- Mode: Ada -*- -- Filename : md5.ads -- Description : -- Author : Rolf Ebert -- Created On : Tue Mar 25 20:06:55 1997 -- Last Modified By: Rolf Ebert -- Last Modified On: Wed Jun 4 21:37:28 1997 -- Update Count : 24 -- Status : Unknown, Use with caution! -- $Revision$ -- $Name$ package MD5 is type Byte is mod 2**8; type Byte_Array is array (Long_Integer range <>) of Byte; pragma Pack (Byte_Array); subtype Fingerprint is Byte_Array (1 .. 16); subtype Digest_String is String (1 .. 32); Malformed : exception; function Digest_From_Text (S : in Digest_String) return Fingerprint; function Digest_To_Text (A : in Fingerprint) return Digest_String; type Context is private; procedure Init (Ctx : in out Context); procedure Update (Ctx : in out Context; Data : in Byte_Array); procedure Update (Ctx : in out Context; Data : in String); procedure Final (Ctx : in out Context; Digest : out Fingerprint); private type Word is mod 2**32; type Word_Array is array (Long_Integer range <>) of Word; pragma Pack (Word_Array); function Rotate_Left (Value : in Word; Amount : in Natural) return Word; pragma Import (Intrinsic, Rotate_Left); function Shift_Left (Value : in Word; Amount : in Natural) return Word; pragma Import (Intrinsic, Shift_Left); function Shift_Right (Value : in Word; Amount : in Natural) return Word; pragma Import (Intrinsic, Shift_Right); subtype ABCD_State is Word_Array (1 .. 4); subtype Count_T is Word_Array (1 .. 2); -- long_integer ?? subtype Buffer_T is Byte_Array (1 .. 64); type Context is record State : ABCD_State := (1 => 16#67452301#, 2 => 16#Efcdab89#, 3 => 16#98badcfe#, 4 => 16#10325476#); Count : Count_T := (1 => 0, 2 => 0); Buffer : Buffer_T := (others => 0); end record; end MD5; -- -*- Mode: Ada -*- -- Filename : md5.ads -- Description : -- Author : Rolf Ebert -- Created On : Tue Mar 25 20:06:55 1997 -- Last Modified By: Rolf Ebert -- Last Modified On: Wed Jun 4 21:41:48 1997 -- Update Count : 93 -- Status : Unknown, Use with caution! -- $Revision$ -- $Name$ with Ada.Unchecked_Conversion; package body MD5 is procedure Transform (State : in out ABCD_State; Block : in Buffer_T); procedure Encode (Output : out Byte_Array; Input : in Word_Array); procedure Decode (Output : out Word_Array; Input : in Byte_Array); -- F, G, H, I are the basic MD5 functions function F (X, Y, Z : in Word) return Word; function G (X, Y, Z : in Word) return Word; function H (X, Y, Z : in Word) return Word; function I (X, Y, Z : in Word) return Word; procedure FF (A : in out Word; B, C, D, X : in Word; S : in Natural; AC : in Word); procedure GG (A : in out Word; B, C, D, X : in Word; S : in Natural; AC : in Word); procedure HH (A : in out Word; B, C, D, X : in Word; S : in Natural; AC : in Word); procedure II (A : in out Word; B, C, D, X : in Word; S : in Natural; AC : in Word); -- function F (X, Y, Z : in Word) return Word is begin return (X and Y) or ((not X) and Z); end F; pragma Inline (F); function G (X, Y, Z : in Word) return Word is begin return (X and Z) or (Y and (not Z)); end G; pragma Inline (G); function H (X, Y, Z : in Word) return Word is begin return X xor Y xor Z; end H; pragma Inline (H); function I (X, Y, Z : in Word) return Word is begin return Y xor (X or (not Z)); end I; pragma Inline (I); -- generic -- function basic_bit_op (X, y, z : in word) return word; -- procedure generic_mang (A : in out Word; -- B, C, D, X : in Word; -- S : in Natural; -- AC : in Word); -- procedure FF (A : in out Word; B, C, D, X : in Word; S : in Natural; AC : in Word) is begin A := A + F (B, C, D) + X + AC; A := Rotate_Left (A, S); A := A + B; end FF; pragma Inline (FF); procedure GG (A : in out Word; B, C, D, X : in Word; S : in Natural; AC : in Word) is begin A := A + G (B, C, D) + X + AC; A := Rotate_Left (A, S); A := A + B; end GG; pragma Inline (GG); procedure HH (A : in out Word; B, C, D, X : in Word; S : in Natural; AC : in Word) is begin A := A + H (B, C, D) + X + AC; A := Rotate_Left (A, S); A := A + B; end HH; pragma Inline (HH); procedure II (A : in out Word; B, C, D, X : in Word; S : in Natural; AC : in Word) is begin A := A + I (B, C, D) + X + AC; A := Rotate_Left (A, S); A := A + B; end II; pragma Inline (II); -- MD5 Initialization. Begin an MD5 operation, writing a new context. procedure Init (Ctx : in out Context) is begin -- Init Ctx.Count (1) := 0; Ctx.Count (2) := 0; Ctx.State (1) := 16#67452301#; Ctx.State (2) := 16#Efcdab89#; Ctx.State (3) := 16#98badcfe#; Ctx.State (4) := 16#10325476#; Ctx.Buffer := (others => 0); end Init; procedure Update (Ctx : in out Context; Data : in Byte_Array) is I : Long_Integer; Index : Long_Integer; Part_Len : Long_Integer; begin -- Update -- compute number of bytes mod 64 Index := Long_Integer (Shift_Right (Ctx.Count (1), 3) and 16#3F#); -- update number of bits Ctx.Count (1) := Ctx.Count (1) + Shift_Left (Word (Data'Length), 3); if Ctx.Count (1) < Shift_Left (Word (Data'Length), 3) then Ctx.Count (2) := Ctx.Count (2) + 1; end if; Ctx.Count (2) := Ctx.Count (2) + Shift_Right (Word (Data'Length), 29); Part_Len := 64 - Index; -- Transform as many times as possible. if Data'Length >= Part_Len then Ctx.Buffer (Index + 1 .. Index + Part_Len) := Data (Data'First .. Data'First + Part_Len - 1); Transform (Ctx.State, Ctx.Buffer); I := Part_Len; while I + 63 < Data'Length loop Transform (Ctx.State, Data (I + 1 .. I + 64)); I := I + 64; end loop; Index := 0; else I := 0; end if; -- Buffer remaining input Ctx.Buffer (Index + 1 .. Index + Data'Length - I) := Data (I + 1 .. Data'Length); end Update; procedure Update (Ctx : in out Context; Data : in String) is subtype Constrained_Byte_Array is Byte_Array (1 .. Data'Length); subtype Constrained_String is String (1 .. Data'Length); function String_To_Byte_Array is new Ada.Unchecked_Conversion (Source => Constrained_String, Target => Constrained_Byte_Array); Data_As_Byte : Constrained_Byte_Array; begin Data_As_Byte := String_To_Byte_Array (Constrained_String (Data)); Update (Ctx, Data_As_Byte); end Update; -- MD5 finalization. Ends an MD5 message-digest operation, writing the -- message digest and zeroizing the context. procedure Final (Ctx : in out Context; Digest : out Fingerprint) is Bits : Byte_Array (1 .. 8); Index : Long_Integer; Pad_Length : Long_Integer; Padding : constant Buffer_T := (1 => 16#80#, others => 0); begin -- Final -- save number of bits Encode (Bits, Ctx.Count); -- Pad out to 56 mod 64. Index := Long_Integer (Shift_Right (Ctx.Count(1), 3) and 16#3F#); if Index < 56 then Pad_Length := 56 - Index; else Pad_Length := 120 - Index; end if; Update (Ctx, Padding (1 .. Pad_Length)); -- Append length (before padding) Update (Ctx, Bits); -- Store state in digest Encode (Digest, Ctx.State); -- Zeroize sensitive information. Ctx.State := (others => 0); Ctx.Count := (others => 0); Ctx.Buffer := (others => 0); end Final; procedure Transform (State : in out ABCD_State; Block : in Buffer_T) is S11 : constant := 7; S12 : constant := 12; S13 : constant := 17; S14 : constant := 22; S21 : constant := 5; S22 : constant := 9; S23 : constant := 14; S24 : constant := 20; S31 : constant := 4; S32 : constant := 11; S33 : constant := 16; S34 : constant := 23; S41 : constant := 6; S42 : constant := 10; S43 : constant := 15; S44 : constant := 21; A : Word := State (1); B : Word := State (2); C : Word := State (3); D : Word := State (4); X : Word_Array (0 .. 15); begin Decode (X, Block); -- Round 1 FF (A, B, C, D, X ( 0), S11, 16#D76AA478#); -- 1 FF (D, A, B, C, X ( 1), S12, 16#E8C7B756#); -- 2 FF (C, D, A, B, X ( 2), S13, 16#242070DB#); -- 3 FF (B, C, D, A, X ( 3), S14, 16#C1BDCEEE#); -- 4 FF (A, B, C, D, X ( 4), S11, 16#F57C0FAF#); -- 5 FF (D, A, B, C, X ( 5), S12, 16#4787C62A#); -- 6 FF (C, D, A, B, X ( 6), S13, 16#A8304613#); -- 7 FF (B, C, D, A, X ( 7), S14, 16#FD469501#); -- 8 FF (A, B, C, D, X ( 8), S11, 16#698098D8#); -- 9 FF (D, A, B, C, X ( 9), S12, 16#8B44F7AF#); -- 10 FF (C, D, A, B, X (10), S13, 16#FFFF5BB1#); -- 11 FF (B, C, D, A, X (11), S14, 16#895CD7BE#); -- 12 FF (A, B, C, D, X (12), S11, 16#6B901122#); -- 13 FF (D, A, B, C, X (13), S12, 16#FD987193#); -- 14 FF (C, D, A, B, X (14), S13, 16#A679438E#); -- 15 FF (B, C, D, A, X (15), S14, 16#49B40821#); -- 16 -- Round 2 GG (A, B, C, D, X ( 1), S21, 16#F61E2562#); -- 17 GG (D, A, B, C, X ( 6), S22, 16#C040B340#); -- 18 GG (C, D, A, B, X (11), S23, 16#265E5A51#); -- 19 GG (B, C, D, A, X ( 0), S24, 16#E9B6C7AA#); -- 20 GG (A, B, C, D, X ( 5), S21, 16#D62F105D#); -- 21 GG (D, A, B, C, X (10), S22, 16#2441453#); -- 22 GG (C, D, A, B, X (15), S23, 16#D8A1E681#); -- 23 GG (B, C, D, A, X ( 4), S24, 16#E7D3FBC8#); -- 24 GG (A, B, C, D, X ( 9), S21, 16#21E1CDE6#); -- 25 GG (D, A, B, C, X (14), S22, 16#C33707D6#); -- 26 GG (C, D, A, B, X ( 3), S23, 16#F4D50D87#); -- 27 GG (B, C, D, A, X ( 8), S24, 16#455A14ED#); -- 28 GG (A, B, C, D, X (13), S21, 16#A9E3E905#); -- 29 GG (D, A, B, C, X ( 2), S22, 16#FCEFA3F8#); -- 30 GG (C, D, A, B, X ( 7), S23, 16#676F02D9#); -- 31 GG (B, C, D, A, X (12), S24, 16#8D2A4C8A#); -- 32 -- Round 3 HH (A, B, C, D, X ( 5), S31, 16#FFFA3942#); -- 33 HH (D, A, B, C, X ( 8), S32, 16#8771F681#); -- 34 HH (C, D, A, B, X (11), S33, 16#6D9D6122#); -- 35 HH (B, C, D, A, X (14), S34, 16#FDE5380C#); -- 36 HH (A, B, C, D, X ( 1), S31, 16#A4BEEA44#); -- 37 HH (D, A, B, C, X ( 4), S32, 16#4BDECFA9#); -- 38 HH (C, D, A, B, X ( 7), S33, 16#F6BB4B60#); -- 39 HH (B, C, D, A, X (10), S34, 16#BEBFBC70#); -- 40 HH (A, B, C, D, X (13), S31, 16#289B7EC6#); -- 41 HH (D, A, B, C, X ( 0), S32, 16#EAA127FA#); -- 42 HH (C, D, A, B, X ( 3), S33, 16#D4EF3085#); -- 43 HH (B, C, D, A, X ( 6), S34, 16#4881D05#); -- 44 HH (A, B, C, D, X ( 9), S31, 16#D9D4D039#); -- 45 HH (D, A, B, C, X (12), S32, 16#E6DB99E5#); -- 46 HH (C, D, A, B, X (15), S33, 16#1FA27CF8#); -- 47 HH (B, C, D, A, X ( 2), S34, 16#C4AC5665#); -- 48 -- Round 4 II (A, B, C, D, X ( 0), S41, 16#F4292244#); -- 49 II (D, A, B, C, X ( 7), S42, 16#432AFF97#); -- 50 II (C, D, A, B, X (14), S43, 16#AB9423A7#); -- 51 II (B, C, D, A, X ( 5), S44, 16#FC93A039#); -- 52 II (A, B, C, D, X (12), S41, 16#655B59C3#); -- 53 II (D, A, B, C, X ( 3), S42, 16#8F0CCC92#); -- 54 II (C, D, A, B, X (10), S43, 16#FFEFF47D#); -- 55 II (B, C, D, A, X ( 1), S44, 16#85845DD1#); -- 56 II (A, B, C, D, X ( 8), S41, 16#6FA87E4F#); -- 57 II (D, A, B, C, X (15), S42, 16#FE2CE6E0#); -- 58 II (C, D, A, B, X ( 6), S43, 16#A3014314#); -- 59 II (B, C, D, A, X (13), S44, 16#4E0811A1#); -- 60 II (A, B, C, D, X ( 4), S41, 16#F7537E82#); -- 61 II (D, A, B, C, X (11), S42, 16#BD3AF235#); -- 62 II (C, D, A, B, X ( 2), S43, 16#2AD7D2BB#); -- 63 II (B, C, D, A, X ( 9), S44, 16#EB86D391#); -- 64 State (1) := State (1) + A; State (2) := State (2) + B; State (3) := State (3) + C; State (4) := State (4) + D; -- Zeroize sensitive information. X := (others => 0); end Transform; -- Encodes input into output procedure Encode (Output : out Byte_Array; Input : in Word_Array) is J : Long_Integer; begin -- if Output'Length / 4 /= Input'Length then -- raise Constraint_Error; -- end if; J := Output'First; for I in Input'range loop Output (J) := Byte (Input (I) and 16#FF#); Output (J + 1) := Byte (Shift_Right (Input (I), 8) and 16#FF#); Output (J + 2) := Byte (Shift_Right (Input (I), 16) and 16#FF#); Output (J + 3) := Byte (Shift_Right (Input (I), 24) and 16#FF#); J := J + 4; end loop; end Encode; -- Decodes input into output. procedure Decode (Output : out Word_Array; Input : in Byte_Array) is J : Long_Integer; begin -- if Output'Length /= Input'Length / 4 then -- raise Constraint_Error; -- end if; J := Input'First; for I in Output'range loop Output (I) := Word (Input (J)) or Shift_Left (Word (Input (J+1)), 8) or Shift_Left (Word (Input (J+2)), 16) or Shift_Left (Word (Input (J+3)), 24); J := J + 4; end loop; end Decode; type Conv_Array is array (0 .. 15) of Character; Hex_Tab : constant Conv_Array := "0123456789abcdef"; function Digest_From_Text (S : in Digest_String) return Fingerprint is Digest : Fingerprint; Val : Word; Ch : Character; begin for I in Digest'range loop Ch := S (2 * Integer (I)); case Ch is when '0' .. '9' => Val := Character'Pos (Ch) - Character'Pos ('0'); when 'a' .. 'f' => Val := Character'Pos (Ch) - Character'Pos ('a') + 10; when 'A' .. 'F' => Val := Character'Pos (Ch) - Character'Pos ('A') + 10; when others => raise Malformed; end case; Val := Shift_Left (Val, 4); Ch := S (2 * Integer (I) + 1); case Ch is when '0' .. '9' => Val := Val + (Character'Pos (Ch) - Character'Pos ('0')); when 'a' .. 'f' => Val := Val + (Character'Pos (Ch) - Character'Pos ('a') + 10); when 'A' .. 'F' => Val := Val + (Character'Pos (Ch) - Character'Pos ('A') + 10); when others => raise Malformed; end case; Digest (I) := Byte (Val); end loop; return Digest; end Digest_From_Text; function Digest_To_Text (A : in Fingerprint) return Digest_String is Str : Digest_String; J : Positive; begin for I in A'range loop J := 2 * Integer (I) - 1; Str (J) := Hex_Tab (Natural (Shift_Right (Word (A (I)), 4))); Str (J + 1) := Hex_Tab (Natural (A (I) and 16#F#)); end loop; return Str; end Digest_To_Text; end MD5; -- -*- Mode: Ada -*- -- Filename : md5-driver.ads -- Description : -- Author : R. Ebert -- Created On : Wed Mar 26 12:37:44 1997 -- Last Modified By: Rolf Ebert -- Last Modified On: Wed Jun 4 21:43:09 1997 -- Update Count : 20 -- Status : Unknown, Use with caution! -- CVS : $Id$ -- Release : $Name$ with Ada.Calendar; with Ada.Text_IO; package body MD5.Driver is procedure Text (S : in String) is use Ada.Text_IO; C : Context; FP : Fingerprint; begin -- Text Init (C); Update (C, S); Final (C, FP); Put ("MD5 ("""); Put (S); Put (""") = "); Put (Digest_To_Text (FP)); New_Line; end Text; procedure Time_Trial is use Ada.Text_IO; use Ada.Calendar; C : Context; FP : Fingerprint; Test_Block_Len : constant := 1000; Test_Block_Count : constant := 10_000; Block : Byte_Array (1 .. Test_Block_Len); Start : Time; Stop : Time; Dur : Long_Float; begin Put ("MD5 time trial. Digesting" & Test_Block_Count'Img & Test_Block_Len'Img & "-byte blocks ..."); -- Initialize block */ for I in Block'range loop Block (I) := Byte (I) and 16#FF#; end loop; -- start timer Start := Clock; -- digest blocks Init (C); for I in 1 .. TEST_BLOCK_COUNT loop Update (C, Block); end loop; Final (C, Fp); -- stop timer Stop := Clock; Put_Line (" done"); Put_Line ("Digest = " & Digest_To_Text (Fp)); Dur := Long_Float (Stop - Start); Put_Line ("Time = " & Dur'Img & " seconds"); Dur := Long_Float (TEST_BLOCK_LEN * TEST_BLOCK_COUNT) / Dur; Put_Line ("Speed = " & Dur'Img & " bytes/second"); end Time_Trial; procedure Test_Suite is begin Ada.Text_IO.Put_Line ("MD5 test suite:"); Text (""); Text ("a"); Text ("abc"); Text ("message digest"); Text ("abcdefghijklmnopqrstuvwxyz"); Text ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"); Text ("12345678901234567890123456789012345678901234567890123456789012345678901234567890"); Text ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012345678912345678901234567890123456789012345678901234567890123456789012345678901234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"); Text ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" & "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" & "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012345678912345678901234567890123456789012345678901234567890123456789012345678901234567890"); Text ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRS" & "TUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv" & "wxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012345678912345678901234567890123456789012345678901234567890123456789012345678901234567" & "890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" & "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012" & "3456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012345678912345678901234567890123456789012345678901234567890123456789012345678901234567890ABCD" & "EFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefg" & "hijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" & "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012345678912345678901234567890123456789012345678901234567890123456789012345678901234567890"); end Test_Suite; procedure File (Filename : in String) is begin -- File null; end File; procedure Filter is begin null; end Filter; end MD5.Driver; -- -*- Mode: Ada -*- -- Filename : md5-driver.ads -- Description : -- Author : R. Ebert -- Created On : Wed Mar 26 12:37:44 1997 -- Last Modified By: Rolf Ebert -- Last Modified On: Wed Jun 4 21:42:08 1997 -- Update Count : 2 -- Status : Unknown, Use with caution! -- CVS : $Id$ -- Release : $Name$ package MD5.Driver is procedure Text (S : in String); procedure Time_Trial; procedure Test_Suite; procedure File (Filename : in String); procedure Filter; end MD5.Driver; -- -*- Mode: Ada -*- -- Filename : md5-test.adb -- Description : -- Author : R. Ebert -- Created On : Wed Mar 26 12:17:15 1997 -- Last Modified By: Rolf Ebert -- Last Modified On: Wed Jun 4 21:44:27 1997 -- Update Count : 10 -- Status : Unknown, Use with caution! -- CVS : $Id$ -- Release : $Name$ with Ada.Command_Line; with MD5.Driver; procedure MD5.Test is use Ada.Command_Line; I : Natural; begin if Argument_Count > 0 then I := 1; while I <= Argument_Count loop if Argument (I)(1..2) = "-s" then MD5.Driver.Text (Argument (I + 1)); I := I + 1; elsif Argument (I) = "-t" then MD5.Driver.Time_Trial; elsif Argument (I) = "-x" then MD5.Driver.Test_Suite; else MD5.Driver.File (Argument (I)); end if; I := I + 1; end loop; else MD5.Driver.Filter; end if; end MD5.Test; -- -*- Mode: Ada -*- -- Filename : md5-test.ads -- Description : -- Author : R. Ebert -- Created On : Wed Mar 26 12:17:15 1997 -- Last Modified By: Rolf Ebert -- Last Modified On: Wed Jun 4 21:43:30 1997 -- Update Count : 1 -- Status : Unknown, Use with caution! -- CVS : $Id$ -- Release : $Name$ procedure MD5.Test; MD5 test suite: MD5 ("") = d41d8cd98f00b204e9800998ecf8427e MD5 ("a") = 0cc175b9c0f1b6a831c399e269772661 MD5 ("abc") = 900150983cd24fb0d6963f7d28e17f72 MD5 ("message digest") = f96b697d7cb7938d525a2f31aaf161d0 MD5 ("abcdefghijklmnopqrstuvwxyz") = c3fcd3d76192e4007dfb496cca67e13b MD5 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") = d174ab98d277d9f5a5611c2c9f419d9f MD5 ("12345678901234567890123456789012345678901234567890123456789012345678901234567890") = 57edf4a22be3c955ac49da2e2107b67a