diff --git a/doc/unreleased/company.md b/doc/unreleased/company.md index dce4e982ba..32da99b85f 100644 --- a/doc/unreleased/company.md +++ b/doc/unreleased/company.md @@ -56,4 +56,7 @@ Faker::Company.south_african_pty_ltd_registration_number #=> "5301/714689/07" Faker::Company.south_african_close_corporation_registration_number #=> "CK74/7585/23" Faker::Company.south_african_listed_company_registration_number #=> "7039/3135/06" Faker::Company.south_african_trust_registration_number #=> "IT38/6489900" + +# Generate a Brazilian company number (CNPJ) +Faker::Company.brazilian_company_number #=> "18553414000618" ``` diff --git a/lib/faker/company.rb b/lib/faker/company.rb index e24593252f..41923027e3 100644 --- a/lib/faker/company.rb +++ b/lib/faker/company.rb @@ -153,6 +153,19 @@ def south_african_trust_registration_number regexify(/IT\d{2,4}\/\d{2,10}/) end + def brazilian_company_number + digits = Array.new(8) { Faker::Number.digit.to_i } + [0, 0, 0, Faker::Number.non_zero_digit.to_i] + + factors = [5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2, 6].cycle + + 2.times do + checksum = digits.inject(0) { |acc, digit| acc + digit * factors.next } % 11 + digits << (checksum < 2 ? 0 : 11 - checksum) + end + + digits.join + end + private # Mod11 functionality from https://github.com/badmanski/mod11/blob/master/lib/mod11.rb diff --git a/test/test_faker_company.rb b/test/test_faker_company.rb index 2d24a08e36..55224617b7 100644 --- a/test/test_faker_company.rb +++ b/test/test_faker_company.rb @@ -159,6 +159,28 @@ def test_luhn_algorithm assert((luhn_checksum(even_control) % 10).zero?) end + def test_brazilian_company_number + sample = @tester.brazilian_company_number + + assert_match(/^\d{14}$/, sample) + + digit_sum = sample[0..11].chars.each_with_index.inject(0) do |acc, (digit, i)| + factor = 2 + (3 - i) % 8 + acc + digit.to_i * factor + end + remainder = digit_sum % 11 + first_digit = remainder < 2 ? '0' : (11 - remainder).to_s + assert_equal sample[12], first_digit + + digit_sum = sample[0..12].chars.each_with_index.inject(0) do |acc, (digit, i)| + factor = 2 + (4 - i) % 8 + acc + digit.to_i * factor + end + remainder = digit_sum % 11 + second_digit = remainder < 2 ? '0' : (11 - remainder).to_s + assert_equal sample[13], second_digit + end + private def czech_o_n_checksum(org_no)