cpf_cnpj_plus 0.2.0 → 0.3.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: 3471ac722167a65351c70e1e5d5cc0942bd915ba0420eaef56050778bc05809b
4
- data.tar.gz: d108eadcb37093bccfe1aca2b5ce65c5c4a1bfad4ebdb312a0d111fca8e0ff95
3
+ metadata.gz: da3b0a99c5007b263786ecff3baa97962e733b978c900b43fbe3221a6c6bd29e
4
+ data.tar.gz: 41d063f24c63805ce0e16cf824537436344166c906f45fcbd04d011519517161
5
5
  SHA512:
6
- metadata.gz: d4aa54004da35e9333beb2fdfce720ffec85f171cee7beb9d1204e27c576dddd7d319659581ed20569810c73468fe84c5633674536b3fa6870bee22b76c0e499
7
- data.tar.gz: 22d11338440ada66d77bd93d05b74297a6a10642f25f7e634d93b44b595e6b08c55ffe06cdb5ca5f74305e44133f3f6f54d32a09001850a084a30c98b57f39be
6
+ metadata.gz: 530da6d176545b6c82b6b9226e2bb43925b76742d35ab66a38826ef3eacba32d90494ebe8447fc49aa3bf332ad01e919f984491d4d3972b376f07f059f02680d
7
+ data.tar.gz: 39b949f17039432825917e19c595f7b0ec90ccada9d389eef7dfa4f9bc4bac55ce0381d22288339ccacdd40e18c67e84a5ec415ebd95087929e604f4f0295e21
data/.rubocop.yml CHANGED
@@ -6,3 +6,6 @@ Style/StringLiterals:
6
6
 
7
7
  Style/StringLiteralsInInterpolation:
8
8
  EnforcedStyle: double_quotes
9
+
10
+ Metrics/BlockLength:
11
+ Max: 60
data/CHANGELOG.md CHANGED
@@ -9,5 +9,12 @@
9
9
 
10
10
  - Adjustment to be able to create the two new generation and formatting methods
11
11
 
12
+ ## [0.3.0] - 2026-04-27
13
+
14
+ - Added the `generate_cpf` method to generate valid CPF numbers.
15
+ - Added the `generate_cnpj` method to generate valid CNPJ numbers.
16
+ - Added the `format_cpf` method to format CPF numbers in the standard format (XXX.XXX.XXX-XX).
17
+ - Added the `format_cnpj` method to format CNPJ numbers in the standard format (XX.XXX.XXX/XXXX-XX).
18
+ - Updated the README.md file to include examples of the new generation and formatting methods.
12
19
 
13
20
 
data/README.md CHANGED
@@ -46,14 +46,14 @@ CpfCnpjPlus.format_cpf("12345678909") # => "123.456.789-09"
46
46
  CpfCnpjPlus.generate # => Gera um CPF válido
47
47
 
48
48
  CNPJ
49
- CpfCnpjPlus.valid?("12.345.678/0001-95") # => true ou false
49
+ CpfCnpjPlus.valid_cnpj?("12.345.678/0001-95") # => true ou false
50
50
  CpfCnpjPlus.format_cnpj("12345678000195") # => "12.345.678/0001-95"
51
51
  CpfCnpjPlus.generate # => Gera um CNPJ válido
52
52
 
53
53
  CNPJ Alfanumérico (novo formato)
54
- CpfCnpjPlus.valid?("A1234567B00195") # => true ou false
55
- CpfCnpjPlus.format_cnpj("A1234567B00195") # => "A12.345.67B/0019-5"
56
- CpfCnpjPlus.generate # => Gera um CNPJ alfanumérico válido
54
+ CpfCnpjPlus.valid_cnpj?("A1234567B00195") # => true ou false
55
+ CpfCnpjPlus.format_cnpj("A1234567B00195") # => "A1.234.567/B001-95"
56
+ CpfCnpjPlus.generate(alphanumeric: true) # => Gera um CNPJ alfanumérico válido
57
57
  ```
58
58
 
59
59
 
data/exe/cnpj_plus ADDED
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "optparse"
5
+ require_relative "../lib/cpf_cnpj_plus"
6
+
7
+ options = {}
8
+ OptionParser.new do |opts|
9
+ opts.banner = "Uso: cnpj_plus [opções]"
10
+ opts.on("--check CNPJ", "Valida um CNPJ (numérico ou alfanumérico)") { |v| options[:check] = v }
11
+ opts.on("--format CNPJ", "Formata um CNPJ") { |v| options[:format] = v }
12
+ opts.on("--generate", "Gera um CNPJ numérico válido") { options[:generate] = true }
13
+ opts.on("--alphanumeric", "Gera um CNPJ alfanumérico (com --generate)") { options[:alphanumeric] = true }
14
+ end.parse!
15
+
16
+ if options[:check]
17
+ valid = CpfCnpjPlus.valid?(options[:check])
18
+ puts valid ? "✅ CNPJ válido" : "❌ CNPJ inválido"
19
+ elsif options[:format]
20
+ result = CpfCnpjPlus.format_cnpj(options[:format])
21
+ puts result || "❌ CNPJ inválido para formatação"
22
+ elsif options[:generate]
23
+ puts CpfCnpjPlus.generate_cnpj(alphanumeric: options[:alphanumeric] || false)
24
+ else
25
+ puts "Use --help para ver as opções disponíveis."
26
+ end
data/exe/cpf_plus ADDED
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "optparse"
5
+ require_relative "../lib/cpf_cnpj_plus"
6
+
7
+ options = {}
8
+ OptionParser.new do |opts|
9
+ opts.banner = "Uso: cpf_plus [opções]"
10
+ opts.on("--check CPF", "Valida um CPF") { |v| options[:check] = v }
11
+ opts.on("--format CPF", "Formata um CPF") { |v| options[:format] = v }
12
+ opts.on("--generate", "Gera um CPF válido") { options[:generate] = true }
13
+ end.parse!
14
+
15
+ if options[:check]
16
+ valid = CpfCnpjPlus.valid_cpf?(options[:check])
17
+ puts valid ? "✅ CPF válido" : "❌ CPF inválido"
18
+ elsif options[:format]
19
+ result = CpfCnpjPlus.format_cpf(options[:format])
20
+ puts result || "❌ CPF inválido para formatação"
21
+ elsif options[:generate]
22
+ puts CpfCnpjPlus.generate_cpf
23
+ else
24
+ puts "Use --help para ver as opções disponíveis."
25
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CpfCnpjPlus
4
+ module Formatter
5
+ # Responsável por formatar números de CNPJ para exibição.
6
+ # Suporta o formato numérico tradicional e o novo formato alfanumérico,
7
+ # aplicando a máscara padrão XX.XXX.XXX/XXXX-XX.
8
+ class Cnpj
9
+ def self.format(cnpj)
10
+ cnpj = cnpj.to_s.upcase.gsub(/[^A-Z0-9]/, "")
11
+ return nil unless cnpj.length == 14
12
+
13
+ "#{cnpj[0..1]}.#{cnpj[2..4]}.#{cnpj[5..7]}/#{cnpj[8..11]}-#{cnpj[12..13]}"
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CpfCnpjPlus
4
+ module Formatter
5
+ # Responsável por formatar números de CPF para exibição.
6
+ # Aplica a máscara padrão XXX.XXX.XXX-XX a partir de uma string numérica.
7
+ class Cpf
8
+ def self.format(cpf)
9
+ cpf = cpf.to_s.gsub(/[^0-9]/, "")
10
+ return nil unless cpf.length == 11
11
+
12
+ "#{cpf[0..2]}.#{cpf[3..5]}.#{cpf[6..8]}-#{cpf[9..10]}"
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CpfCnpjPlus
4
+ # Módulo responsável por agrupar formatadores de CPF e CNPJ.
5
+ # Fornece métodos e classes auxiliares para formatação de documentos brasileiros,
6
+ # incluindo suporte a formatos tradicionais e CNPJ alfanumérico.
7
+ module Formatter
8
+ require_relative "formatter/cnpj"
9
+ require_relative "formatter/cpf"
10
+ end
11
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CpfCnpjPlus
4
+ module Generator
5
+ # Responsável por gerar números de CNPJ válidos aleatoriamente.
6
+ # Suporta geração no formato numérico tradicional e no novo formato
7
+ # alfanumérico, calculando os dígitos verificadores conforme a Receita Federal.
8
+ class Cnpj
9
+ DIGITS = ("0".."9").to_a.freeze
10
+ LETTERS = ("A".."Z").to_a.freeze
11
+ ALPHANUMERIC = (DIGITS + LETTERS).freeze
12
+
13
+ WEIGHTS_1D = [5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2].freeze
14
+ WEIGHTS_2D = [6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2].freeze
15
+
16
+ def self.generate(alphanumeric: false)
17
+ loop do
18
+ base = build_base(alphanumeric)
19
+ cnpj = build_cnpj(base)
20
+ return cnpj unless Validator::Cnpj.cnpj_not_valid?(cnpj)
21
+ end
22
+ end
23
+
24
+ def self.build_base(alphanumeric)
25
+ if alphanumeric
26
+ # Garante ao menos uma letra para ser genuinamente alfanumérico
27
+ base = Array.new(12) { ALPHANUMERIC.sample }
28
+ base[rand(0..11)] = LETTERS.sample
29
+ base
30
+ else
31
+ Array.new(12) { DIGITS.sample }
32
+ end
33
+ end
34
+
35
+ def self.build_cnpj(base)
36
+ values = base.map { |c| char_to_value(c) }
37
+ d1 = calculate_digit(values, WEIGHTS_1D)
38
+ d2 = calculate_digit(values + [d1], WEIGHTS_2D)
39
+ base.join + "#{d1}#{d2}"
40
+ end
41
+
42
+ def self.char_to_value(char)
43
+ char.ord - 48
44
+ end
45
+
46
+ def self.calculate_digit(values, weights)
47
+ soma = weights.each_with_index.sum { |w, i| values[i] * w }
48
+ result = (soma * 10) % 11
49
+ result == 10 ? 0 : result
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CpfCnpjPlus
4
+ module Generator
5
+ # Responsável por gerar números de CPF válidos aleatoriamente.
6
+ # Calcula os dígitos verificadores conforme o algoritmo oficial da Receita Federal.
7
+ class Cpf
8
+ def self.generate
9
+ loop do
10
+ base = Array.new(9) { rand(0..9) }
11
+ cpf = build_cpf(base)
12
+ return cpf unless Validator::Cpf.cpf_not_valid?(cpf)
13
+ end
14
+ end
15
+
16
+ def self.build_cpf(base)
17
+ d1 = calculate_digit(base, (2..10).to_a.reverse)
18
+ d2 = calculate_digit(base + [d1], (2..11).to_a.reverse)
19
+ (base + [d1, d2]).join
20
+ end
21
+
22
+ def self.calculate_digit(digits, weights)
23
+ soma = digits.each_with_index.sum { |d, i| d * weights[i] }
24
+ result = (soma * 10) % 11
25
+ result == 10 ? 0 : result
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CpfCnpjPlus
4
+ # Módulo responsável por agrupar geradores de CPF e CNPJ.
5
+ # Fornece métodos e classes auxiliares para geração de documentos brasileiros,
6
+ # incluindo suporte a formatos tradicionais e CNPJ alfanumérico.
7
+ module Generator
8
+ require_relative "generator/cnpj"
9
+ require_relative "generator/cpf"
10
+ end
11
+ end
@@ -8,7 +8,7 @@ module CpfCnpjPlus
8
8
  def self.valid?(cnpj)
9
9
  cnpj = normalize(cnpj)
10
10
  return false unless valid_length?(cnpj)
11
- return false if cpj_not_valid?(cnpj)
11
+ return false if cnpj_not_valid?(cnpj)
12
12
  return false unless valid_structure?(cnpj)
13
13
 
14
14
  base = cnpj[0..11].chars.map { |c| char_to_value(c) }
@@ -30,13 +30,7 @@ module CpfCnpjPlus
30
30
  end
31
31
 
32
32
  def self.char_to_value(char)
33
- if ("0".."9").include?(char)
34
- char.ord - 48
35
- elsif ("A".."Z").include?(char)
36
- char.ord - 48 # Ajuste para A=10, B=11, ..., Z=35
37
- else
38
- raise ArgumentError, "Caractere inválido"
39
- end
33
+ char.ord - 48
40
34
  end
41
35
 
42
36
  def self.calculate_cnpj_digits(base)
@@ -63,7 +57,7 @@ module CpfCnpjPlus
63
57
  digit
64
58
  end
65
59
 
66
- def self.cpj_not_valid?(cnpj)
60
+ def self.cnpj_not_valid?(cnpj)
67
61
  cnpj = cnpj.to_s.gsub(/[^0-9]/, "")
68
62
  %w[00000000000000 11111111111111 22222222222222 33333333333333
69
63
  44444444444444 55555555555555 66666666666666 77777777777777
@@ -8,36 +8,35 @@ module CpfCnpjPlus
8
8
  def self.valid?(cpf)
9
9
  cpf = cpf.to_s.gsub(/[^0-9]/, "")
10
10
  return false unless cpf.length == 11 && cpf =~ /^\d{11}$/
11
- return false if cpj_not_valid?(cpf)
11
+ return false if cpf_not_valid?(cpf)
12
12
 
13
13
  first_digit(cpf) && second_digit(cpf)
14
14
  end
15
15
 
16
16
  def self.first_digit(cpf)
17
- first_digit = cpf[0..8]
17
+ base_digits = cpf[0..8]
18
18
  soma = 0
19
19
  ponteiro = 10
20
- first_digit.chars.each do |char|
21
- res = (char.to_i * ponteiro)
22
- soma += res
20
+ base_digits.chars.each do |char|
21
+ soma += char.to_i * ponteiro
23
22
  ponteiro -= 1
24
23
  end
25
- soma * 10 % 11 == cpf[9].to_i
24
+ result = soma * 10 % 11
25
+ result == cpf[9].to_i || (result == 10 && cpf[9].to_i.zero?)
26
26
  end
27
27
 
28
28
  def self.second_digit(cpf)
29
- second_digit = cpf[0..9]
29
+ base_digits = cpf[0..9]
30
30
  soma = 0
31
31
  ponteiro = 11
32
- second_digit.chars.each do |char|
33
- res = (char.to_i * ponteiro)
34
- soma += res
32
+ base_digits.chars.each do |char|
33
+ soma += char.to_i * ponteiro
35
34
  ponteiro -= 1
36
35
  end
37
36
  soma * 10 % 11 == cpf[10].to_i || (soma * 10 % 11 == 10 && cpf[10].to_i.zero?)
38
37
  end
39
38
 
40
- def self.cpj_not_valid?(cpf)
39
+ def self.cpf_not_valid?(cpf)
41
40
  cpf = cpf.to_s.gsub(/[^0-9]/, "")
42
41
  %w[00000000000 11111111111 22222222222 33333333333
43
42
  44444444444 55555555555 66666666666
@@ -3,7 +3,7 @@
3
3
  module CpfCnpjPlus
4
4
  # Módulo responsável por agrupar validadores de CPF e CNPJ.
5
5
  # Fornece métodos e classes auxiliares para validação de documentos brasileiros,
6
- # incluindo suporte a formatos tradicionais e futuros (como CNPJ alfanumérico).
6
+ # incluindo suporte a formatos tradicionais e CNPJ alfanumérico.
7
7
  module Validator
8
8
  require_relative "validator/cnpj"
9
9
  require_relative "validator/cpf"
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module CpfCnpjPlus
4
- VERSION = "0.2.0"
4
+ VERSION = "0.3.0"
5
5
  end
data/lib/cpf_cnpj_plus.rb CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  require_relative "cpf_cnpj_plus/version"
4
4
  require_relative "cpf_cnpj_plus/validator"
5
+ require_relative "cpf_cnpj_plus/formatter"
6
+ require_relative "cpf_cnpj_plus/generator"
5
7
 
6
8
  # Módulo principal da gem cpf_cnpj_plus.
7
9
  # Fornece métodos para validação, geração e formatação de CPFs e CNPJs,
@@ -9,27 +11,30 @@ require_relative "cpf_cnpj_plus/validator"
9
11
  module CpfCnpjPlus
10
12
  class Error < StandardError; end
11
13
 
12
- def self.valid_cnpj?(cnpj)
13
- CpfCnpjPlus::Validator::Cnpj.valid?(cnpj)
14
- end
15
-
14
+ # CPF
16
15
  def self.valid_cpf?(cpf)
17
16
  CpfCnpjPlus::Validator::Cpf.valid?(cpf)
18
17
  end
19
18
 
20
19
  def self.format_cpf(cpf)
21
- CpfCnpjPlus::Format::Cpf.format(cpf)
20
+ CpfCnpjPlus::Formatter::Cpf.format(cpf)
22
21
  end
23
22
 
24
- def self.format_cnpj(cnpj)
25
- CpfCnpjPlus::Format::Cnpj.format(cnpj)
23
+ def self.generate_cpf
24
+ CpfCnpjPlus::Generator::Cpf.generate
26
25
  end
27
26
 
28
- def self.generate_cpf
29
- CpfCnpjPlus::Generate::Cpf.generate
27
+ # CNPJ
28
+
29
+ def self.valid_cnpj?(cnpj)
30
+ CpfCnpjPlus::Validator::Cnpj.valid?(cnpj)
31
+ end
32
+
33
+ def self.format_cnpj(cnpj)
34
+ CpfCnpjPlus::Formatter::Cnpj.format(cnpj)
30
35
  end
31
36
 
32
- def self.generate_cnpj
33
- CpfCnpjPlus::Generate::Cnpj.generate
37
+ def self.generate_cnpj(alphanumeric: false)
38
+ CpfCnpjPlus::Generator::Cnpj.generate(alphanumeric: alphanumeric)
34
39
  end
35
40
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cpf_cnpj_plus
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - DougNeo
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 2025-07-07 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: simplecov
@@ -29,7 +29,9 @@ description: |-
29
29
  governamentais e aplicações Ruby em geral.
30
30
  email:
31
31
  - doug.neo@gmail.com
32
- executables: []
32
+ executables:
33
+ - cnpj_plus
34
+ - cpf_plus
33
35
  extensions: []
34
36
  extra_rdoc_files: []
35
37
  files:
@@ -41,20 +43,28 @@ files:
41
43
  - LICENSE.txt
42
44
  - README.md
43
45
  - Rakefile
46
+ - exe/cnpj_plus
47
+ - exe/cpf_plus
44
48
  - lib/cpf_cnpj_plus.rb
49
+ - lib/cpf_cnpj_plus/formatter.rb
50
+ - lib/cpf_cnpj_plus/formatter/cnpj.rb
51
+ - lib/cpf_cnpj_plus/formatter/cpf.rb
52
+ - lib/cpf_cnpj_plus/generator.rb
53
+ - lib/cpf_cnpj_plus/generator/cnpj.rb
54
+ - lib/cpf_cnpj_plus/generator/cpf.rb
45
55
  - lib/cpf_cnpj_plus/validator.rb
46
56
  - lib/cpf_cnpj_plus/validator/cnpj.rb
47
57
  - lib/cpf_cnpj_plus/validator/cpf.rb
48
58
  - lib/cpf_cnpj_plus/version.rb
49
59
  - sig/cpf_cnpj_plus.rbs
50
- homepage: https://github.com/DougNeo/cpf_cnpj_plus.git
60
+ homepage: https://github.com/DougNeo/cpf_cnpj_plus
51
61
  licenses:
52
62
  - MIT
53
63
  metadata:
54
64
  allowed_push_host: https://rubygems.org
55
- homepage_uri: https://github.com/DougNeo/cpf_cnpj_plus.git
56
- source_code_uri: https://github.com/DougNeo/cpf_cnpj_plus.git
57
- changelog_uri: https://github.com/DougNeo/cpf_cnpj_plus.git/blob/main/CHANGELOG.md
65
+ homepage_uri: https://github.com/DougNeo/cpf_cnpj_plus
66
+ source_code_uri: https://github.com/DougNeo/cpf_cnpj_plus
67
+ changelog_uri: https://github.com/DougNeo/cpf_cnpj_plus/blob/main/CHANGELOG.md
58
68
  rdoc_options: []
59
69
  require_paths:
60
70
  - lib
@@ -69,7 +79,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
69
79
  - !ruby/object:Gem::Version
70
80
  version: '0'
71
81
  requirements: []
72
- rubygems_version: 3.6.5
82
+ rubygems_version: 4.0.6
73
83
  specification_version: 4
74
84
  summary: Validação, geração e formatação de números de CPF e CNPJ para o Brasil.
75
85
  test_files: []