diff --git a/lib/faker/company.rb b/lib/faker/company.rb index f5b220a3af..53c2bc0960 100644 --- a/lib/faker/company.rb +++ b/lib/faker/company.rb @@ -178,7 +178,7 @@ def mod11(number) def luhn_algorithm(number) multiplications = [] - number.split(//).each_with_index do |digit, i| + number.reverse.split(//).each_with_index do |digit, i| multiplications << if i.even? digit.to_i * 2 else diff --git a/test/test_faker_company.rb b/test/test_faker_company.rb index cb6e3946e6..2d24a08e36 100644 --- a/test/test_faker_company.rb +++ b/test/test_faker_company.rb @@ -144,6 +144,21 @@ def test_south_african_trust_registration_number ) end + def test_luhn_algorithm + # Odd length base for luhn algorithm + odd_base = Faker::Number.number([5, 7, 9, 11, 13].sample) + odd_luhn_complement = @tester.send(:luhn_algorithm, odd_base) + odd_control = "#{odd_base}#{odd_luhn_complement}" + + # Even length base for luhn algorithm + even_base = Faker::Number.number([4, 6, 8, 10, 12].sample) + even_luhn_complement = @tester.send(:luhn_algorithm, even_base) + even_control = "#{even_base}#{even_luhn_complement}" + + assert((luhn_checksum(odd_control) % 10).zero?) + assert((luhn_checksum(even_control) % 10).zero?) + end + private def czech_o_n_checksum(org_no) @@ -163,4 +178,13 @@ def abn_checksum(abn) (i.zero? ? n - 1 : n) * abn_weights[i] end.inject(:+) end + + def luhn_checksum(luhn) + luhn_split = luhn.each_char.map(&:to_i).reverse.each_with_index.map do |n, i| + x = i.odd? ? n * 2 : n + x > 9 ? x - 9 : x + end + + luhn_split.compact.inject(0) { |sum, x| sum + x } + end end