Module: Cnpj::Alfanumerico

Defined in:
lib/cnpj/alfanumerico.rb,
lib/cnpj/alfanumerico/version.rb

Constant Summary collapse

BODY_LENGTH =
12
FULL_LENGTH =
14
FIRST_WEIGHTS =
[5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2].freeze
SECOND_WEIGHTS =
[6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2].freeze
BODY_PATTERN =
/\A[0-9A-Z]{12}\z/.freeze
FULL_PATTERN =
/\A[0-9A-Z]{12}[0-9]{2}\z/.freeze
FORMATTED_PATTERN =
/\A([0-9A-Z]{2})([0-9A-Z]{3})([0-9A-Z]{3})([0-9A-Z]{4})([0-9]{2})\z/.freeze
VERSION =
"0.1.5"

Class Method Summary collapse

Class Method Details

.assert_valid!(value) ⇒ Object

Raises:

  • (ArgumentError)


55
56
57
58
59
60
# File 'lib/cnpj/alfanumerico.rb', line 55

def assert_valid!(value)
  normalized = normalize(value)
  raise ArgumentError, "Invalid CNPJ." unless valid?(normalized)

  normalized
end

.calculate_check_digits(base) ⇒ Object

Raises:

  • (ArgumentError)


31
32
33
34
35
36
37
38
39
# File 'lib/cnpj/alfanumerico.rb', line 31

def calculate_check_digits(base)
  normalized = normalize(base)
  raise ArgumentError, "Base CNPJ must contain exactly 12 alphanumeric characters." unless BODY_PATTERN.match?(normalized)

  first_digit = compute_digit(normalized, FIRST_WEIGHTS)
  second_digit = compute_digit("#{normalized}#{first_digit}", SECOND_WEIGHTS)

  "#{first_digit}#{second_digit}"
end

.char_value(char) ⇒ Object

Raises:

  • (ArgumentError)


23
24
25
26
27
28
29
# File 'lib/cnpj/alfanumerico.rb', line 23

def char_value(char)
  code = char.to_s.upcase.ord
  return code - 48 if code.between?(48, 57)
  return code - 48 if code.between?(65, 90)

  raise ArgumentError, "Invalid CNPJ character: #{char}"
end

.format(value) ⇒ Object

Raises:

  • (ArgumentError)


62
63
64
65
66
67
68
# File 'lib/cnpj/alfanumerico.rb', line 62

def format(value)
  normalized = normalize(value)
  raise ArgumentError, "CNPJ must contain 12 alphanumeric characters followed by 2 numeric check digits." unless FULL_PATTERN.match?(normalized)

  match = FORMATTED_PATTERN.match(normalized)
  "#{match[1]}.#{match[2]}.#{match[3]}/#{match[4]}-#{match[5]}"
end

.formatted?(value) ⇒ Boolean

Returns:

  • (Boolean)


19
20
21
# File 'lib/cnpj/alfanumerico.rb', line 19

def formatted?(value)
  /\A[0-9A-Z]{2}\.[0-9A-Z]{3}\.[0-9A-Z]{3}\/[0-9A-Z]{4}-[0-9]{2}\z/.match?(value.to_s.upcase)
end

.generate(base) ⇒ Object



41
42
43
44
# File 'lib/cnpj/alfanumerico.rb', line 41

def generate(base)
  normalized = normalize(base)
  "#{normalized}#{calculate_check_digits(normalized)}"
end

.normalize(value) ⇒ Object



15
16
17
# File 'lib/cnpj/alfanumerico.rb', line 15

def normalize(value)
  value.to_s.gsub(/[^0-9A-Za-z]/, "").upcase
end

.split(value) ⇒ Object

Raises:

  • (ArgumentError)


70
71
72
73
74
75
76
77
78
79
# File 'lib/cnpj/alfanumerico.rb', line 70

def split(value)
  normalized = normalize(value)
  raise ArgumentError, "Invalid CNPJ." unless FULL_PATTERN.match?(normalized)

  {
    raiz: normalized[0, 8],
    ordem: normalized[8, 4],
    dv: normalized[12, 2]
  }
end

.valid?(value) ⇒ Boolean

Returns:

  • (Boolean)


46
47
48
49
50
51
52
53
# File 'lib/cnpj/alfanumerico.rb', line 46

def valid?(value)
  normalized = normalize(value)
  return false unless FULL_PATTERN.match?(normalized)

  base = normalized[0, BODY_LENGTH]
  dv = normalized[BODY_LENGTH, 2]
  calculate_check_digits(base) == dv
end