将 PHP 代码转换为 Ruby 以获得 SHA512 哈希码

Convert PHP code to Ruby for SHA512 hash code

PHP代码:

$secret = '70b49742-adbf-4ac5-9cd6-5ded5c39aa83'; // Signature Secret

$fields = array(
    'merchant_reference' => '1234567890',
    'currency' => 'USD',
    'amount' => '100.00',
    'customer_ip' => '123.123.123.123',
    'customer_name' => 'Someone Buying',
    'customer_address' => '1, Bay Street',
    'customer_phone' => '0123123123',
    'customer_email' => 'someone@gmail.com',
    'customer_country' => 'US',
    'return_url' => 'https://demo.shop.com/payment/return'
);

ksort($fields);

$sign = hash('SHA512', http_build_query($fields) . $secret);

// value of $sign
// 750b059c76657abf2a2b73e0c8d919ec5739f83a713fcdce1fd22f2b3f45446d554bc26d6508972ba16cf2c4e55ec46861d966ba976effaeba9802b829164417

我尝试在 Ruby 代码:

中进行上述转换
require 'digest'
secret = '70b49742-adbf-4ac5-9cd6-5ded5c39aa83'
fields = {
  'merchant_reference' => '1234567890',
  'currency' => 'USD',
  'amount' => '100.00',
  'customer_ip'=> '123.123.123.123',
  'customer_name' => 'Someone Buying',
  'customer_address'=> '1, Bay Street',
  'customer_phone' => '0123123123',
  'customer_email' => 'someone@gmail.com',
  'customer_country' => 'US',
  'return_url' => 'https://demo.shop.com/payment/return'
}

sorted_fields = Hash[fields.sort_by{|key,value| key}]

sign = OpenSSL::HMAC.hexdigest('sha512', secret, sorted_fields.to_query)
# Output:
# 9c3104f9efd449987cc2055a1524b0f6c032fc3ae9e7516bbb8de2bffca08a212558323dd17cc96b77d6d63a8b92777ddadb38df39fa75971408efc16296322a

我期待 sign 的输出相同。在 PHP 代码中,我用 Ruby 生成的字符串 sorted_fields.to_query 值替换了 http_build_query($fields),它工作正常。

我确定下一行有问题:

OpenSSL::HMAC.hexdigest('sha512', secret, sorted_fields.to_query)

正在 Ruby 中寻找合适的语法。

尝试:

> sign = Digest::SHA512.hexdigest(sorted_fields.to_query + secret) 
# => 750b059c76657abf2a2b73e0c8d919ec5739f83a713fcdce1fd22f2b3f45446d554bc26d6508972ba16cf2c4e55ec46861d966ba976effaeba9802b829164417

完整代码:

secret = '70b49742-adbf-4ac5-9cd6-5ded5c39aa83'
fields = {
  'merchant_reference' => '1234567890',
  'currency' => 'USD',
  'amount' => '100.00',
  'customer_ip'=> '123.123.123.123',
  'customer_name' => 'Someone Buying',
  'customer_address'=> '1, Bay Street',
  'customer_phone' => '0123123123',
  'customer_email' => 'someone@gmail.com',
  'customer_country' => 'US',
  'return_url' => 'https://demo.shop.com/payment/return'
}
sorted_fields = Hash[fields.sort_by{|key,value| key}]
sign = Digest::SHA512.hexdigest(sorted_fields.to_query + secret) 
puts sign
# 750b059c76657abf2a2b73e0c8d919ec5739f83a713fcdce1fd22f2b3f45446d554bc26d6508972ba16cf2c4e55ec46861d966ba976effaeba9802b829164417

Reference for more information refer https://ruby-doc.org/stdlib-2.1.0/libdoc/digest/rdoc/Digest.html