Как вычислить хэш ruby в JavaScript?

#node.js #ruby-on-rails #ruby

#node.js #ruby-on-rails #ruby

Вопрос:

У меня есть вариант использования для отправки хэш-кода полезной нагрузки вместе с полезной нагрузкой в запросе.

Мой клиент — Ruby, но серверы — это как Rails, так и Node.

Каков наилучший способ создания хэш-кода для полезной нагрузки (любой Ruby HashMap)?

Как я могу создать тот же хэш-код на другом сервере?

 >> x = {:name=>"John", :age=>30, :cars=>{:car1=>"Ford", :car2=>"BMW", :car3=>"Fiat"}} 
>> x.hash
-4250725627701565010
 

Комментарии:

1. Может быть, лучше использовать хорошо известный независимый от языка алгоритм хэширования? Например, MD5, SHA1 и так далее.

2. Есть ли какой-нибудь помощник, который очищает полезную нагрузку, чтобы получить одну и ту же форму на стороне клиента и на стороне сервера? Он также должен поддерживать вложенный JSON.

3. Для JS есть JSON.stringify

Ответ №1:

Это невозможно.

Единственными гарантиями, которые Ruby дает в отношении хэш-кода, являются:

  • Два объекта, которые eql? имеют одинаковый хэш-код.
  • Хэш-код объекта не изменяется, если только он не видоизменен.
  • Хэш — код — это an Integer . В некоторых методах он может быть усечен до целого числа фиксированной ширины.

В частности, не гарантируется следующее:

  • Нет никакой гарантии, что реализация Ruby использует какой-либо конкретный алгоритм хеширования.
  • Нет никакой гарантии, что хэш-значение объекта будет одинаковым в разных реализациях Ruby.
  • Нет никакой гарантии, что хэш-значение объекта будет одинаковым в разных версиях одной и той же реализации Ruby.
  • Нет никакой гарантии, что хэш-значение объекта будет одинаковым между различными процессами одной и той же версии одной и той же реализации Ruby.
  • Нет никакой гарантии, что хэш-значение объекта будет одинаковым между различными запусками одного и того же кода в рамках одного и того же процесса одной и той же версии одной и той же реализации Ruby.

Фактически, несколько реализаций Ruby рандомизируют хэш-коды в целях безопасности.

Другими словами, в Ruby даже нет способа узнать, каким будет хэш-код для объекта во время выполнения, поэтому в ECMAScript определенно нет способа узнать это.

Ответ №2:

Вы могли бы использовать альтернативный алгоритм хеширования, такой как SHA256, это даст тот же результат в Ruby и Javascript.

Однако нужно быть осторожным, хэши будут совпадать только в том случае, если входные данные будут точно такими же.

Рубиновый

 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);
 

Мы получим одинаковый результат в обоих случаях:

 Hash: 1b5299251d2e9bf775bc4cf34a017c829d93866ac9563b04e2b14b6b3d291067