Search code examples
rubyluhn

Luhn Algorithm- Returning True for a False Credit Card


Having a little issue with my code to see if a credit card number adheres to the Luhn Algorithm. The code is returning true when the Credit Card is divisible by 10, but also is returning true when the CC number is not divisible by 10. I have printed out the final sum to make sure the numbers were actually adding to the sum variable, and they seem to be.. Below is my code. I know it can be cleaner, but at this stage I would like to see it work first.

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

Here is how it is being called:

it 'returns false for a bad card' do
  card = CreditCard.new(4408041234567892)
  card.check_card.should eq false
end

Solution

  • This is your code, commented and adapted to behave like the 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