Получение блока SHA1 из GNAT.SHA1 - PullRequest
1 голос
/ 14 января 2012

Я использую GNAT.SHA1 для создания SHA1 хеша строки в Ada. У меня небольшая база кода, поэтому я хотел бы избежать импорта в проект любых библиотек, которые не предоставлены моим компилятором, поэтому я использую GNAT.SHA1. Насколько я знаю, единственные "публичные" методы для получения хеша находятся в строковой форме через функцию Digest. Вместо этого я хотел бы получить 160-битный блок, являющийся членом H типа Context. К сожалению, запись Context является конфиденциальной. Есть ли способ, которым я могу добраться до этого? Или это альтернативный метод, предоставляемый GNAT или стандартной библиотекой Ada?

1 Ответ

4 голосов
/ 14 января 2012

Я не знаю ни одного прямого способа получить 160-битный блок, но, конечно, вы можете вычислить его из шестнадцатеричной строки.

Вот пример, который я только что скомбинировал.(Конечно, извлечение 32-разрядных целых чисел путем добавления "16#" и "#" к шестнадцатеричной подстроке может оказаться не самым элегантным решением.

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;

Вывод:

SHA1("hello") = aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d
H(0) = 16#AAF4C61D#
H(1) = 16#DCC5E8A2#
H(2) = 16#DABEDE0F#
H(3) = 16#3B482CD9#
H(4) = 16#AEA9434D#
...