Question

I am using GNAT.SHA1 to create a SHA1 hash of a string in Ada. My code base is small, so I'd like to avoid importing any libraries to the project that aren't provided by my compiler, hence I'm using GNAT.SHA1. As far as I'm aware, the only "public" methods for retrieving the hash is in String form via the Digest function. I would like to instead get the 160-bit block that is the H member of the Context type. Unfortunately, the Context record is private. Is there any way I can get at it? Or is their an alternative method provided by GNAT or the Ada standard library?

Was it helpful?

Solution

I don't know of any direct way to get the 160-bit block, but of course you can compute it from the hexadecimal string.

Here's an example I just threw together. (Granted, extracting 32-bit integers by adding "16#" and "#" to the hex substring may not be the most elegant solution.

with GNAT.SHA1;
with Interfaces;
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
procedure SHA1_Demo is
    C: GNAT.SHA1.Context;
    package U32_IO is new Ada.Text_IO.Modular_IO(Interfaces.Unsigned_32);
    use U32_IO;
begin
    GNAT.SHA1.Update(C, "hello");
    declare
        SHA1: constant String := GNAT.SHA1.Digest(C);
        H: array(0..4) of Interfaces.Unsigned_32;
    begin
        Put_Line("SHA1(""hello"") = " & GNAT.SHA1.Digest(C));
        for I in Integer range 0 .. 4 loop
            H(I) := Interfaces.Unsigned_32'Value
                        ("16#" & SHA1(I*8+1 .. I*8+8) & "#");
            Put("H(");
            Put(I, Width => 0);
            Put(") = ");
            Put(H(I), Base => 16);
            New_Line;
        end loop;
    end;
end SHA1_Demo;

The output is:

SHA1("hello") = aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d
H(0) = 16#AAF4C61D#
H(1) = 16#DCC5E8A2#
H(2) = 16#DABEDE0F#
H(3) = 16#3B482CD9#
H(4) = 16#AEA9434D#
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top