How to Serialize a Ruby Digest::Sha1 Instance Object

Flatten deep nested hash to array for sha1 hashing

EDIT : As you detailed, two hashes with keys in different order should give the same string. I would reopen the Hash class to add my new custom flatten method :

class Hash
def custom_flatten()
self.sort.map{|pair| ["key: #{pair[0]}", pair[1]]}.flatten.map{ |elem| elem.is_a?(Hash) ? elem.custom_flatten : elem }.flatten
end
end

Explanation :

  • sort converts the hash to a sorted array of pairs (for the comparison of hashes with different keys order)
  • .map{|pair| ["key: #{pair[0]}", pair[1]]} is a trick to differentiate keys from values in the final flatten array, to avoid the problem of {a: {b: {c: :d}}}.custom_flatten == {a: :b, c: :d}.custom_flatten
  • flatten converts an array of arrays into a single array of values
  • map{ |elem| elem.is_a?(Hash) ? elem.custom_flatten : elem } calls back fully_flatten on any sub-hash left.

Then you just need to use :

require 'digest/sha1'
Digest::SHA1.hexdigest hash.custom_flatten.to_s

Ruby 1.9.3 Digest::SHA1.hexdigest equivalent in Golang

Use crypto/sha1

package main

import (
"crypto/sha1"
"fmt"
)

func main() {
s := sha1.New()
s.Write([]byte("Hello world"))
fmt.Printf("%x", s.Sum(nil))
}

playground

Getting the SHA1 block from GNAT.SHA1

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#

How do I create a SHA1 hash in ruby?

require 'digest/sha1'
Digest::SHA1.hexdigest 'foo'

Ruby: How can I write a digest to a file in binary format

The to_s method of Digest returns the hexadecimal encoding of the hash, so this is what you get by default when trying to output it (since Ruby will use to_s when writing). To get the raw binary, use digest:

digest = Digest::SHA512.new
digest.update(chall)
File.open('sha1.bin', 'wb') { |file| file.write(digest.digest) }

Alternatively you could use the class method version of digest if you’re not calculating the hash in chunks:

digest = Digest::SHA512.digest(chall)
File.open('sha1.bin', 'wb') { |file| file.write(digest) }

sha1 checksum in delphi

You appear to be using Indy 9, which does not support SHA1. SHA1 (and a few other hashes, including several other SHAs) was added in Indy 10. The interface for TIdHash was also re-written in Indy 10. Amongst other changes, the HashValue() method was replaced with new Hash...() and Hash...AsHex() methods (HashString(AsHex), HashStream(AsHex), HashBytes(AsHex)), eg:

uses
..., IdHash, IdHashMessageDigest;

var
Hash: TIdBytes;
begin
with TIdHashMessageDigest5.Create do
try
st2.Position := 0;
Hash := HashStream( st2 );
finally
Free;
end;
// use Hash as needed...
end;

uses
..., IdHash, IdHashSHA;

var
Hash: TIdBytes;
begin
with TIdHashSHA1.Create do
try
st2.Position := 0;
Hash := HashStream( st2 );
finally
Free;
end;
// use Hash as needed...
end;


Related Topics



Leave a reply



Submit