Adam O'Connor
Adam O'Connor

Reputation: 2652

Create a SHA1 hash in Ruby via .net technique

OK hopefully the title didn't scare you away. I'm creating a sha1 hash using Ruby but it has to follow a formula that our other system uses to create the hash.

How can I do the following via Ruby? I'm creating hashes fine - but the format stuff is confusing me - curious if there's something equiv in the Ruby standard library.

System Security Cryptography (MSDN)

Here's the C# code that I'm trying to convert to Ruby. I'm making my hash fine, but not sure about the 'String.Format("{0,2:X2}' part.

//create our SHA1 provider
SHA1 sha = new SHA1CryptoServiceProvider();

String str = "Some value to hash";
String hashedValue; -- hashed value of the string

//hash the data -- use ascii encoding
byte[] hashedDataBytes = sha.ComputeHash(Encoding.ASCII.GetBytes(str));

//loop through each byte in the byte array 
foreach (byte b in hashedDataBytes) 
{
   //convert each byte -- append to result
   hashedValue += String.Format("{0,2:X2}", b); 
}

Upvotes: 0

Views: 649

Answers (1)

Neil Slater
Neil Slater

Reputation: 27197

A SHA1 hash of a specific piece of data is always the same hash (effectively just a large number), the only variation should be how you need to format it, to e.g. send to the other system. Although particularly obscure systems might post-process the data, truncate it or only take alternate bytes etc.

At a very rough guess from reading the C# code, this ends up a standard looking 40 character hex string. So my initial thought in Ruby is:

require 'digest/sha1'
Digest::SHA1.hexdigest("Some value to hash").upcase

. . . I don't know however what the force to ascii format in C# would do when it starts with e.g. a Latin-1 or UTF-8 string. They would be useful example inputs, if only to see C# throw an exception - you know then whether you need to worry about character encoding for your Ruby version. The data input to SHA1 is bytes, not characters, so which encoding to use and how to convert are parts of your problem.

My current understanding is that Encoding.ASCII.GetBytes will force anything over character number 127 to a '?', so you may need to emulate that in Ruby using a .gsub or similar, especially if you are actually expecting that to come in from the data source.

Upvotes: 2

Related Questions