Last active
November 29, 2021 07:46
-
-
Save trietle/62fe5c4378780b04dec1 to your computer and use it in GitHub Desktop.
Simple Luhn algorithm with ruby
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Luhn | |
class << self | |
# Write a function that takes one parameter, the credit card number, and returns true or false depending on | |
# whether the number is a valid number. | |
def is_luhn_valid?(card_number) | |
luhn_checksum(card_number).zero? | |
end | |
# write a second function that takes a | |
# number of any length and calculates the Luhn check digit and returns the original | |
# number with the check digit appended on the end. | |
def calculate_luhn(partial_card_number) | |
card_number = partial_card_number.to_i * 10 | |
check_digit = luhn_checksum(card_number) | |
appended_number = check_digit.zero? ? check_digit : (10 - check_digit) | |
card_number + appended_number | |
end | |
private | |
def digits_of(n) | |
n.to_s.split(//).map(&:to_i) | |
end | |
# get digits by following rule | |
# double the value of every second digit | |
# if the product of this doubling operation is greater than 9 (e.g., 8 × 2 = 16), | |
# then sum the digits of the products (e.g., 16: 1 + 6 = 7, 18: 1 + 8 = 9). | |
def get_digits(card_number) | |
numbers = digits_of(card_number) | |
numbers.reverse.map.with_index do |n, i| | |
if i.odd? | |
t = n*2 # double second digits | |
t > 9 ? digits_of(t).inject(:+) : t | |
else | |
n | |
end | |
end | |
end | |
def sum_of_digits(card_number) | |
get_digits(card_number).inject(:+) | |
end | |
def luhn_checksum(card_number) | |
# computing the sum of digits then computing 9 times that value modulo 10 (in equation form, (67 × 9 mod 10)) | |
sum_of_digits(card_number) % 10 | |
end | |
end | |
end | |
Luhn.is_luhn_valid?(123451234512348) => true | |
Luhn.is_luhn_valid?(1996008) => true | |
Luhn.is_luhn_valid?(20239) => fase | |
Luhn.calculate_luhn(12345123451234) => 123451234512348 | |
Luhn.calculate_luhn(199600) => 1996008 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment