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

时间:2015-12-09 15:51:24

标签: ruby-on-rails ruby

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

UIView

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

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

UITapGestureRecognizer

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

key|txnid|amount|productinfo|firstname|email|||||||||||salt

但是现在我得到的错误数量的论点"错误:

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

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

3 个答案:

答案 0 :(得分:2)

您要发送一个哈希作为参数,而只需要发送值(不带键​​)。也不需要声明类型String str,你应该检查你的Ruby基础知识,我猜你是来自另一种语言。

# 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', ...)

答案 1 :(得分:1)

以下是使用关键字参数定义方法的方法:

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

然后你可以用你当前的哈希来调用它。

我认为这看起来更清洁一点:

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

或者也许:

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

答案 2 :(得分:1)

让我们来看看你是如何编写代码的,看看我们是否可以使它更像Ruby,并希望更具生产价值。

你写了这个:

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

首先,ick。

  • Ruby中的方法和变量是snake_case,而不是camelCase。 ItsAReadabilityThing。
  • 我们不使用String str =...定义变量。 Ruby可以找出99.99%的时间变量类型,因此str =...就足够了。
  • 想想你是如何使用固定字符串和值的。 '|'是您的分隔符,因此请将其定义为:

    SEPARATOR = '|'
    

    你需要将其中的11个作为分隔符,所以要定义:

    DIVIDER = SEPARATOR * 11
    

我会更像这样编写代码:

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

但即使这样也可以改进。

当我们有三个以上的参数时,是时候重构和清理参数列表了。有很多方法可以做到这一点,但使用哈希是最常见的:

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,或者想知道如何在其他语言中完成它,我们可以查看收到的键,然后查看它们的相关值,如果不是看起来很好提出异常,而不是返回虚假价值。

为了简化操作,我将使用在Core Extensions中找到的Active Support的blank?方法:

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

以下是对方法的各种版本的调用,以及返回的相关校验和:

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 Keyword Arguments”。