Solution for day 4 part 1 and part 2
This commit is contained in:
parent
60c80cf946
commit
03f0d3ed29
209
AoC/2015/day_4/day_4.adb
Normal file
209
AoC/2015/day_4/day_4.adb
Normal file
|
|
@ -0,0 +1,209 @@
|
||||||
|
with Ada.Text_IO; use Ada.Text_IO;
|
||||||
|
with Interfaces;
|
||||||
|
|
||||||
|
procedure Day_4 is
|
||||||
|
|
||||||
|
type Uint32 is mod 2**32;
|
||||||
|
type Uint64 is mod 2**64;
|
||||||
|
type Uint128 is mod 2**128;
|
||||||
|
type Byte is range 0 .. 2**8 -1;
|
||||||
|
for Byte'Size use 8;
|
||||||
|
|
||||||
|
package Uint128_IO is new Ada.Text_IO.Modular_IO( Uint128 );
|
||||||
|
package Uint32_IO is new Ada.Text_IO.Modular_IO( Uint32 );
|
||||||
|
|
||||||
|
type Byte_Array is array (Natural range <>) of Byte;
|
||||||
|
|
||||||
|
type Uint32_Array is array (Natural range <>) of Uint32;
|
||||||
|
|
||||||
|
function Hex( Num : Uint32 ) return String is
|
||||||
|
Str : String( 1 .. 8 );
|
||||||
|
Tally : Uint32 := Num;
|
||||||
|
Temp : Uint32;
|
||||||
|
begin
|
||||||
|
for I in reverse Str'Range loop
|
||||||
|
Temp := Tally mod 16;
|
||||||
|
case Temp is
|
||||||
|
when 0 .. 9 => Str(I) := Character'Val(48 + Temp);
|
||||||
|
when 10 .. 15 => Str(I) := Character'val(65 + (Temp - 10));
|
||||||
|
when others => Str(I) := 'x';
|
||||||
|
end case;
|
||||||
|
Tally := Tally / 16;
|
||||||
|
end loop;
|
||||||
|
|
||||||
|
return Str;
|
||||||
|
end Hex;
|
||||||
|
|
||||||
|
function Pad( Key : String ) return Byte_Array is
|
||||||
|
Size : Natural := Key'Length;
|
||||||
|
Mod_Size : Natural := Size mod 64;
|
||||||
|
Pad_Size : Natural;
|
||||||
|
Original : Uint64 := Uint64(Size) * 8;
|
||||||
|
begin
|
||||||
|
|
||||||
|
if Mod_Size <= 55 then
|
||||||
|
Pad_Size := 55 - Mod_Size;
|
||||||
|
else
|
||||||
|
Pad_Size := (63 - Mod_Size) + 56;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
declare
|
||||||
|
B : Byte_Array( 0 .. Pad_Size + Size + 8);
|
||||||
|
begin
|
||||||
|
for I in Key'Range loop
|
||||||
|
B(I-1) := Byte(Character'Pos(Key(I)));
|
||||||
|
end loop;
|
||||||
|
|
||||||
|
B(Key'Last) := 16#80#;
|
||||||
|
|
||||||
|
for I in 1 .. Pad_Size loop
|
||||||
|
B(Key'Last + I) := 0;
|
||||||
|
end loop;
|
||||||
|
|
||||||
|
for I in 0 .. 7 loop
|
||||||
|
B(B'Last - (7-I)) := Byte((Original / 2**(8*I)) and 16#FF#);
|
||||||
|
end loop;
|
||||||
|
|
||||||
|
return B;
|
||||||
|
end;
|
||||||
|
|
||||||
|
end Pad;
|
||||||
|
|
||||||
|
function MD5( Key : String ) return Uint128 is
|
||||||
|
S : Uint32_Array( 0 .. 63 ) := (
|
||||||
|
7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
|
||||||
|
5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
|
||||||
|
4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
|
||||||
|
6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21
|
||||||
|
);
|
||||||
|
|
||||||
|
K : Uint32_Array( 0 .. 63 ) := (
|
||||||
|
16#d76aa478#, 16#e8c7b756#, 16#242070db#, 16#c1bdceee#,
|
||||||
|
16#f57c0faf#, 16#4787c62a#, 16#a8304613#, 16#fd469501#,
|
||||||
|
16#698098d8#, 16#8b44f7af#, 16#ffff5bb1#, 16#895cd7be#,
|
||||||
|
16#6b901122#, 16#fd987193#, 16#a679438e#, 16#49b40821#,
|
||||||
|
16#f61e2562#, 16#c040b340#, 16#265e5a51#, 16#e9b6c7aa#,
|
||||||
|
16#d62f105d#, 16#02441453#, 16#d8a1e681#, 16#e7d3fbc8#,
|
||||||
|
16#21e1cde6#, 16#c33707d6#, 16#f4d50d87#, 16#455a14ed#,
|
||||||
|
16#a9e3e905#, 16#fcefa3f8#, 16#676f02d9#, 16#8d2a4c8a#,
|
||||||
|
16#fffa3942#, 16#8771f681#, 16#6d9d6122#, 16#fde5380c#,
|
||||||
|
16#a4beea44#, 16#4bdecfa9#, 16#f6bb4b60#, 16#bebfbc70#,
|
||||||
|
16#289b7ec6#, 16#eaa127fa#, 16#d4ef3085#, 16#04881d05#,
|
||||||
|
16#d9d4d039#, 16#e6db99e5#, 16#1fa27cf8#, 16#c4ac5665#,
|
||||||
|
16#f4292244#, 16#432aff97#, 16#ab9423a7#, 16#fc93a039#,
|
||||||
|
16#655b59c3#, 16#8f0ccc92#, 16#ffeff47d#, 16#85845dd1#,
|
||||||
|
16#6fa87e4f#, 16#fe2ce6e0#, 16#a3014314#, 16#4e0811a1#,
|
||||||
|
16#f7537e82#, 16#bd3af235#, 16#2ad7d2bb#, 16#eb86d391#
|
||||||
|
);
|
||||||
|
|
||||||
|
A0 : Uint32 := 16#67452301#;
|
||||||
|
B0 : Uint32 := 16#efcdab89#;
|
||||||
|
C0 : Uint32 := 16#98badcfe#;
|
||||||
|
D0 : Uint32 := 16#10325476#;
|
||||||
|
|
||||||
|
Data : Byte_Array := Pad(Key);
|
||||||
|
|
||||||
|
Output : Uint128 := 0;
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
for I in 0 .. (Data'Length / 64) - 1 loop
|
||||||
|
declare
|
||||||
|
M : Uint32_Array( 0 .. 15 );
|
||||||
|
A : Uint32 := A0;
|
||||||
|
B : Uint32 := B0;
|
||||||
|
C : Uint32 := C0;
|
||||||
|
D : Uint32 := D0;
|
||||||
|
F : Uint32;
|
||||||
|
G : Uint32;
|
||||||
|
begin
|
||||||
|
for J in 0 .. 15 loop
|
||||||
|
declare
|
||||||
|
Index : Integer := (I*64) + (J*4);
|
||||||
|
begin
|
||||||
|
M(J) := Uint32(Data(Index));
|
||||||
|
M(J) := @ + Uint32(Data(Index + 1)) * 2**8;
|
||||||
|
M(J) := @ + Uint32(Data(Index + 2)) * 2**16;
|
||||||
|
M(J) := @ + Uint32(Data(Index + 3)) * 2**24;
|
||||||
|
end;
|
||||||
|
end loop;
|
||||||
|
|
||||||
|
|
||||||
|
for J in 0 .. 63 loop
|
||||||
|
if J >= 0 and J <= 15 then
|
||||||
|
F := (B and C) or ((not B) and D);
|
||||||
|
G := Uint32(J);
|
||||||
|
elsif J >= 16 and J <= 31 then
|
||||||
|
F := (D and B) or ((not D) and C);
|
||||||
|
G := (5*Uint32(J) + 1) mod 16;
|
||||||
|
elsif J >= 32 and J <= 47 then
|
||||||
|
F := B xor C xor D;
|
||||||
|
G := (3*Uint32(J) + 5) mod 16;
|
||||||
|
else
|
||||||
|
F := C xor (B or (not D));
|
||||||
|
G := (7*Uint32(J)) mod 16;
|
||||||
|
end if;
|
||||||
|
F := F + A + K(J) + M(Integer(G));
|
||||||
|
A := D;
|
||||||
|
D := C;
|
||||||
|
C := B;
|
||||||
|
B := B + Uint32(
|
||||||
|
Interfaces.Rotate_Left(
|
||||||
|
Interfaces.Unsigned_32(F), Natural(S(J))));
|
||||||
|
|
||||||
|
end loop;
|
||||||
|
|
||||||
|
A0 := @ + A;
|
||||||
|
B0 := @ + B;
|
||||||
|
C0 := @ + C;
|
||||||
|
D0 := @ + D;
|
||||||
|
end;
|
||||||
|
end loop;
|
||||||
|
|
||||||
|
declare
|
||||||
|
Output_Arr : Uint32_Array := [A0, B0, C0, D0];
|
||||||
|
begin
|
||||||
|
for I in 0 .. 3 loop
|
||||||
|
declare
|
||||||
|
Nibble : Uint32 := Output_Arr(I);
|
||||||
|
begin
|
||||||
|
for J in 0 .. 3 loop
|
||||||
|
Output := (@ * 2**8) + Uint128(Nibble mod 2**8);
|
||||||
|
Nibble := @ / 2**8;
|
||||||
|
end loop;
|
||||||
|
end;
|
||||||
|
end loop;
|
||||||
|
end;
|
||||||
|
|
||||||
|
return Output;
|
||||||
|
|
||||||
|
end MD5;
|
||||||
|
|
||||||
|
Base_Key : String := "yzbqklnj";
|
||||||
|
Index : Positive := 1;
|
||||||
|
|
||||||
|
MD5_Hash : Uint128;
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
Uint128_IO.Put(MD5("a"), Base => 16);
|
||||||
|
New_Line;
|
||||||
|
|
||||||
|
loop
|
||||||
|
declare
|
||||||
|
Num : String := Index'Image;
|
||||||
|
begin
|
||||||
|
Put_Line("Testing: " & Base_Key & Num(Num'First + 1 .. Num'Last));
|
||||||
|
MD5_Hash := MD5(Base_Key & Num( Num'First + 1 .. Num'Last));
|
||||||
|
Uint128_IO.Put(MD5_Hash, Base => 16);
|
||||||
|
New_Line;
|
||||||
|
end;
|
||||||
|
|
||||||
|
exit when (MD5_Hash and 16#FFFFFF00000000000000000000000000#) = 0;
|
||||||
|
|
||||||
|
Index := @ + 1;
|
||||||
|
end loop;
|
||||||
|
|
||||||
|
Put_Line("Key is" & Index'Image);
|
||||||
|
|
||||||
|
end Day_4;
|
||||||
Loading…
Reference in New Issue
Block a user