1

I have a use case to send the hashcode of the payload along with the payload in the request.

My Client is Ruby but Servers are both Rails and Node.

What is the best way to create a hash code for the payload (any Ruby HashMap)?

How can I create the same hashcode on the other server?

>> x = {:name=>"John", :age=>30, :cars=>{:car1=>"Ford", :car2=>"BMW", :car3=>"Fiat"}} 
>> x.hash
-4250725627701565010
3
  • 1
    Maybe it's better to use well-known language independent hash algorithm? Like MD5, SHA1 and so on. Commented Dec 8, 2020 at 8:20
  • 1
    Is there any helper that cleans the payload to get the same form on the client side and on the server side? It has to support the nested JSON as well. Commented Dec 8, 2020 at 8:34
  • For JS there is JSON.stringify Commented Dec 8, 2020 at 9:37

2 Answers 2

6

This is not possible.

The only guarantees that Ruby makes about the hashcode are:

  • Two objects that are eql? have the same hashcode.
  • The hashcode of an object does not change, unless it is mutated.
  • The hashcode is an Integer. It may be truncated to a fixed-width integer in certain methods.

In particular, the following are not guaranteed:

  • There is no guarantee that a Ruby implementation uses any particular hashing algorithm.
  • There is no guarantee that the hash value of an object will be the same between different Ruby implementations.
  • There is no guarantee that the hash value of an object will be the same between different versions of the same Ruby implementation.
  • There is no guarantee that the hash value of an object will be the same between different processes of the same version of the same Ruby implementation.
  • There is no guarantee that the hash value of an object will be the same between different runs of the same code within the same process of the same version of the same Ruby implementation.

In fact, several Ruby implementations randomize hashcodes for security purposes.

In other words, there isn't even a way in Ruby to know what the hashcode for an object will be at runtime, so there is most definitely no way to know that in ECMAScript.

Sign up to request clarification or add additional context in comments.

Comments

2

You could use an alternative hashing algorithm, such as SHA256, this will give the same result in Ruby and Javascript.

One must be careful however, the hashes will only match if the inputs are exactly the same.

Ruby

require 'json'
require 'digest/sha2'

x = {:name=>"John", :age=>30, :cars=>{:car1=>"Ford", :car2=>"BMW", :car3=>"Fiat"}} 
json = JSON.generate(x)
print "Hash: " + (Digest::SHA2.hexdigest json)

Node.js

const crypto = require("crypto");

const x = { name: "John", age: 30, cars: { car1: "Ford", car2: "BMW", car3: "Fiat" }};
const json = JSON.stringify(x);
const hash = crypto.createHash("SHA256").update(json, "utf8").digest("hex");
console.log("Hash:", hash);

We'll get the same result in both cases:

Hash: 1b5299251d2e9bf775bc4cf34a017c829d93866ac9563b04e2b14b6b3d291067

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.