
A Ruby utility to generate valid CPF (Brazilian Individual's Taxpayer ID) values.
Ruby Support
| Passing β | Passing β | Passing β |
Requires Ruby β₯ 3.1 (see required_ruby_version in the gemspec).
Features
- β Numeric CPF: Generates 11-digit numeric CPF values with valid check digits
- β Optional prefix: Provide 0β9 digits to fix the start of the CPF and generate the rest with valid check digits
- β
Formatting: Option to return the standard formatted string (
000.000.000-00) - β
Reusable generator:
CpfGen::CpfGeneratorclass with default options and per-call overrides - β
Keyword overrides: Pass
format:andprefix:oncpf_gen,CpfGenerator#generate, and constructors - β
Minimal dependencies: Only
cpf-dvandlacus-utils - β
Error handling: API misuse vs domain errors with a
CpfGen::Errormarker for library-wide rescue
Installation
Install the gem directly:
gem install cpf-gen
Or add it to your Gemfile and run bundle install:
gem 'cpf-gen'
Require
require 'cpf-gen'
Quick Start
require 'cpf-gen'
CpfGen.cpf_gen # => e.g. "47844241055" (11-digit numeric)
CpfGen.cpf_gen(format: true) # => e.g. "005.265.352-88"
CpfGen.cpf_gen(prefix: '528250911') # => e.g. "52825091138"
CpfGen.cpf_gen( # => e.g. "528.250.911-38"
prefix: '528250911',
format: true
)
Options can also be passed as a Hash:
CpfGen.cpf_gen({ format: true, prefix: '528250911' })
Usage
The main entry points are the module helper CpfGen.cpf_gen, the class CpfGen::CpfGenerator, and the options class CpfGen::CpfGeneratorOptions.
Generator options
All options are optional:
| Option | Type | Default | Description |
|---|---|---|---|
format |
Boolean |
false |
When truthy, return the generated CPF in standard format (000.000.000-00). Non-boolean values are coerced (false, '', and 0 become false; other values become truthy). |
prefix |
String |
'' |
Partial start string (0β9 digits). Only digits are kept; missing characters are generated randomly and check digits are computed. Prefixes longer than 9 digits are truncated silently. |
Prefix rules: the base (first 9 digits) cannot be all zeros; 9 repeated digits (e.g. 999999999) are not allowed. Prefixes shorter than 9 digits are never rejected by these rules (e.g. "00000000" and "11111111" are allowed).
nil is accepted as a keyword argument on cpf_gen, CpfGenerator.new, CpfGenerator#generate, and CpfGeneratorOptions.new/#set β it simply means "no override for this option". It is not accepted by the CpfGeneratorOptions property setters (options.format = value, options.prefix = value): calling a setter with nil directly raises CpfGen::TypeMismatchError. To reset a property to its default value through a setter, pass the literal constant instead, e.g. options.format = CpfGen::CpfGeneratorOptions::DEFAULT_FORMAT.
CpfGen.cpf_gen (helper)
Generates a valid CPF string. With no options, returns an 11-digit numeric CPF. This is a convenience wrapper around CpfGen::CpfGenerator.new(...).generate.
options(optional):CpfGen::CpfGeneratorOptionsinstance, aHashof option keys, ornil. See Generator options.format,prefix(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.
CpfGen::CpfGenerator (class)
For reusable defaults or per-call overrides, use the class:
require 'cpf-gen'
generator = CpfGen::CpfGenerator.new(format: true)
generator.generate # => e.g. "005.265.352-88"
generator.generate(prefix: '123456') # override for this call only
generator. # current default options (CpfGen::CpfGeneratorOptions)
initialize(options = nil, **keywords): Optional default options. Whenoptionsis given (aCpfGen::CpfGeneratorOptionsinstance or aHash) alone, it determines the default options; aCpfGen::CpfGeneratorOptionsinstance 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:). Passingoptionstogether with any non-nilkeyword raisesInvalidArgumentCombinationErrorinstead of silently ignoring the keywords.generate(options = nil, **keywords): Returns a valid CPF.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 'cpf-gen'
generator = CpfGen::CpfGenerator.new(format: true)
generator.generate # formatted CPF
generator.generate(format: false) # this call only: unformatted
generator.generate # formatted again (instance defaults preserved)
CpfGen::CpfGeneratorOptions (class)
Holds options (format, prefix) with validation and merge support:
require 'cpf-gen'
= CpfGen::CpfGeneratorOptions.new(
prefix: '123456',
format: true
)
.prefix # => "123456"
.format # => true
.set(format: false) # merge and return self
.all # => { format: false, prefix: "123456" }
# Resetting a property to its default value requires the literal constant β
# a bare `nil` on a setter raises TypeMismatchError:
.format = CpfGen::CpfGeneratorOptions::DEFAULT_FORMAT
initialize(*options, **keywords): Every positionaloptionsargument (each aHashor anotherCpfGen::CpfGeneratorOptionsinstance) is folded left to right β later arguments win β then the keyword arguments (format:,prefix:) 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: Accessors with setters;prefixis validated (zeroed base ID, repeated digits). The setters never acceptnilβ pass the matchingDEFAULT_*constant (e.g.CpfGeneratorOptions::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).
API
Exports
After require 'cpf-gen':
CpfGen.cpf_gen:(options = nil, **keywords) -> Stringβ convenience helper.CpfGen::CpfGenerator: Class to generate CPF with optional default options and per-call overrides.CpfGen::CpfGeneratorOptions: Class holding options with validation and merge.CpfGen::CPF_LENGTH:11(constant).CpfGen::CPF_PREFIX_MAX_LENGTH:9(constant).CpfGen::VERSION: gem version string.- Errors:
CpfGen::Error,CpfGen::DomainError,CpfGen::InvalidArgumentCombinationError,CpfGen::TypeMismatchError,CpfGen::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). |
Every custom error includes the CpfGen::Error marker module. Domain failures (ValidationError) inherit from CpfGen::DomainError (RangeError).
Important: passing both an options instance/Hash and any non-nil keyword argument raises InvalidArgumentCombinationError.
Summary
| Class | Inherits from | Category | Trigger condition |
|---|---|---|---|
CpfGen::InvalidArgumentCombinationError |
ArgumentError (+ include Error) |
API misuse | Both an options instance/Hash and any non-nil keyword argument are passed at once |
CpfGen::TypeMismatchError |
TypeError (+ include Error) |
API misuse | A generator option has the wrong data type |
CpfGen::ValidationError |
CpfGen::DomainError |
Domain error | prefix is ineligible (zeroed base ID or 9 repeated digits) |
CpfGen::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 CpfGen::Error
# everything this library raises
CpfGen::DomainError
- Inheritance:
CpfGen::DomainError < RangeError(includesCpfGen::Error) - Category: Domain error β ancestor for all domain failures.
- When it is raised: Not raised directly; prefer raising a leaf subclass.
- Example: Prefer
raise CpfGen::ValidationErrorover raisingDomainErrordirectly. - How to rescue it:
rescue CpfGen::DomainError
# ValidationError and other DomainError subclasses
CpfGen::TypeMismatchError
- Inheritance:
CpfGen::TypeMismatchError < TypeError(includesCpfGen::Error) - Category: API misuse β the caller passed a value of the wrong type.
- When it is raised: Raised when a generator option (
formatorprefix) has the wrong runtime type. - Example:
CpfGen.cpf_gen(prefix: 123) # raises CpfGen::TypeMismatchError
- How to rescue it:
rescue CpfGen::TypeMismatchError
# this library's type-contract violation
rescue TypeError
# native type errors, including this library's TypeMismatchError
CpfGen::InvalidArgumentCombinationError
- Inheritance:
CpfGen::InvalidArgumentCombinationError < ArgumentError(includesCpfGen::Error) - Category: API misuse β the caller mixed mutually exclusive argument patterns.
- When it is raised: Raised when
CpfGenerator.new,#generate, orcpf_genreceives both anoptionsargument (instance orHash) and any non-nilkeyword argument at the same time. - Example:
begin
CpfGen::CpfGenerator.new({ format: true }, prefix: '123')
rescue CpfGen::InvalidArgumentCombinationError => e
puts e.
# Pass either an options instance/Hash to `options`, or keyword arguments (format:, prefix:), not both.
end
- How to rescue it:
rescue CpfGen::InvalidArgumentCombinationError
# this library's invalid argument combination
rescue ArgumentError
# native argument errors, including this library's InvalidArgumentCombinationError
CpfGen::ValidationError
- Inheritance:
CpfGen::ValidationError < CpfGen::DomainError < RangeError(includesCpfGen::Error) - Category: Domain error β a value fails a non-numeric, non-length domain rule.
- When it is raised: Raised when
prefixis ineligible (zeroed base ID"000000000", or 9 repeated digits such as"999999999"). - Example:
CpfGen.cpf_gen(prefix: '000000000') # raises CpfGen::ValidationError
CpfGen.cpf_gen(prefix: '999999999') # raises CpfGen::ValidationError
- How to rescue it:
rescue CpfGen::ValidationError
# this exact domain validation failure
rescue CpfGen::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
# CpfGen::TypeMismatchError and any other TypeError (library or not)
# 2) CpfGen::DomainError β catches business-rule violations under DomainError.
rescue CpfGen::DomainError
# CpfGen::ValidationError and other DomainError subclasses
# 3) CpfGen::Error β catches everything the library raises.
rescue CpfGen::Error
# every custom error that includes CpfGen::Error
# 4) Specific leaf class β catches only that exact failure mode.
rescue CpfGen::ValidationError
# only CpfGen::ValidationError
Notable attributes:
TypeMismatchError:option_name,actual_input,actual_type,expected_typeValidationError:option_name,actual_input,reason(prefix failures);expected_valuesis alwaysnilfor CPF
Property setters never accept nil directly β pass the matching DEFAULT_* constant to reset:
= CpfGen::CpfGeneratorOptions.new
begin
.prefix = nil
rescue CpfGen::TypeMismatchError => e
puts e.
# CPF generator option "prefix" must be of type string. Got nil.
end
.prefix = CpfGen::CpfGeneratorOptions::DEFAULT_PREFIX # explicit reset instead
Check-digit computation failures from cpf-dv are handled internally by retrying generation with the same resolved options; they are not raised to callers under normal operation.
Other available resources
CpfGen::CpfGeneratorOptions::CPF_LENGTH:11.CpfGen::CpfGeneratorOptions::CPF_PREFIX_MAX_LENGTH:9.CpfGen::CpfGeneratorOptions::DEFAULT_FORMAT,DEFAULT_PREFIX: 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