Ruby on rails Ruby hexdigest sha1包('H*')字符串编码。。。
我遇到了一个编码问题。。。控制台中没有错误,但输出编码不正确。 我必须对字符串使用Digest::SHA1.hexdigest,然后必须打包结果 下面的示例应该输出“{pODýGÎ-£Iô8ü:IÀ”,但它在控制台和{�豆荚�G^BΗ�我�8^D�:我�' 在日志文件中 所以,我的变量pack等于“{pOD?GΗ?I?8?:I?”而不是“{pODýGÎ-”Iô8ü:IÀ”。这是一个大问题……我是在Rails任务中完成的。 有什么想法吗,伙计们 谢谢Ruby on rails Ruby hexdigest sha1包('H*')字符串编码。。。,ruby-on-rails,ruby,character-encoding,pack,digest,Ruby On Rails,Ruby,Character Encoding,Pack,Digest,我遇到了一个编码问题。。。控制台中没有错误,但输出编码不正确。 我必须对字符串使用Digest::SHA1.hexdigest,然后必须打包结果 下面的示例应该输出“{pODýGÎ-£Iô8ü:IÀ”,但它在控制台和{�豆荚�G^BΗ�我�8^D�:我�' 在日志文件中 所以,我的变量pack等于“{pOD?GΗ?I?8?:I?”而不是“{pODýGÎ-”Iô8ü:IÀ”。这是一个大问题……我是在Rails任务中完成的。 有什么想法吗,伙计们 谢谢 # encoding: utf-8 requi
# encoding: utf-8
require 'digest/sha1'
namespace :my_app do
namespace :check do
desc "Description"
task :weather => :environment do
hexdigest = Digest::SHA1.hexdigest('29d185d98c984a359e6e6f26a0474269partner=100043982026&code=34154&profile=large&filter=movie&striptags=synopsis%2Csynopsisshort&format=json&sed=20130527')
pack = [hexdigest].pack("H*")
puts pack # => {?p)OD?GΗ?I?8?:i?
puts '{´p)ODýGΗ£Iô8ü:iÀ' # => {´p)ODýGΗ£Iô8ü:iÀ
end
end
end
我认为这个编码问题是由于调试了从PHP到Ruby的转换的其他部分而出现的。将使用参数摘要的目标API看起来将接受一个用Ruby构建的签名变量,如下编辑:这是猜测,Ruby和PHP在URI编码和base6方面也可能有相关的差异4个默认值:
require 'digest/sha1'
require 'base64'
require 'uri'
sig_data = 'edhefhekjfhejk8edfefefefwjw69partne...'
sig = URI.encode( Base64.encode64( Digest::SHA1.digest( sig_data ) ) )
=> "+ZabHg22Wyf7keVGNWTc4sK1ez4=%0A"
从正在签名的参数中准确构造sig_数据也很重要。这是由PHP方法http_build_查询生成的,我不知道将应用于输入参数的顺序或转义。如果您的Ruby版本以不同的顺序获取这些参数,或者转义与PHP不同,则签名将是错误的编辑:Actually我们可能在这里寻找API发送的确切查询字符串上的签名-我不知道。这可能是一个类似的问题,使您陷入了如何构造签名的兔子洞?这就是我从PHP到Ruby的转换
# encoding: utf-8
require 'open-uri'
require 'base64'
require 'digest/sha1'
class Allocine
$_api_url = 'http://api.allocine.fr/rest/v3'
$_partner_key
$_secret_key
$_user_agent = 'Dalvik/1.6.0 (Linux; U; Android 4.2.2; Nexus 4 Build/JDQ39E)'
def initialize (partner_key, secret_key)
$_partner_key = partner_key
$_secret_key = secret_key
end
def get(id)
# build the params
params = { 'partner' => $_partner_key,
'code' => id,
'profile' => 'large',
'filter' => 'movie',
'striptags' => 'synopsis,synopsisshort',
'format' => 'json' }
# do the request
response = _do_request('movie', params)
return response
end
private
def _do_request(method, params)
# build the URL
query_url = $_api_url + '/' + method
# new algo to build the query
http_build_query = Rack::Utils.build_query(params)
sed = DateTime.now.strftime('%Y%m%d')
sig = URI::encode(Base64.encode64(Digest::SHA1.digest($_secret_key + http_build_query + '&sed=' + sed)))
return sig
end
end
然后打电话
allocine = Allocine.new(ALLOCINE_PARTNER_KEY, ALLOCINE_SECRET_KEY)
puts allocine.get('any ID')
获取方法在PHP中返回'e7RwKU9E%2FUcCzpejSfQ4BPw6acA%3D',在Ruby中返回'cPf6I4ZP0qHQTSVgdKTbSspivzg=%0A'
再次感谢你们的帮助。 问题解决了。通过以下代码,我获得了与PHP完全相同的字符串:
http_build_query = Rack::Utils.build_query(params)
sed = DateTime.now.strftime('%Y%m%d')
sig = CGI::escape(Base64.strict_encode64(Digest::SHA1.digest($_secret_key + http_build_query + '&sed=' + sed)))
现在我有另一个问题,我打开了一个
非常感谢。您如何知道输出应该是'{'pODýGÎ-£Iô8ü:IÀ。这应该是什么编码?我知道这一点,因为我用php编写了相同的脚本,在浏览器中呈现。你可以看看我的rail应用程序的第二个参数是utf8,我的服务器本地值也是。我不确定你为什么希望pack的结果是一个特定的字符序列?通常用于像d这样的字节字符串igest需要匹配特定的字节序列,并且需要使用ASCII中定义良好的编码十六进制摘要来发送或存储它,这是一种简单但空间效率低下的方案。如果您确实希望将特定的字符序列作为输出,然后编码到当前web应用程序的输出,则需要指定encod在转换之前,我会将初始摘要字节解释为拉丁文-1。在浏览器中渲染可能很容易损坏它,例如,如果您转储了一些原始字节,浏览器将其解释为UTF8,请注意,可以将hexdigest和pack行组合在一起:digest::SHA1。摘要数据在Ruby中是等效的,并且可能稍微快一点好的,我处理了参数的顺序。输入字符串与PHP版本中的完全相同…我已经在下面粘贴了我的代码。好的,我看不出Ruby和PHP之间有什么不同,但这可能只是因为我对PHP了解不够。我有理由相信,您的问题不是直接从摘要或hexdig中进行字符编码est/pack或尽管如此。谢谢尼尔,它现在可以工作了。回答下面的问题。但是新问题。如果你知道如何解决它…再次感谢