cpf_cnpj 0.6.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d7b0bd493ddd22ed0ebe7128fd0e8dc17c8ff15bfb1209300e1ce60ae03b2c6b
4
- data.tar.gz: c2f7a21d000907e8779790d8b72ce6177b58ddaa2fb0f369941d3e3d1989eae1
3
+ metadata.gz: af6460ddd8fccffc42d4f642c5a511c01f484a7ca7103d2d5cc4edcc23fbeae6
4
+ data.tar.gz: e314c5cf1b043811a0ed804a7634a64f5079e833160385768dd3cd113a02b2d6
5
5
  SHA512:
6
- metadata.gz: b58f3e8547dda2131b290a4db50c0c84da0ccaf266ebd241cef0d34e43eb935d0e31d1310185749f9a929d19db01136484d1b54bbb1abb9c41d351409c6b685b
7
- data.tar.gz: 3d62c15ab2f3b0be301a55a5328368bcca1ccf1d2b453c3e28c01fa868dc10c403690b2ee2d33cd0bba375271a8a20b2415a77f477d3c3d2b941fad4049f8417
6
+ metadata.gz: 9389e3356414b201c0bd9eeb1eef63e07c1bf869a1fd1fa30c3ef90d105711f466343f3cef8a7ea8899bbdfdfa4586725f10c67022bd7325ee39a8519668f8f2
7
+ data.tar.gz: 41c4f3ee6632bc631070ae5879506d4ed78711aa6bb645302aa9b5bf8c9d235e7bdde042268ffe4b3fa412c43434cac00fae03a9dde9fd212609750cfe735495
data/README.md CHANGED
@@ -36,6 +36,12 @@ Or install it yourself as:
36
36
  This library has the same API for both CNPJ/CPF, so only one of them is
37
37
  documented below.
38
38
 
39
+ > [!NOTE]
40
+ >
41
+ > This library already supports the new alphanumeric CNPJ algorithm that will be
42
+ > available starting July 2026. For more information, see
43
+ > <https://www.gov.br/receitafederal/pt-br/acesso-a-informacao/acoes-e-programas/programas-e-atividades/cnpj-alfanumerico>.
44
+
39
45
  ```ruby
40
46
  require "cpf_cnpj"
41
47
 
@@ -3,11 +3,13 @@
3
3
  class CNPJ
4
4
  class Formatter
5
5
  STRICT_REGEX = %r{[/.-]}.freeze
6
- LOOSE_REGEX = /[^\d]/.freeze
6
+ LOOSE_REGEX = /[^A-Z\d]/.freeze
7
+ REPLACE_REGEX = /
8
+ \A([A-Z\d]{2})([A-Z\d]{3})([A-Z\d]{3})([A-Z\d]{4})([A-Z\d]{2})\Z
9
+ /x.freeze
7
10
 
8
11
  def self.format(number)
9
- strip(number)
10
- .gsub(/\A(\d{2})(\d{3})(\d{3})(\d{4})(\d{2})\Z/, "\\1.\\2.\\3/\\4-\\5")
12
+ strip(number).gsub(REPLACE_REGEX, "\\1.\\2.\\3/\\4-\\5")
11
13
  end
12
14
 
13
15
  def self.strip(number, strict = false)
data/lib/cnpj.rb CHANGED
@@ -7,8 +7,8 @@ class CNPJ
7
7
 
8
8
  attr_reader :number, :strict
9
9
 
10
- REGEX = %r[\A\d{2}\.\d{3}.\d{3}/\d{4}-\d{2}\Z].freeze
11
- VALIDATION_SIZE_REGEX = /^\d{14}$/.freeze
10
+ REGEX = %r[\A[\dA-Z]{2}\.[\dA-Z]{3}.[\dA-Z]{3}/[\dA-Z]{4}-[\dA-Z]{2}\Z].freeze
11
+ VALIDATION_SIZE_REGEX = /^[A-Z\d]{14}$/.freeze
12
12
  NUMBER_SIZE = 12
13
13
 
14
14
  DENYLIST = %w[
@@ -33,13 +33,18 @@ class CNPJ
33
33
  end
34
34
 
35
35
  def self.generate(formatted = false)
36
- number = CpfCnpj::Generator.generate(NUMBER_SIZE, VerifierDigit)
37
- cnpj = new(number)
36
+ numbers = Array("0".."9") + ("A".."Z").to_a
37
+ digits = Array.new(NUMBER_SIZE) { numbers.sample }
38
+ numeric_digits = digits.map {|d| d.ord - 48 }
39
+ numeric_digits << VerifierDigit.generate(numeric_digits)
40
+ numeric_digits << VerifierDigit.generate(numeric_digits)
41
+
42
+ cnpj = new((digits + numeric_digits[-2, 2]).join)
38
43
  formatted ? cnpj.formatted : cnpj.stripped
39
44
  end
40
45
 
41
46
  def initialize(number, strict = false)
42
- @number = number.to_s
47
+ @number = number.to_s.upcase
43
48
  @strict = strict
44
49
  end
45
50
 
@@ -64,6 +69,7 @@ class CNPJ
64
69
  end
65
70
 
66
71
  return false unless stripped.match?(VALIDATION_SIZE_REGEX)
72
+
67
73
  return false if DENYLIST.include?(stripped)
68
74
 
69
75
  digits = numbers[0...NUMBER_SIZE]
@@ -79,10 +85,16 @@ class CNPJ
79
85
  alias eql? ==
80
86
 
81
87
  def number_without_verifier
82
- numbers[0...NUMBER_SIZE].join
88
+ stripped_chars[0...NUMBER_SIZE].join
89
+ end
90
+
91
+ private def stripped_chars
92
+ @stripped_chars ||= stripped.chars
83
93
  end
84
94
 
85
95
  private def numbers
86
- @numbers ||= stripped.each_char.to_a.map(&:to_i)
96
+ @numbers ||= stripped_chars.map do |number|
97
+ number.ord - 48
98
+ end
87
99
  end
88
100
  end
data/lib/cpf.rb CHANGED
@@ -34,8 +34,12 @@ class CPF
34
34
  end
35
35
 
36
36
  def self.generate(formatted = false)
37
- number = CpfCnpj::Generator.generate(NUMBER_SIZE, VerifierDigit)
38
- cpf = new(number)
37
+ numbers = Array(0..9)
38
+ digits = Array.new(NUMBER_SIZE) { numbers.sample }
39
+ digits << VerifierDigit.generate(digits)
40
+ digits << VerifierDigit.generate(digits)
41
+
42
+ cpf = new(digits.join)
39
43
  formatted ? cpf.formatted : cpf.stripped
40
44
  end
41
45
 
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module CpfCnpj
4
- VERSION = "0.6.0"
4
+ VERSION = "1.0.0"
5
5
  end
6
6
 
7
7
  class CPF
data/lib/cpf_cnpj.rb CHANGED
@@ -2,7 +2,6 @@
2
2
 
3
3
  require "English"
4
4
  require "optparse"
5
- require "cpf_cnpj/generator"
6
5
  require "cpf_cnpj/cli"
7
6
  require "cpf_cnpj/version"
8
7
  require "cpf"
@@ -72,7 +72,7 @@ module CNPJCli
72
72
  exit_status, stdout = run_command(["-gs"])
73
73
 
74
74
  assert_equal 0, exit_status
75
- assert_match(/\A\d{14}\Z/, stdout)
75
+ assert_match(/\A[A-Z\d]{14}\Z/, stdout)
76
76
  end
77
77
  end
78
78
 
data/test/cnpj_test.rb CHANGED
@@ -30,6 +30,18 @@ class CnpjTest < Minitest::Test
30
30
  assert CNPJ.valid?(number)
31
31
  end
32
32
 
33
+ test "validates formatted strings with letters" do
34
+ number = "12.ABC.345/01DE-35"
35
+
36
+ assert CNPJ.valid?(number)
37
+ end
38
+
39
+ test "validates formatted strings with letters (lowercase)" do
40
+ number = "12.abc.345/01de-35"
41
+
42
+ assert CNPJ.valid?(number)
43
+ end
44
+
33
45
  test "formats number" do
34
46
  cnpj = CNPJ.new("54550752000155")
35
47
 
@@ -50,14 +62,17 @@ class CnpjTest < Minitest::Test
50
62
  end
51
63
 
52
64
  test "generates formatted number" do
53
- assert_match %r[\A\d{2}\.\d{3}\.\d{3}/\d{4}-\d{2}\z], CNPJ.generate(true)
65
+ assert_match(
66
+ %r[\A[A-Z\d]{2}\.[A-Z\d]{3}\.[A-Z\d]{3}/[A-Z\d]{4}-[A-Z\d]{2}\z],
67
+ CNPJ.generate(true)
68
+ )
54
69
  end
55
70
 
56
71
  test "generates stripped number" do
57
- assert_match(/\A\d{14}\z/, CNPJ.generate)
72
+ assert_match(/\A[A-Z\d]{14}\z/, CNPJ.generate)
58
73
  end
59
74
 
60
- test "rejects strings" do
75
+ test "rejects invalid strings" do
61
76
  refute CNPJ.valid?("aa.bb.ccc/dddd-ee")
62
77
  end
63
78
 
@@ -66,6 +81,8 @@ class CnpjTest < Minitest::Test
66
81
  refute CNPJ.valid?("54....550....752///0001---55", strict: true)
67
82
  assert CNPJ.valid?("54.550.752/0001-55", strict: true)
68
83
  assert CNPJ.valid?("54550752000155", strict: true)
84
+ assert CNPJ.valid?("12.ABC.345/01DE-35", strict: true)
85
+ assert CNPJ.valid?("12ABC34501DE35", strict: true)
69
86
  end
70
87
 
71
88
  test "compare objects by their numeric value" do
@@ -80,8 +97,9 @@ class CnpjTest < Minitest::Test
80
97
  end
81
98
 
82
99
  test "returns number without verifier" do
83
- cnpj = CNPJ.new("54550752000155")
84
-
85
- assert_equal "545507520001", cnpj.number_without_verifier
100
+ assert_equal "545507520001",
101
+ CNPJ.new("54550752000155").number_without_verifier
102
+ assert_equal "12ABC34501DE",
103
+ CNPJ.new("12.ABC.345/01DE-35").number_without_verifier
86
104
  end
87
105
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cpf_cnpj
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nando Vieira
@@ -110,7 +110,6 @@ files:
110
110
  - lib/cpf/verifier_digit.rb
111
111
  - lib/cpf_cnpj.rb
112
112
  - lib/cpf_cnpj/cli.rb
113
- - lib/cpf_cnpj/generator.rb
114
113
  - lib/cpf_cnpj/version.rb
115
114
  - test/cnpj/cli_test.rb
116
115
  - test/cnpj/formatter_test.rb
@@ -1,14 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module CpfCnpj
4
- class Generator
5
- NUMBERS = Array(0..9).freeze
6
-
7
- def self.generate(size, verifier_digit_generator)
8
- numbers = Array.new(size) { NUMBERS.sample }
9
- numbers << verifier_digit_generator.generate(numbers)
10
- numbers << verifier_digit_generator.generate(numbers)
11
- numbers.join
12
- end
13
- end
14
- end