Module: RomanianValidators::Cif

Defined in:
lib/romanianvalidators/cif.rb

Constant Summary collapse

TEST_KEY =
'753217532'.to_s.chars.map(&:to_i).reverse.freeze
FIRST_CIF =

used to break iteration when direction is :down

19

Class Method Summary collapse

Class Method Details

.control_sum(n, test_key) ⇒ Object



55
56
57
58
59
# File 'lib/romanianvalidators/cif.rb', line 55

def control_sum(n, test_key)
  control, *rest_digits = n.to_s.chars.map(&:to_i).reverse
  sum = rest_digits.zip(test_key).map { |a, b| a * b }.reduce(0, &:+)
  [control, sum]
end

.enumerator(start, direction = :up) ⇒ Object



40
41
42
43
44
45
46
47
48
49
# File 'lib/romanianvalidators/cif.rb', line 40

def enumerator(start, direction = :up)
  Enumerator.new do |yielder|
    memo = direction == :up ? next_valid_cif(start + 1) : prev_valid_cif(start - 1)
    loop do
      yielder << memo
      memo = direction == :up ? next_valid_cif(memo + 1) : prev_valid_cif(memo - 1)
      break if memo < FIRST_CIF
    end
  end.lazy
end

.next_valid_cif(cif) ⇒ Object



18
19
20
21
22
23
24
25
26
27
# File 'lib/romanianvalidators/cif.rb', line 18

def next_valid_cif(cif)
  control, sum = control_sum(cif, TEST_KEY)
  last_digit_of_next_cif = sum * 10 % 11 % 10

  if last_digit_of_next_cif < control
    next_valid_cif(((cif / 10) + 1) * 10)
  else
    replace_last_digit(cif, last_digit_of_next_cif)
  end
end

.prev_valid_cif(cif) ⇒ Object



29
30
31
32
33
34
35
36
37
38
# File 'lib/romanianvalidators/cif.rb', line 29

def prev_valid_cif(cif)
  control, sum = control_sum(cif, TEST_KEY)
  last_digit_of_next_cif = sum * 10 % 11 % 10

  if last_digit_of_next_cif > control
    next_valid_cif(((cif / 10) - 1) * 10)
  else
    replace_last_digit(cif, last_digit_of_next_cif)
  end
end

.replace_last_digit(number, digit) ⇒ Object



51
52
53
# File 'lib/romanianvalidators/cif.rb', line 51

def replace_last_digit(number, digit)
  ((number / 10).to_s + digit.to_s).to_i
end

.valid?(cif) ⇒ Boolean

Returns:

  • (Boolean)


8
9
10
11
12
# File 'lib/romanianvalidators/cif.rb', line 8

def valid?(cif)
  return false unless well_formed?(cif)
  control, sum = control_sum(cif, TEST_KEY)
  sum * 10 % 11 % 10 == control
end

.well_formed?(cif) ⇒ Boolean

Returns:

  • (Boolean)


14
15
16
# File 'lib/romanianvalidators/cif.rb', line 14

def well_formed?(cif)
  cif.present? && (2..10).cover?(cif.size) && (cif =~ /[^0-9]/).nil?
end