背景:小弟最近在对接腾讯云短信的接口,由于腾讯云短信没有提供 ruby 的 SDK,所以按照官方的签名方法自己进行了封装。但是腾讯一直报签名错误,故与腾讯贴出来的 python 代码示例进行了对比,发现问题出在 ruby 和 python 对中文的处理上
ruby:
require 'json'
require 'digest'
params = { "key": '' }
u = JSON.dump(params).gsub(':', ': ').gsub(',', ', ')
res = Digest::SHA256.hexdigest(u)
puts res
# 30428a3206c817f42e49331138ba5d36e2a29124876f75fad011f4c1f5b94661
python:
import json, hashlib
params = {"key": ''}
u = json.dumps(params).encode('utf-8')
res = hashlib.sha256(u).hexdigest()
print(res)
# 30428a3206c817f42e49331138ba5d36e2a29124876f75fad011f4c1f5b94661
到这里为止,ruby 和 python 使用 SHA256 算法散列出来的结果是相同的
加入中文:
ruby:
require 'json'
require 'digest'
params = { "key": '爱你' }
u = JSON.dump(params).gsub(':', ': ').gsub(',', ', ')
res = Digest::SHA256.hexdigest(u)
puts res
# 3454c5b42519f5be5a953324779d48b7662d25d08e06fe020a5c2248a23921ae
python:
import json, hashlib
params = {"key": '爱你'}
u = json.dumps(params).encode('utf-8')
res = hashlib.sha256(u).hexdigest()
print(res)
# 981727d14419aedca58b2e719b4a9ff94cf20ef91e02c9cd22e7ee6f5744f630
不知道 ruby 中对中文的处理和 python 中有何不同,造成了这个偏差?各路大佬可以讲讲吗?
ps:
gsub(':', ': ').gsub(',', ', ')
这个操作感到奇怪,但是如果不做这个处理,结果会是这样require 'json'
require 'digest'
params = { "key": '' }
u = JSON.dump(params)
res = Digest::SHA256.hexdigest(u)
puts res
# 0944d67c4d96fe949834700d0cb784b99ee5b0b6205b0667d842ece155405df2