Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

GNAT.SHA256 produces result different from sha257sum on Linux

54 views
Skip to first unread message

wvxvw

unread,
Nov 4, 2023, 10:39:42 AM11/4/23
to
Hello. (Sorry for duplication, the first attempt to send this sent it as
a response to an unrelated thread).

I'm learning Ada as well as how to use Usenet, so don't be too harsh.
As a learning exercise, I want to write a program that, beside other
things, needs to compute SHA256 hashes. I discovered GNAT.SHA256
library and was able to use it (by calling Digest(<some string>)),
however the result is different from what I'd get for the same string
with running sha256sum.

Eg, with GNAT.SHA256 for string "foo" I get:

❯ ./bin/test_sha --arg foo
2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae
❯ echo foo | sha256sum -
b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c -

My Ada code looks (with some unrelated stuff removed) like this:

with GNAT.Command_Line; use GNAT.Command_Line;
with GNAT.SHA256; use GNAT.SHA256;

procedure Main is
loop
case Getopt ("-arg=") is
when '-' =>
if Full_Switch = "-arg" then
Put_Line (Digest (Parameter));
end if;
end case;
end loop;
end Main;

My understanding is that there are plenty of configuration settings to
how the checksum is computed, but I know very little about it. My goal
is to produce the same checksum as would be produced by sha256sum
though, as the checksums are to be used outside of my program.

Finally: is GNAT.SHA256 a good way to go if I need this functionality (I
don't care about portability, if that's a concern)?

Thanks!

Jeffrey R.Carter

unread,
Nov 4, 2023, 11:10:03 AM11/4/23
to
On 2023-11-04 15:39, wvxvw wrote:
>
> ❯ ./bin/test_sha --arg foo
> 2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae
> ❯ echo foo | sha256sum -
> b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c -

I think the problem may be that echo adds an LF:

$ echo foo | hd
00000000 66 6f 6f 0a |foo.|

Since sha256sum expects to work on arbitrary files, it would include the LF in
its input.

--
Jeff Carter
"You can never forget too much about C++."
115

wvxvw

unread,
Nov 4, 2023, 12:48:07 PM11/4/23
to
"Jeffrey R.Carter" <spam.jrc...@spam.acm.org.not> writes:

> I think the problem may be that echo adds an LF:
>
> $ echo foo | hd
> 00000000 66 6f 6f 0a |foo.|
>
> Since sha256sum expects to work on arbitrary files, it would include
> the LF in its input.

Hi, thanks for the idea, but no, that's not it. With the line end added
I get 04e1806fda6bdbc9e5e3534edd993c7c2bf03173f5489742db53d1e8b0ef8c61
from Ada.

Niklas Holsti

unread,
Nov 4, 2023, 12:50:02 PM11/4/23
to
On 2023-11-04 17:09, Jeffrey R.Carter wrote:
> On 2023-11-04 15:39, wvxvw wrote:
>>
>> ❯ ./bin/test_sha --arg foo
>> 2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae
>> ❯ echo foo | sha256sum -
>> b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c  -
>
> I think the problem may be that echo adds an LF:
>
> $ echo foo | hd
> 00000000  66 6f 6f 0a                                       |foo.|
>
> Since sha256sum expects to work on arbitrary files, it would include the
> LF in its input.


Some implementations of "echo" accept an option "-n" to suppress the
trailing newline (LF). The OP could try that option as a quick check of
this answer (which seems very plausible).

Jeffrey R.Carter

unread,
Nov 4, 2023, 1:39:55 PM11/4/23
to
> On 2023-11-04 17:09, Jeffrey R.Carter wrote:
>> On 2023-11-04 15:39, wvxvw wrote:
>>>
>>> ❯ ./bin/test_sha --arg foo
>>> 2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae
>>> ❯ echo foo | sha256sum -
>>> b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c  -
>>
>> I think the problem may be that echo adds an LF:
>>
>> $ echo foo | hd
>> 00000000  66 6f 6f 0a                                       |foo.|
>>
>> Since sha256sum expects to work on arbitrary files, it would include the LF in
>> its input.

wvxvw wrote:
>
> Hi, thanks for the idea, but no, that's not it. With the line end added
> I get 04e1806fda6bdbc9e5e3534edd993c7c2bf03173f5489742db53d1e8b0ef8c61
> from Ada.

On 2023-11-04 17:49, Niklas Holsti wrote:
>
> Some implementations of "echo" accept an option "-n" to suppress the trailing
> newline (LF). The OP could try that option as a quick check of this answer
> (which seems very plausible).

$ echo -n foo | hd
00000000 66 6f 6f |foo|
$ echo -n foo | sha256sum -
2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae -

Interesting results.

Ben Bacarisse

unread,
Nov 4, 2023, 1:53:45 PM11/4/23
to
wvxvw <olegs...@gmail.com> writes:

> "Jeffrey R.Carter" <spam.jrc...@spam.acm.org.not> writes:
>
>> I think the problem may be that echo adds an LF:
>>
>> $ echo foo | hd
>> 00000000 66 6f 6f 0a |foo.|
>>
>> Since sha256sum expects to work on arbitrary files, it would include
>> the LF in its input.
>
> Hi, thanks for the idea, but no, that's not it.

You say that's not it, but with the newline removed, sha256sum gives the
same hash as your original test code:

$ printf foo | sha256sum -
2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae -

From your earlier post:
> Eg, with GNAT.SHA256 for string "foo" I get:
>
> ❯ ./bin/test_sha --arg foo
> 2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae

> With the line end added
> I get 04e1806fda6bdbc9e5e3534edd993c7c2bf03173f5489742db53d1e8b0ef8c61
> from Ada.

Ah! You didn't add a newline! I can get the same hash by guesswork:

$ printf foo\\\\n >input
$ sha256sum input
04e1806fda6bdbc9e5e3534edd993c7c2bf03173f5489742db53d1e8b0ef8c61 input
$ hd input
00000000 66 6f 6f 5c 6e |foo\n|
00000005

What you added to the test string was a backslash and a letter n.

--
Ben.

wvxvw

unread,
Nov 4, 2023, 3:26:39 PM11/4/23
to
Ben Bacarisse <ben.u...@bsb.me.uk> writes:

> Ah! You didn't add a newline! I can get the same hash by guesswork:
>
> $ printf foo\\\\n >input
> $ sha256sum input
> 04e1806fda6bdbc9e5e3534edd993c7c2bf03173f5489742db53d1e8b0ef8c61 input
> $ hd input
> 00000000 66 6f 6f 5c 6e |foo\n|
> 00000005
>
> What you added to the test string was a backslash and a letter n.

Yeah, thanks! I realized this too by trying to do this in Python:

>>> import hashlib
>>> hashlib.sha256('foo'.encode()).hexdigest()
'2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae'
>>> hashlib.sha256('foo\n'.encode()).hexdigest()
'b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c'

Thanks again.
0 new messages