我的代码有点问题,看看信用卡号码是否符合Luhn算法。当信用卡可被10整除时,代码返回true,但当CC数不能被10整除时,代码也返回true。我打印出最后的总和,以确保数字实际上是加到sum变量,并且它们似乎是..下面是我的代码。我知道它可以更干净,但在这个阶段我希望看到它先工作。
def check_card
c_num= []
sum=0
s_numbers=@card_numbers.to_s.reverse.split("")
s_numbers.each_slice(2) do |x|
c_num << (x.last.to_s.to_i*2)
c_num << (x.first.to_s.to_i)
end
c_num.each do |num|
if num.to_i > 9
sum+= (num.to_i % 10)+1
else
sum += num.to_i
end
end
sum % 10==0
end
以下是它的调用方式:
it 'returns false for a bad card' do
card = CreditCard.new(4408041234567892)
card.check_card.should eq false
end
答案 0 :(得分:1)
现在又出现了另一个答案,我将提供建议的编码。这不能回答你的问题,但我认为它可能会引起人们的兴趣并且不能很好地将它放在评论中,因为格式限制。
def valid?(card)
return false unless card =~ /^\d+$/ # Ensure card contains only digits
arr = card.split('').reverse.each_with_index.map {|d, index| (index.odd? ? 2*(d.to_i) : d.to_i)}
(arr.join.split('').inject(0) {|tot, d| tot + d.to_i}) % 10 == 0
end
valid?("1234567890123456") => false
答案 1 :(得分:0)
这是您的代码,经过评论和调整,表现得像wikipedia description。
def check_card(str) #creditcardnumber as argument
c_num = []
sum = 0
s_numbers = str.split("") #no reversing. str.split("").map(&:to_i) would save a lot of to_i's later on...
checksum = s_numbers.pop.to_i #chop off last digit, store as checksum
s_numbers.each_slice(2) do |x|
c_num << (x.last.to_s.to_i*2)
c_num << (x.first.to_s.to_i)
end
c_num.each do |num|
if num.to_i > 9
sum+= (num.to_i % 10)+1
else
sum += num.to_i
end
end
(sum * 9) % 10 == checksum
end
p check_card("79927398713") #=> true
答案 2 :(得分:0)
您似乎将测试的输出与check_card
方法的输出混淆。您已确认sum == 69
,因此sum % 10 == 0
应返回false
(除非Ruby的数学运算被破坏),因此您的check_card
方法也应返回false
- 添加测试块中行puts card.check_card
之后(但在下一行之前)的行card = CreditCard.new(4408041234567892)
以显示返回的值。
下一行card.check_card.should eq false
断言返回的值“应该等于”false
- 也就是说,check_card
的{{1}}值为false
{1}},如果是这样,将返回@card_numbers
。我怀疑您看到测试出现true
并认为该方法返回的值不正确true
。
在没有看到测试结果的情况下,这当然只是猜测。但是,您的代码似乎是正确的,对我来说,给出了正确的结果。
答案 3 :(得分:0)
发布我的答案,因为我觉得它很干净:
def valid?(card_number)
return false unless card_number !~ /\D/
card_numbers = card_number.reverse.split("").map(&:to_i)
sum = 0
card_numbers.each_with_index do |num, i|
if i.even?
sum += num
else
sum += (num *= 2) > 9 ? num.divmod(10).inject(:+) : num
end
end
sum % 10 == 0
end