首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为Ruby中传入的参数创建校验和

为Ruby中传入的参数创建校验和
EN

Stack Overflow用户
提问于 2015-12-09 15:51:24
回答 3查看 523关注 0票数 0

我正在为我的支付网关创建一个校验和。校验和应采用以下格式:

代码语言:javascript
运行
复制
key|txnid|amount|productinfo|firstname|email|||||||||||salt

我需要在电子邮件和盐之间留下11个管道。

在我的控制器中我创建了一个方法:

代码语言:javascript
运行
复制
require 'digest/sha2'

def getChecksum(key, txnid, amount, productinfo, firstname, email, phone, surl, furl)
  String str = key + '|' + txnid + '|' + amount + '|' + productinfo + '|' + firstname + '|' + email + '|' + phone + '|' + surl + '|' + furl+ '|'+ '|'+ '|'+ '|'+ '|'+ '|'+ '|'+ '|' + 'salt'
  Digest::SHA512.hexdigest( str )
end

我在控制器中调用了这个方法:

代码语言:javascript
运行
复制
hash: getChecksum(
              key: 'key_value',
              txnid: '4',
              amount: '2000',
              productinfo: 'first sales',
              firstname: 'John',
              email: 'johndepp@gmail.com',
              phone: '123456789',
              surl: 'http://someurl.io',
              furl: 'http://someurl.io')

但是现在我得到了一个“错误数目的论点”错误:

代码语言:javascript
运行
复制
wrong number of arguments (1 for 9)    
def getChecksum( key,  txnid, 
amount,  productinfo,  firstname, email, phone, surl, furl)

我认为所有的参数都被认为是单一的。有人能告诉我我在这里做错了什么吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-12-09 17:46:33

让我们看看您是如何编写代码的,看看我们是否能够使它更像Ruby,并希望它更具有生产价值。

你写了这个:

代码语言:javascript
运行
复制
def getChecksum(key, txnid, amount, productinfo, firstname, email, phone, surl, furl)
  String str = key + '|' + txnid + '|' + amount + '|' + productinfo + '|' + firstname + '|' + email + '|' + phone + '|' + surl + '|' + furl+ '|'+ '|'+ '|'+ '|'+ '|'+ '|'+ '|'+ '|' + 'salt'
  Digest::SHA512.hexdigest( str )
end

首先,尼克。

  • Ruby中的方法和变量是snake_case,而不是camelCase。ItsAReadabilityThing。
  • 我们不使用String str =...定义变量。Ruby可以计算出哪种类型的变量是99.99%的时间,所以str =...就足够了。
  • 想想你是如何使用固定字符串和值的。'|'是您的分隔符,因此将其定义为: 分隔符=‘x’ 你需要其中的十一个作为分隔器,所以定义如下: 分隔器=分隔符* 11

我会写更像这样的代码:

代码语言:javascript
运行
复制
require 'digest/sha2'

SEPARATOR = '|'
DIVIDER = SEPARATOR * 11 # => "|||||||||||"

def checksum_1(key, txnid, amount, productinfo, firstname, email, phone, surl, furl)
  str = [key, txnid, amount, productinfo, firstname, email, phone, surl, furl].join(SEPARATOR) + DIVIDER + 'salt'
  Digest::SHA512.hexdigest(str)
end

但即便如此,也是可以改进的。

当我们有三个以上的参数时,是时候重构和清理参数列表了。做这件事有很多种方法,但最常见的方法是使用散列:

代码语言:javascript
运行
复制
def checksum_2(params)
  str = params.values_at(
    :key, :txnid, :amount, :productinfo, :firstname, :email, :phone, :surl, :furl
  ).join(SEPARATOR) + DIVIDER + 'salt'

  Digest::SHA512.hexdigest( str )
end

使用values_at是提取散列中键值的一种很好的方法。它们以相同的键顺序以数组的形式出现。

现在的问题是,可能缺少一个参数,而Ruby无法捕捉它。命名参数是处理这个问题的新热点,但是对于老的Rubies来说,或者想知道在其他语言中是如何实现的,我们可以查看接收到的键,然后查看它们的相关值,如果事情看起来不太好,就会引发异常,而不是返回虚假的值。

为了使事情变得更简单,我将使用Active Support的blank?方法,这可以在核心扩展中找到:

代码语言:javascript
运行
复制
require 'active_support/core_ext/object/blank'
def checksum_3(params)
  required_values = [:key, :txnid, :amount, :productinfo, :firstname, :email, :phone, :surl, :furl]

  missing_keys = required_values - params.keys
  fail ArgumentError, "Missing keys: #{ missing_keys.map{ |k| ":#{ k }" }.join(', ') }" unless missing_keys.empty?

  missing_values = required_values.select{ |k| params[k].blank? }
  fail ArgumentError, "Missing values for: #{ missing_values.map{ |k| ":#{ k }" }.join(', ') }" unless missing_values.empty?

  str = params.values_at(*required_values).join(SEPARATOR) + DIVIDER + 'salt'
  Digest::SHA512.hexdigest(str)
end

下面是对该方法不同版本的调用以及返回的相关校验和的外观:

代码语言:javascript
运行
复制
c1 = checksum_1('key_value', '4', '2000', 'first sales', 'John', 'johndepp@gmail.com', '123456789', 'http://someurl.io', 'http://someurl.io')

c2 = checksum_2(
  key: 'key_value',
  txnid: '4',
  amount: '2000',
  productinfo: 'first sales',
  firstname: 'John',
  email: 'johndepp@gmail.com',
  phone: '123456789',
  surl: 'http://someurl.io',
  furl: 'http://someurl.io'
)

c3 = checksum_3(
  key: 'key_value',
  txnid: '4',
  amount: '2000',
  productinfo: 'first sales',
  firstname: 'John',
  email: 'johndepp@gmail.com',
  phone: '123456789',
  surl: 'http://someurl.io',
  furl: 'http://someurl.io'
)

c1 # => "fcf4e21c6e711808a6984824f09552dccc5c4378b55720c88b3abd4a1904931b8d883beaef51edec705a9d8b0ccd3ba898a0d4c05f75bd41fa3b90f0df7b5c79"
c2 # => "fcf4e21c6e711808a6984824f09552dccc5c4378b55720c88b3abd4a1904931b8d883beaef51edec705a9d8b0ccd3ba898a0d4c05f75bd41fa3b90f0df7b5c79"
c3 # => "fcf4e21c6e711808a6984824f09552dccc5c4378b55720c88b3abd4a1904931b8d883beaef51edec705a9d8b0ccd3ba898a0d4c05f75bd41fa3b90f0df7b5c79"

虽然我们仍然需要传递相同数量的信息,但是使用散列可以让我们看到每个参数被分配给什么,从而产生自文档化代码,这对于长期维护来说是非常重要的。此外,哈希不需要参数的特定顺序,这样编写调用它的代码就更容易了;我通常知道我需要某些东西,但不记得它们的顺序。

这就是我对如何编写这类代码的全部看法。有关相同主题的类似文章,请参见"Ruby 2关键字参数“。

票数 1
EN

Stack Overflow用户

发布于 2015-12-09 15:54:49

您要发送一个散列作为参数,而只需要发送值(没有键)。另外,不需要声明String str类型,您应该检查一下您的Ruby基本面,我猜您来自另一种语言。

代码语言:javascript
运行
复制
# You are calling this
getChecksum(key: 'key_value', txnid: '4', ...)
# which syntactically equals this, a single hash as a parameter
getChecksum({key: 'key_value', txnid: '4', ...})
# Instead, send the values alone
getChecksum('key_value', '4', ...)
票数 2
EN

Stack Overflow用户

发布于 2015-12-09 16:10:59

下面是如何定义带有关键字参数的方法:

代码语言:javascript
运行
复制
def getChecksum(key:, txnid:, amount:, productinfo:, firstname:, email:, phone:, surl:, furl:)
  str = key + '|' + txnid + '|' + amount + '|' + productinfo + '|' + firstname + '|' + email + '|' + phone + '|' + surl + '|' + furl+ '|'+ '|'+ '|'+ '|'+ '|'+ '|'+ '|'+ '|' + 'salt'
  Digest::SHA512.hexdigest( str )
end

然后,您可以像现在这样用哈希调用它。

不过,我觉得这个看起来更干净一些:

代码语言:javascript
运行
复制
def get_checksum(key:, txnid:, amount:, productinfo:, firstname:, email:, phone:, surl:, furl:)
  str = "#{key}|#{txnid}|#{amount}|#{productinfo}|#{firstname}|#{email}|#{phone}|#{surl}|#{furl}||||||||salt"
  Digest::SHA512.hexdigest(str)
end

或者也许:

代码语言:javascript
运行
复制
def get_checksum(key:, txnid:, amount:, productinfo:, firstname:, email:, phone:, surl:, furl:)
  str = [ key, txnid, amount, productinfo, firstname, email, phone, surl, furl ].join("|")
  Digest::SHA512.hexdigest("#{str}||||||||salt")
end

您可以了解关于关键字参数的更多信息,包括如何赋予关键字默认值使其可选,在这里:https://robots.thoughtbot.com/ruby-2-keyword-arguments

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34183149

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档