
π Full support for the new alphanumeric CNPJ format.
A Ruby utility to generate valid CNPJ (Brazilian Business Tax ID) values.
Ruby Support
| Passing β | Passing β | Passing β |
Requires Ruby β₯ 3.1 (see required_ruby_version in the gemspec).
Features
- β Alphanumeric CNPJ: Generates 14-character CNPJ with optional numeric, alphabetic, or alphanumeric (default) character sets
- β Optional prefix: Provide 0β12 alphanumeric characters to fix the start of the CNPJ (e.g. base ID) and generate the rest with valid check digits
- β
Formatting: Option to return the standard formatted string (
00.000.000/0000-00) - β
Reusable generator:
CnpjGen::CnpjGeneratorclass with default options and per-call overrides - β
Keyword overrides: Pass
format:,prefix:, andtype:oncnpj_gen,CnpjGenerator#generate, and constructors - β
Minimal dependencies: Only
cnpj-dvandlacus-utils - β
Error handling: API misuse vs domain errors with a
CnpjGen::Errormarker for library-wide rescue
Installation
Install the gem directly:
gem install cnpj-gen
Or add it to your Gemfile and run bundle install:
gem 'cnpj-gen'
Require
require 'cnpj-gen'
Quick Start
require 'cnpj-gen'
CnpjGen.cnpj_gen # => e.g. "AB123CDE000155" (14-char alphanumeric)
CnpjGen.cnpj_gen(format: true) # => e.g. "AB.123.CDE/0001-55"
CnpjGen.cnpj_gen(prefix: '45623767') # => e.g. "45623767ABCD96"
CnpjGen.cnpj_gen( # => e.g. "45.623.767/ABCD-96"
prefix: '45623767',
format: true
)
CnpjGen.cnpj_gen(type: 'numeric') # => e.g. "65453043000178" (digits only)
CnpjGen.cnpj_gen(type: 'alphabetic') # => e.g. "ABCDEFGHIJKL80" (letters only, except check digits)
Options can also be passed as a Hash:
CnpjGen.cnpj_gen({ format: true, type: 'numeric' })
Usage
The main entry points are the module helper CnpjGen.cnpj_gen, the class CnpjGen::CnpjGenerator, and the options class CnpjGen::CnpjGeneratorOptions.
Generator options
All options are optional:
| Option | Type | Default | Description |
|---|---|---|---|
format |
Boolean |
false |
When truthy, return the generated CNPJ in standard format (00.000.000/0000-00). Non-boolean values are coerced (false, '', and 0 become false; other values become truthy). |
prefix |
String |
'' |
Partial start string (0β12 alphanumeric chars). Only alphanumeric characters are kept and uppercased; missing characters are generated randomly and check digits are computed. |
type |
String |
'alphanumeric' |
Character set for the randomly generated part (prefix is kept as-is after sanitization). Must be one of 'numeric', 'alphabetic', or 'alphanumeric'. Check digits are always numeric. |
Prefix rules: base ID (first 8 chars) and branch ID (chars 9β12) cannot be all zeros; 12 repeated digits (e.g. 777777777777) are also not allowed.
nil is accepted as a keyword argument on cnpj_gen, CnpjGenerator.new, CnpjGenerator#generate, and CnpjGeneratorOptions.new/#set β it simply means "no override for this option". It is not accepted by the CnpjGeneratorOptions property setters (options.format = value, options.prefix = value, options.type = value): calling a setter with nil directly raises CnpjGen::TypeMismatchError. To reset a property to its default value through a setter, pass the literal constant instead, e.g. options.format = CnpjGen::CnpjGeneratorOptions::DEFAULT_FORMAT.
CnpjGen.cnpj_gen (helper)
Generates a valid CNPJ string. With no options, returns a 14-character alphanumeric CNPJ. This is a convenience wrapper around CnpjGen::CnpjGenerator.new(...).generate.
options(optional):CnpjGen::CnpjGeneratorOptionsinstance, aHashof option keys, ornil. See Generator options.format,prefix,type(keyword arguments): Only used whenoptionsis omitted (nil). Passingoptionsand any non-nilof these keywords at the same time raisesInvalidArgumentCombinationErrorβ the two ways of passing options are never merged.
CnpjGen::CnpjGenerator (class)
For reusable defaults or per-call overrides, use the class:
require 'cnpj-gen'
generator = CnpjGen::CnpjGenerator.new(type: 'numeric', format: true)
generator.generate # => e.g. "73.008.535/0005-06"
generator.generate(prefix: '12345678') # override for this call only
generator. # current default options (CnpjGen::CnpjGeneratorOptions)
initialize(options = nil, **keywords): Optional default options. Whenoptionsis given (aCnpjGen::CnpjGeneratorOptionsinstance or aHash) alone, it determines the default options; aCnpjGen::CnpjGeneratorOptionsinstance is stored by reference (mutating it later affects futuregeneratecalls that do not pass per-call options), while aHashbuilds a new instance. Whenoptionsis omitted (nil), the default options are built exclusively from the keyword arguments (format:,prefix:,type:). Passingoptionstogether with any non-nilkeyword raisesInvalidArgumentCombinationErrorinstead of silently ignoring the keywords.generate(options = nil, **keywords): Returns a valid CNPJ.optionsand the keyword arguments are never merged: a givenoptionsargument alone fully overrides the instance defaults for this call; otherwise, any given keyword overrides the instance defaults for this call. When neither is given, the instance defaults are used as-is. The instance defaults are never mutated by a per-call override. Passingoptionstogether with any non-nilkeyword raisesInvalidArgumentCombinationError.options: Reader returning the default options used when per-call options are not provided (same instance as used internally; mutating it affects futuregeneratecalls).
Default options on the instance; per-call overrides:
require 'cnpj-gen'
generator = CnpjGen::CnpjGenerator.new(format: true)
generator.generate # formatted CNPJ
generator.generate(format: false) # this call only: unformatted
generator.generate # formatted again (instance defaults preserved)
CnpjGen::CnpjGeneratorOptions (class)
Holds options (format, prefix, type) with validation and merge support:
require 'cnpj-gen'
= CnpjGen::CnpjGeneratorOptions.new(
prefix: 'AB123XYZ',
type: 'numeric',
format: true
)
.prefix # => "AB123XYZ"
.type # => "numeric"
.format # => true
.set(format: false) # merge and return self
.all # => { format: false, prefix: "AB123XYZ", type: "numeric" }
# Resetting a property to its default value requires the literal constant β
# a bare `nil` on a setter raises TypeMismatchError:
.format = CnpjGen::CnpjGeneratorOptions::DEFAULT_FORMAT
initialize(*options, **keywords): Every positionaloptionsargument (each aHashor anotherCnpjGen::CnpjGeneratorOptionsinstance) is folded left to right β later arguments win β then the keyword arguments (format:,prefix:,type:) are applied on top with the highest precedence. At every step, anilvalue for a given key is ignored in favor of whatever was resolved so far. Any option still unresolved after that is set to itsDEFAULT_*value.format,prefix,type: Accessors with setters;prefixis validated (base/branch ineligible, repeated digits). The setters never acceptnilβ pass the matchingDEFAULT_*constant (e.g.CnpjGeneratorOptions::DEFAULT_PREFIX) to reset a property explicitly.set(*options, **keywords): Updates multiple options at once, using the same fold-then-keywords, ignore-nilresolution asinitialize. Any option left unresolved after merging keeps its current value on the instance (a partial update, not a re-initialization). Returnsself.all: ShallowHashcopy of current options (:format,:prefix,:type).
API
Exports
After require 'cnpj-gen':
CnpjGen.cnpj_gen:(options = nil, **keywords) -> Stringβ convenience helper.CnpjGen::CnpjGenerator: Class to generate CNPJ with optional default options and per-call overrides.CnpjGen::CnpjGeneratorOptions: Class holding options with validation and merge.CnpjGen::CNPJ_LENGTH:14(constant).CnpjGen::CNPJ_PREFIX_MAX_LENGTH:12(constant).CnpjGen::CNPJ_TYPE_VALUES:%w[alphabetic alphanumeric numeric]β allowedtypevalues.CnpjGen::VERSION: gem version string.- Errors:
CnpjGen::Error,CnpjGen::DomainError,CnpjGen::InvalidArgumentCombinationError,CnpjGen::TypeMismatchError,CnpjGen::ValidationError.
Error handling
Errors fall into two categories:
| Category | Meaning |
|---|---|
| API misuse | The caller invoked the library incorrectly (wrong type for an option, or an invalid argument combination). |
| Domain error | The call was structurally correct, but a value violates a business rule (invalid prefix, or type not in the allowed set). |
Every custom error includes the CnpjGen::Error marker module. Domain failures (ValidationError) inherit from CnpjGen::DomainError (RangeError).
Important: passing both an options instance/Hash and any non-nil keyword argument raises InvalidArgumentCombinationError.
Summary
| Class | Inherits from | Category | Trigger condition |
|---|---|---|---|
CnpjGen::InvalidArgumentCombinationError |
ArgumentError (+ include Error) |
API misuse | Both an options instance/Hash and any non-nil keyword argument are passed at once |
CnpjGen::TypeMismatchError |
TypeError (+ include Error) |
API misuse | A generator option has the wrong data type |
CnpjGen::ValidationError |
CnpjGen::DomainError |
Domain error | prefix is ineligible, or type is not one of the allowed values |
CnpjGen::Error (marker module)
- Inheritance: module marker mixed into every library error via
include(not a class). - Category: N/A (rescue target only) β not a failure mode by itself.
- When it is raised: Never raised directly; included by every custom error the library raises.
- Example: N/A
- How to rescue it:
rescue CnpjGen::Error
# everything this library raises
CnpjGen::DomainError
- Inheritance:
CnpjGen::DomainError < RangeError(includesCnpjGen::Error) - Category: Domain error β ancestor for all domain failures.
- When it is raised: Not raised directly; prefer raising a leaf subclass.
- Example: Prefer
raise CnpjGen::ValidationErrorover raisingDomainErrordirectly. - How to rescue it:
rescue CnpjGen::DomainError
# ValidationError and other DomainError subclasses
CnpjGen::TypeMismatchError
- Inheritance:
CnpjGen::TypeMismatchError < TypeError(includesCnpjGen::Error) - Category: API misuse β the caller passed a value of the wrong type.
- When it is raised: Raised when a generator option (
format,prefix, ortype) has the wrong runtime type. - Example:
CnpjGen.cnpj_gen(prefix: 123) # raises CnpjGen::TypeMismatchError
- How to rescue it:
rescue CnpjGen::TypeMismatchError
# this library's type-contract violation
rescue TypeError
# native type errors, including this library's TypeMismatchError
CnpjGen::InvalidArgumentCombinationError
- Inheritance:
CnpjGen::InvalidArgumentCombinationError < ArgumentError(includesCnpjGen::Error) - Category: API misuse β the caller mixed mutually exclusive argument patterns.
- When it is raised: Raised when
CnpjGenerator.new,#generate, orcnpj_genreceives both anoptionsargument (instance orHash) and any non-nilkeyword argument at the same time. - Example:
begin
CnpjGen::CnpjGenerator.new({ format: true }, prefix: 'AB')
rescue CnpjGen::InvalidArgumentCombinationError => e
puts e.
# Pass either an options instance/Hash to `options`, or keyword arguments (format:, prefix:, type:), not both.
end
- How to rescue it:
rescue CnpjGen::InvalidArgumentCombinationError
# this library's invalid argument combination
rescue ArgumentError
# native argument errors, including this library's InvalidArgumentCombinationError
CnpjGen::ValidationError
- Inheritance:
CnpjGen::ValidationError < CnpjGen::DomainError < RangeError(includesCnpjGen::Error) - Category: Domain error β a value fails a non-numeric, non-length domain rule.
- When it is raised: Raised when
prefixis ineligible (zeroed base/branch ID, or 12 repeated digits), or whentypeis not one of'alphabetic','alphanumeric', or'numeric'. - Example:
CnpjGen.cnpj_gen(prefix: '000000000001') # raises CnpjGen::ValidationError
CnpjGen.cnpj_gen(type: 'invalid') # raises CnpjGen::ValidationError
- How to rescue it:
rescue CnpjGen::ValidationError
# this exact domain validation failure
rescue CnpjGen::DomainError
# RangeError-rooted domain failures from this library
Rescue granularity
# 1) Single native class β catches type misuse from this library (and other TypeErrors).
rescue TypeError
# CnpjGen::TypeMismatchError and any other TypeError (library or not)
# 2) CnpjGen::DomainError β catches business-rule violations under DomainError.
rescue CnpjGen::DomainError
# CnpjGen::ValidationError and other DomainError subclasses
# 3) CnpjGen::Error β catches everything the library raises.
rescue CnpjGen::Error
# every custom error that includes CnpjGen::Error
# 4) Specific leaf class β catches only that exact failure mode.
rescue CnpjGen::ValidationError
# only CnpjGen::ValidationError
Notable attributes:
TypeMismatchError:option_name,actual_input,actual_type,expected_typeValidationError:option_name,actual_input,reason(prefix failures),expected_values(type failures)
Property setters never accept nil directly β pass the matching DEFAULT_* constant to reset:
= CnpjGen::CnpjGeneratorOptions.new
begin
.prefix = nil
rescue CnpjGen::TypeMismatchError => e
puts e.
# CNPJ generator option "prefix" must be of type string. Got nil.
end
.prefix = CnpjGen::CnpjGeneratorOptions::DEFAULT_PREFIX # explicit reset instead
Check-digit computation failures from cnpj-dv are handled internally by retrying generation with the same resolved options; they are not raised to callers under normal operation.
Other available resources
CnpjGen::CnpjGeneratorOptions::CNPJ_LENGTH:14.CnpjGen::CnpjGeneratorOptions::CNPJ_PREFIX_MAX_LENGTH:12.CnpjGen::CnpjGeneratorOptions::DEFAULT_FORMAT,DEFAULT_PREFIX,DEFAULT_TYPE: Class-level default constants.
Contribution & Support
We welcome contributions! Please see our Contributing Guidelines for details. If you find this project helpful, please consider:
- β Starring the repository
- π€ Contributing to the codebase
- π‘ Suggesting new features
- π Reporting bugs
License
This project is licensed under the MIT License β see the LICENSE file for details.
Changelog
See CHANGELOG for a list of changes and version history.
Made with β€οΈ by Lacus Solutions