Getting the SHA1 block from GNAT.SHA1
题
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?
解决方案
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#