cpf_cnpj_tools 0.2.2 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0b334d9f2cd553e996b9146601f3a3cafed9108379c716c4fb087ed2d5ae1472
4
- data.tar.gz: e6631210c24a518bdac6493147bf3e47ce6f0eaf54ed0b405138cad48fa7bca1
3
+ metadata.gz: 960e2816d23cd9e748a8b09c2c9938b1528b68659e9e278d2a9b521428701b68
4
+ data.tar.gz: 211d39ed878ae4417c0b242dc42d6db1e8e94c55c3b95859a9729e79d9db266b
5
5
  SHA512:
6
- metadata.gz: c7abd8c9649f3b3f8a485edf164b397449d5f5f2fd6b5dc1b320bbeddab48faa3a4790ad04d48284f87f1be22b677f96f4e2604ae1754c426f8e08615976047a
7
- data.tar.gz: '08c10b9bd37f4441946100f8a1ba21e25ead5aacd5037d415b440f526ce381d11fd413a72204d79766e85366711ebc45135d90aad7f278d227d4416ef1961be4'
6
+ metadata.gz: c2b1e1db0a91f2eac6a68f9d8c14364096c6e1d4b35c43b6d22b81ed295428e6483e702da84630553b0ec36cfc9c9b83960ff94f525e28470a0cd59a83a3eb19
7
+ data.tar.gz: f8f44be528bdd50da122e62d8a61ca4d763ae1a2bf614c06ff80fb25885aa1fbb2790ca6b290cfcb2318a3bdb1d5466a2d4701df534406fa42e45e4a080f17ee
data/.rubocop.yml CHANGED
@@ -20,7 +20,10 @@ Lint/ScriptPermission:
20
20
  Enabled: False
21
21
 
22
22
  Metrics/MethodLength:
23
- Max: 15
23
+ Max: 20
24
24
 
25
25
  Metrics/ClassLength:
26
- Max: 120
26
+ Max: 150
27
+
28
+ Metrics/AbcSize:
29
+ Enabled: false
data/README.md CHANGED
@@ -1,5 +1,8 @@
1
1
  # CpfCnpjTools
2
2
 
3
+ A simple and very efficient Ruby Gem to validate and generate CPF and CNPJ values.
4
+ ** It supports the new alphanumeric CNPJ format!!! **
5
+
3
6
  ## Installation
4
7
 
5
8
  Install the gem and add to the application's Gemfile by executing:
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module CpfCnpjTools
4
- VERSION = "0.2.2"
4
+ VERSION = "1.0.0"
5
5
  end
@@ -8,6 +8,15 @@ module CpfCnpjTools
8
8
  # Class responsible for generating and
9
9
  # validating CPF and CNPJ numbers
10
10
  class Generator
11
+ BLACKLIST_CPF = %w[
12
+ 00000000000 11111111111 22222222222 33333333333 44444444444
13
+ 55555555555 66666666666 77777777777 88888888888 99999999999
14
+ ].freeze
15
+
16
+ REGEX_CPF_FORMATTED = /^\d{3}\.\d{3}\.\d{3}-\d{2}$/.freeze
17
+ REGEX_CNPJ_FORMATTED = %r{^[A-Za-z0-9]{2}\.[A-Za-z0-9]{3}\.[A-Za-z0-9]{3}/[A-Za-z0-9]{4}-\d{2}$}.freeze
18
+ REGEX_CNPJ_UNFORMATTED = /^[A-Z0-9]{12}\d{2}$/.freeze
19
+
11
20
  CPF1DIGIT = [10, 9, 8, 7, 6, 5, 4, 3, 2].freeze
12
21
  CPF2DIGIT = [11, 10, 9, 8, 7, 6, 5, 4, 3, 2].freeze
13
22
  CNPJ1DIGIT = [5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2].freeze
@@ -18,25 +27,35 @@ module CpfCnpjTools
18
27
  # @param {Boolean} formatted
19
28
  # @return String
20
29
  def generate_cpf(formatted: true)
21
- base = generate_base
22
- base << generate_identifier(base, true)
23
- base << generate_identifier(base, false)
24
- return base.join unless formatted
30
+ # Destructure the two arrays returned by the new generate_base
31
+ base_chars, base_values = generate_base(cnpj: false)
32
+
33
+ # Calculate the verification digits using base_values
34
+ first_digit = generate_identifier(base_values, true)
35
+ second_digit = generate_identifier(base_values + [first_digit], false)
36
+
37
+ # Combine the characters with the calculated digits
38
+ result = (base_chars + [first_digit, second_digit]).join
39
+ return result unless formatted
25
40
 
26
- format(base.join)
41
+ format(result)
27
42
  end
28
43
 
29
44
  ##
30
- # Method for generating valid CNPJ numbers
45
+ # Method for generating valid CNPJ numbers (Numeric)
46
+ # Standard numeric CNPJs remain 100% valid under the new rules.
31
47
  # @param {Boolean} formatted
32
48
  # @return String
33
- def generate_cnpj(formatted: true)
34
- base = generate_base(cnpj: true)
35
- base << generate_identifier(base, true, cpf: false)
36
- base << generate_identifier(base, false, cpf: false)
37
- return base.join unless formatted
49
+ def generate_cnpj(formatted: true, alphanumeric: false)
50
+ base_chars, base_values = generate_base(cnpj: true, alphanumeric: alphanumeric)
38
51
 
39
- format(base.join)
52
+ first_digit = generate_identifier(base_values, true, cpf: false)
53
+ second_digit = generate_identifier(base_values + [first_digit], false, cpf: false)
54
+
55
+ result = (base_chars + [first_digit, second_digit]).join
56
+ return result unless formatted
57
+
58
+ format(result)
40
59
  end
41
60
 
42
61
  ##
@@ -44,28 +63,41 @@ module CpfCnpjTools
44
63
  # @param {String, Integer} cpf
45
64
  # @return bool
46
65
  def cpf_valid?(cpf)
66
+ unformatted = remove_formatting(cpf.to_s)
67
+ return false if BLACKLIST_CPF.include?(unformatted)
68
+
47
69
  cpf_array = remove_formatting(cpf.to_s).split("").map!(&:to_i)
70
+ return false if cpf_array.length != 11
71
+
48
72
  first_digit = cpf_array[-2]
49
73
  second_digit = cpf_array[-1]
50
74
  base_cpf = cpf_array[0..8]
51
75
  calculated_first_digit = generate_identifier(base_cpf, true)
52
76
  calculated_second_digit = generate_identifier(base_cpf << calculated_first_digit, false)
77
+
53
78
  return false if (first_digit != calculated_first_digit) || (second_digit != calculated_second_digit)
54
79
 
55
80
  true
56
81
  end
57
82
 
58
83
  ##
59
- # Method for validating CNPJ numbers.
60
- # @param {Integer, String} cpf
84
+ # Method for validating CNPJ numbers (Handles Alphanumeric).
85
+ # @param {Integer, String} cnpj
61
86
  # @return bool
62
87
  def cnpj_valid?(cnpj)
63
- cnpj_array = remove_formatting(cnpj.to_s).split("").map!(&:to_i)
64
- first_digit = cnpj_array[-2]
65
- second_digit = cnpj_array[-1]
66
- base_cnpj = cnpj_array[0..11]
67
- calculated_first_digit = generate_identifier(base_cnpj, true, cpf: false)
68
- calculated_second_digit = generate_identifier(base_cnpj << calculated_first_digit, false, cpf: false)
88
+ unformatted = remove_formatting(cnpj.to_s).upcase
89
+
90
+ return false unless unformatted.match?(REGEX_CNPJ_UNFORMATTED)
91
+
92
+ cnpj_array = unformatted.chars
93
+ first_digit = cnpj_array[-2].to_i
94
+ second_digit = cnpj_array[-1].to_i
95
+
96
+ base_cnpj_values = cnpj_array[0..11].map { |char| cnpj_char_to_value(char) }
97
+
98
+ calculated_first_digit = generate_identifier(base_cnpj_values, true, cpf: false)
99
+ calculated_second_digit = generate_identifier(base_cnpj_values + [calculated_first_digit], false, cpf: false)
100
+
69
101
  return false if (first_digit != calculated_first_digit) || (second_digit != calculated_second_digit)
70
102
 
71
103
  true
@@ -78,20 +110,19 @@ module CpfCnpjTools
78
110
  # @return bool
79
111
  def formatted?(cpf_or_cnpj)
80
112
  number = cpf_or_cnpj.to_s
81
- return true if (number =~ /\d{3}\.\d{3}\.\d{3}-\d{2}/) || (number =~ %r{\d{2}\.\d{3}\.\d{3}/0001-\d{2}})
113
+ return true if number =~ REGEX_CPF_FORMATTED
114
+ return true if number =~ REGEX_CNPJ_FORMATTED
82
115
 
83
116
  false
84
117
  end
85
118
 
86
119
  ##
87
120
  # Returns an unformatted CPF or CNPJ.
88
- # If the value is already unformatted,
89
- # the method returns the value passed as argument.
90
121
  # @param {String, Integer} cpf_or_cnpj
91
122
  # @return String
92
123
  def remove_formatting(cpf_or_cnpj)
93
124
  unformatted = cpf_or_cnpj.to_s.delete("./-")
94
- return unformatted unless unformatted.nil?
125
+ return unformatted unless unformatted.empty?
95
126
 
96
127
  cpf_or_cnpj.to_s
97
128
  end
@@ -102,12 +133,12 @@ module CpfCnpjTools
102
133
  # @return String
103
134
  def format(cpf_or_cnpj)
104
135
  if cpf_valid?(cpf_or_cnpj)
105
- cpf = cpf_or_cnpj.to_s.dup
136
+ cpf = remove_formatting(cpf_or_cnpj).dup
106
137
  cpf.insert(3, ".")
107
138
  .insert(7, ".")
108
139
  .insert(-3, "-")
109
140
  elsif cnpj_valid?(cpf_or_cnpj)
110
- cnpj = cpf_or_cnpj.to_s.dup
141
+ cnpj = remove_formatting(cpf_or_cnpj).upcase.dup
111
142
  cnpj.insert(2, ".")
112
143
  .insert(6, ".")
113
144
  .insert(10, "/")
@@ -135,31 +166,48 @@ module CpfCnpjTools
135
166
  # @param {Integer} number
136
167
  # @param {bool} formatted
137
168
  # @return {Array[String]}
138
- def generate_array_of_cnpj(number, formatted: true)
169
+ def generate_array_of_cnpj(number, formatted: true, alphanumeric: false)
139
170
  array = []
140
171
  number.times do
141
- array << generate_cnpj(formatted: formatted)
172
+ array << generate_cnpj(formatted: formatted, alphanumeric: alphanumeric)
142
173
  end
143
174
  array
144
175
  end
145
176
 
146
177
  private
147
178
 
179
+ ##
180
+ # Converts a character to its mathematical value for CNPJ calculation.
181
+ # Numbers retain face value. Letters use ASCII value - 48.
182
+ # @param char (String)
183
+ # @return Integer
184
+ def cnpj_char_to_value(char)
185
+ char.match?(/[A-Z]/) ? char.ord - 48 : char.to_i
186
+ end
187
+
148
188
  ##
149
189
  # Generate the first numbers of CPF/CNPJ
150
190
  # randomly.
151
191
  # @param cnpj (Boolean)
152
192
  # @return (Array)
153
- def generate_base(cnpj: false)
154
- base_number = []
155
- 9.times do
156
- base_number << rand(10)
157
- end
193
+ def generate_base(cnpj: false, alphanumeric: false)
194
+ pool = ("0".."9").to_a
195
+ pool += ("A".."Z").to_a if alphanumeric
196
+
197
+ base_chars = []
198
+
158
199
  if cnpj
159
- base_number.delete_at(-1)
160
- base_number.push 0, 0, 0, 1
200
+ 8.times { base_chars << pool.sample }
201
+ 4.times { base_chars << pool.sample }
202
+ else
203
+ 9.times { base_chars << rand(10).to_s }
161
204
  end
162
- base_number
205
+
206
+ base_values = base_chars.map do |char|
207
+ char.match?(/[A-Z]/) ? char.ord - 48 : char.to_i
208
+ end
209
+
210
+ [base_chars, base_values]
163
211
  end
164
212
 
165
213
  ##
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cpf_cnpj_tools
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aria Diniz
8
- autorequire:
9
8
  bindir: exe
10
9
  cert_chain: []
11
- date: 2023-01-02 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies: []
13
12
  description: With this tool you will be able to generate and validate brazilian CPF
14
13
  and CNPJ numbers.
@@ -37,7 +36,6 @@ metadata:
37
36
  documentation_uri: https://rubydoc.info/gems/cpf_cnpj_tools
38
37
  homepage_uri: https://github.com/ariasdiniz/cpf_cnpj_tools
39
38
  source_code_uri: https://github.com/ariasdiniz/cpf_cnpj_tools
40
- post_install_message:
41
39
  rdoc_options: []
42
40
  require_paths:
43
41
  - lib
@@ -52,8 +50,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
52
50
  - !ruby/object:Gem::Version
53
51
  version: '0'
54
52
  requirements: []
55
- rubygems_version: 3.3.26
56
- signing_key:
53
+ rubygems_version: 4.0.10
57
54
  specification_version: 4
58
55
  summary: A tool for generating and validating CPF/CNPJ numbers
59
56
  test_files: []