Skip to content

Commit

Permalink
Adding Faker::IDNumber.brazilian_citizen_number (faker-ruby#1382)
Browse files Browse the repository at this point in the history
  • Loading branch information
bschettino authored and vbrazo committed Oct 6, 2018
1 parent c6b9474 commit 7ede721
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 0 deletions.
3 changes: 3 additions & 0 deletions doc/id_number.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,7 @@ Faker::IDNumber.valid_south_african_id_number #=> "8105128870184"

# Generate an invalid South African ID Number
Faker::IDNumber.invalid_south_african_id_number #=> "1642972065088"

# Generate a Brazilian citizen number (CPF)
Faker::IDNumber.brazilian_citizen_number #=> "53540542221"
```
15 changes: 15 additions & 0 deletions lib/faker/id_number.rb
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,13 @@ def invalid_south_african_id_number
[id_number, south_african_id_checksum_digit(id_number)].join
end

def brazilian_citizen_number
digits = Faker::Number.leading_zero_number(9) until digits&.match(/(\d)((?!\1)\d)+/)
first_digit = brazilian_citizen_number_checksum_digit(digits)
second_digit = brazilian_citizen_number_checksum_digit(digits + first_digit)
[digits, first_digit, second_digit].join
end

private

def south_african_id_checksum_digit(id_number)
Expand All @@ -95,6 +102,14 @@ def south_african_id_checksum_digit(id_number)
((10 - (total_sum % 10)) % 10).to_s
end

def brazilian_citizen_number_checksum_digit(digits)
digit_sum = digits.chars.each_with_index.inject(0) do |acc, (digit, i)|
acc + digit.to_i * (digits.size + 1 - i)
end * 10
remainder = digit_sum % 11
remainder == 10 ? '0' : remainder.to_s
end

def _translate(key)
parse("id_number.#{key}")
end
Expand Down
18 changes: 18 additions & 0 deletions test/test_faker_id_number.rb
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,24 @@ def test_invalid_south_african_id_number
end
end

def test_brazilian_citizen_number
sample = @tester.brazilian_citizen_number
assert_match(/^\d{11}$/, sample)
assert_match(/(\d)((?!\1)\d)+/, sample)
digit_sum = sample[0..8].chars.each_with_index.inject(0) do |acc, (digit, i)|
acc + digit.to_i * (10 - i)
end * 10
remainder = digit_sum % 11
first_digit = remainder == 10 ? '0' : remainder.to_s
assert_equal sample[9], first_digit
digit_sum = sample[0..9].chars.each_with_index.inject(0) do |acc, (digit, i)|
acc + digit.to_i * (11 - i)
end * 10
remainder = digit_sum % 11
second_digit = remainder == 10 ? '0' : remainder.to_s
assert_equal sample[10], second_digit
end

private

def south_african_id_number_to_date_of_birth_string(sample)
Expand Down

0 comments on commit 7ede721

Please sign in to comment.