
π Full support for the new alphanumeric CNPJ format.
A Ruby utility to validate CNPJ (Brazilian Business Tax ID) values.
Ruby Support
| Passing β | Passing β | Passing β |
Features
- β Alphanumeric CNPJ: Validates 14-character CNPJ in numeric or alphanumeric format
- β
Flexible input: Accepts
StringorArrayof strings; array elements are concatenated in order - β
Format agnostic: Strips non-alphanumeric characters (or non-digits when
typeisnumeric) and optionally uppercases before validation - β
Optional case sensitivity: When
case_sensitiveisfalse, lowercase letters are accepted for alphanumeric CNPJ - β
Per-call override model: Instance defaults can be overridden for one
is_validcall only - β
Error handling: API misuse vs domain errors with a
CnpjVal::Errormarker for library-wide rescue - β
Minimal dependencies:
cnpj-dvfor check-digit calculation andlacus-utilsfor type descriptions in error messages - β
Dual API style: Object-oriented (
CnpjVal::CnpjValidator) and functional (CnpjVal.cnpj_val)
Installation
Install the gem directly:
gem install cnpj-val
Or add it to your Gemfile and run bundle install:
gem 'cnpj-val'
Require
require 'cnpj-val'
Quick Start
require 'cnpj-val'
validator = CnpjVal::CnpjValidator.new
validator.is_valid('98765432000198') # => true
validator.is_valid('98.765.432/0001-98') # => true
validator.is_valid('98765432000199') # => false
validator.is_valid('1QB5UKALPYFP59') # => true (alphanumeric)
validator.is_valid('1QB5UKALpyfp59') # => false (default is case-sensitive)
validator.is_valid('1QB5UKALpyfp59', case_sensitive: false) # => true
validator.is_valid('96206256120884') # => true (numeric)
validator.is_valid('1QB5UKALPYFP59', type: 'numeric') # => false (letters stripped β length β 14)
Functional helper:
require 'cnpj-val'
CnpjVal.cnpj_val('98765432000198') # => true
CnpjVal.cnpj_val('98.765.432/0001-98') # => true
CnpjVal.cnpj_val('98765432000199') # => false
Usage
The main entry points are the class CnpjVal::CnpjValidator, the options class CnpjVal::CnpjValidatorOptions, and the helper CnpjVal.cnpj_val.
CnpjVal::CnpjValidator
-
initialize(options = nil, **keywords): Optional default validation options. Whenoptionsis given (aCnpjVal::CnpjValidatorOptionsinstance or aHash) alone, it determines the default options; aCnpjVal::CnpjValidatorOptionsinstance is stored by reference (mutating it later affects futureis_validcalls 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 (case_sensitive:,type:). Passingoptionstogether with any non-nilkeyword raisesInvalidArgumentCombinationErrorinstead of silently ignoring the keywords. Example:CnpjVal::CnpjValidator.new(type: 'numeric', case_sensitive: false). -
options: Returns the instanceβsCnpjVal::CnpjValidatorOptions(same object used internally). -
is_valid(cnpj_input, options = nil, **keywords): Validates a CNPJ value.Input is normalized to a string (arrays of strings are concatenated). When
case_sensitiveisfalse, the string is uppercased before sanitization. Characters are stripped according totype. If the sanitized length is not exactly 14, the last two characters are not digits, or check digits do not match (CnpjDV::CnpjCheckDigitsfromcnpj-dv), the method returnsfalseβ no exception is raised for validation failure.If the input is not a
Stringor anArrayof strings,CnpjVal::TypeMismatchErroris raised.Per-call
optionsand 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.
require 'cnpj-val'
validator = CnpjVal::CnpjValidator.new(type: 'numeric')
validator.is_valid('98.765.432/0001-98') # => true
validator.is_valid('1QB5UKALPYFP59') # => false (letters stripped β length β 14)
validator.is_valid('1QB5UKALpyfp59', type: 'alphanumeric', case_sensitive: false) # => true
Default options on the instance; per-call overrides:
require 'cnpj-val'
validator = CnpjVal::CnpjValidator.new(case_sensitive: false)
validator.is_valid('1qb5ukalpyfp59') # => true (instance defaults)
validator.is_valid('1qb5ukalpyfp59', case_sensitive: true) # this call only: false
validator.is_valid('1qb5ukalpyfp59') # => true again
CnpjVal::CnpjValidatorOptions
Holds validator settings (case_sensitive, type). Construct with an optional options Hash or CnpjVal::CnpjValidatorOptions instance, optional extra override objects (merged in order), and/or keyword arguments. Exposes accessors: case_sensitive, type.
all: Returns a shallow, frozenHashsnapshot of all current options.set(options): Updates multiple fields at once; returnsself. Accepts aHashor anotherCnpjVal::CnpjValidatorOptionsinstance. Omitted keys retain their current values.
require 'cnpj-val'
= CnpjVal::CnpjValidatorOptions.new(case_sensitive: false, type: 'numeric')
.case_sensitive # => false
.type # => "numeric"
.set({ type: 'alphanumeric' }) # merge and return self
.all # => frozen snapshot of current options
Functional helper
CnpjVal.cnpj_val builds a new CnpjVal::CnpjValidator from the same constructor parameters and calls is_valid(cnpj_input) once. Pass either keyword arguments or a Hash/CnpjVal::CnpjValidatorOptions instance for options β not both (passing options with any non-nil keyword raises InvalidArgumentCombinationError):
require 'cnpj-val'
CnpjVal.cnpj_val('98765432000198') # => true
CnpjVal.cnpj_val('1QB5UKALpyfp59', case_sensitive: false) # => true
CnpjVal.cnpj_val('1QB5UKALPYFP59', type: 'numeric') # => false
CnpjVal.cnpj_val('1QB5UKALpyfp59', { # Hash form
type: 'alphanumeric',
case_sensitive: false,
}) # => true
Input formats
String: Raw digits and/or letters, or formatted CNPJ (e.g. 98.765.432/0001-98, 1Q.B5U.KAL/PYFP-59). Characters are stripped according to type; when case_sensitive is false, letters are uppercased before alphanumeric validation.
Array of strings: Each element must be a String; values are concatenated (e.g. per digit, grouped segments, or mixed with punctuation). Non-string elements raise CnpjVal::TypeMismatchError.
require 'cnpj-val'
CnpjVal.cnpj_val(['1', 'Q', 'B', '5', 'U', 'K', 'A', 'L', 'P', 'Y', 'F', 'P', '5', '9']) # => true
CnpjVal.cnpj_val(['1Q.B5U', 'KAL', 'PYFP-59']) # => true
Validation options
| Parameter | Type | Default | Description | ||
|---|---|---|---|---|---|
type |
'alphanumeric' \ |
'numeric' \ |
nil |
'alphanumeric' |
Character set after sanitization: alphanumeric (0β9, AβZ, aβz) or numeric-only (0β9) |
case_sensitive |
Boolean, nil |
true |
When false, lowercase letters are uppercased before alphanumeric validation |
Invalid CNPJ (wrong length after sanitization, invalid check digits, ineligible base/branch 00000000 / 0000, repeated digits, non-numeric verifier digits) returns false β no exception is raised for validation failure.
Example with all options:
require 'cnpj-val'
CnpjVal.cnpj_val(
'1QB5UKALpyfp59',
type: 'alphanumeric',
case_sensitive: false,
)
Error handling
Errors fall into two categories:
| Category | Meaning |
|---|---|
| API misuse | The caller invoked the library incorrectly (wrong type for the CNPJ input or an option, or an invalid argument combination). |
| Domain error | The call was structurally correct, but a value violates a business rule (invalid type string). |
Every custom error includes the CnpjVal::Error marker module. Domain failures (ValidationError) inherit from CnpjVal::DomainError (RangeError). Invalid CNPJ data returns false (it does not raise).
Important: passing both an options instance/Hash and any non-nil keyword argument raises InvalidArgumentCombinationError.
Summary
| Class | Inherits from | Category | Trigger condition |
|---|---|---|---|
CnpjVal::InvalidArgumentCombinationError |
ArgumentError (+ include Error) |
API misuse | Both an options instance/Hash and any non-nil keyword argument are passed at once |
CnpjVal::TypeMismatchError |
TypeError (+ include Error) |
API misuse | CNPJ input or option has the wrong data type |
CnpjVal::ValidationError |
CnpjVal::DomainError |
Domain error | type is not one of the allowed values |
CnpjVal::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 CnpjVal::Error
# everything this library raises
CnpjVal::DomainError
- Inheritance:
CnpjVal::DomainError < RangeError(includesCnpjVal::Error) - Category: Domain error β ancestor for all domain failures.
- When it is raised: Not raised directly; prefer raising a leaf subclass.
- Example: Prefer
raise CnpjVal::ValidationErrorover raisingDomainErrordirectly. - How to rescue it:
rescue CnpjVal::DomainError
# ValidationError and other DomainError subclasses
CnpjVal::TypeMismatchError
- Inheritance:
CnpjVal::TypeMismatchError < TypeError(includesCnpjVal::Error) - Category: API misuse β the caller passed a value of the wrong type.
- When it is raised: Raised when the CNPJ input is not a
StringorArrayof strings, or when a validator option (type) has the wrong runtime type. - Example:
CnpjVal.cnpj_val(12_345_678_000_198) # raises CnpjVal::TypeMismatchError
CnpjVal.cnpj_val('98765432000198', type: 123) # raises CnpjVal::TypeMismatchError
- How to rescue it:
rescue CnpjVal::TypeMismatchError
# this library's type-contract violation
rescue TypeError
# native type errors, including this library's TypeMismatchError
CnpjVal::InvalidArgumentCombinationError
- Inheritance:
CnpjVal::InvalidArgumentCombinationError < ArgumentError(includesCnpjVal::Error) - Category: API misuse β the provided arguments do not form a valid API signature.
- When it is raised: Raised when
CnpjValidator.new,#is_valid, orcnpj_valreceives both anoptionsargument (instance orHash) and any non-nilkeyword argument at the same time. - Example:
begin
CnpjVal.cnpj_val('98765432000198', { type: 'numeric' }, case_sensitive: false)
rescue CnpjVal::InvalidArgumentCombinationError => e
puts e.
# Pass either an options instance/Hash to `options`, or keyword arguments (case_sensitive:, type:), not both.
end
- How to rescue it:
rescue CnpjVal::InvalidArgumentCombinationError
# this library's invalid signature combination
rescue ArgumentError
# native argument errors, including this library's InvalidArgumentCombinationError
CnpjVal::ValidationError
- Inheritance:
CnpjVal::ValidationError < CnpjVal::DomainError < RangeError(includesCnpjVal::Error) - Category: Domain error β a value fails a non-numeric, non-length domain rule.
- When it is raised: Raised when
typeis not one of'alphanumeric'or'numeric'. - Example:
CnpjVal.cnpj_val('98765432000198', type: 'invalid') # raises CnpjVal::ValidationError
- How to rescue it:
rescue CnpjVal::ValidationError
# this exact domain validation failure
rescue CnpjVal::DomainError
# ValidationError and other DomainError subclasses
Rescue granularity
# 1) Single native class β catches misuse errors of that kind.
rescue TypeError
# CnpjVal::TypeMismatchError and any other TypeError (library or not)
# 2) CnpjVal::DomainError β catches all business-rule violations under DomainError.
rescue CnpjVal::DomainError
# CnpjVal::ValidationError and other DomainError subclasses
# 3) CnpjVal::Error β catches everything the library raises.
rescue CnpjVal::Error
# every custom error that includes CnpjVal::Error
# 4) Specific leaf class β catches only that exact failure mode.
rescue CnpjVal::ValidationError
# only CnpjVal::ValidationError
Notable attributes on raised errors:
TypeMismatchError:option_name(nil for CNPJ input),actual_input,actual_type,expected_typeValidationError:option_name,actual_input,expected_values
API
Exports
After require 'cnpj-val':
CnpjVal.cnpj_val:(cnpj_input, options = nil, **keywords) -> Booleanβ convenience helper.CnpjVal::CnpjValidator: Class to validate CNPJ with optional default options; acceptsStringorArray<String>inis_valid.CnpjVal::CnpjValidatorOptions: Class holding options; supports merge via constructor,set, and keyword arguments.CnpjVal::CNPJ_LENGTH:14(constant).CnpjVal::VERSION: gem version string.- Type predicate:
CnpjVal::CnpjInputβCnpjVal::CnpjInput.accept?(value)/CnpjVal::CnpjInput === valueis true only forStringorArray<String>. - Type markers:
CnpjVal::CnpjType,CnpjVal::CnpjValidatorOptionsInput. - Errors:
CnpjVal::Error,CnpjVal::DomainError,CnpjVal::InvalidArgumentCombinationError,CnpjVal::TypeMismatchError,CnpjVal::ValidationError.
Other available resources
CnpjVal::CnpjValidatorOptions::CNPJ_LENGTH:14.CnpjVal::CnpjValidatorOptions::DEFAULT_CASE_SENSITIVE:true.CnpjVal::CnpjValidatorOptions::DEFAULT_TYPE:'alphanumeric'.
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