#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