
A Ruby utility to validate CPF (Brazilian Individual's Taxpayer ID) values.
Ruby Support
| Passing β | Passing β | Passing β |
Features
- β Fixed 11-digit CPF: Validates the standard 11-digit Brazilian CPF via the official modulo-11 algorithm
- β
Flexible input: Accepts
StringorArrayof strings; array elements are concatenated in order - β Format agnostic: Strips every non-digit character before validation
- β
Repeated-digit rejection: All-identical-digit bases (e.g.
111.111.111-11,00000000000) are rejected - β
Error handling: Typed API-misuse errors with a
CpfVal::Errormarker for library-wide rescue - β
Minimal dependencies:
cpf-dvfor check-digit calculation andlacus-utilsfor type descriptions in error messages - β
Dual API style: Object-oriented (
CpfVal::CpfValidator) and functional (CpfVal.cpf_val)
Installation
Install the gem directly:
gem install cpf-val
Or add it to your Gemfile and run bundle install:
gem 'cpf-val'
Require
require 'cpf-val'
Quick Start
require 'cpf-val'
validator = CpfVal::CpfValidator.new
validator.is_valid('12345678909') # => true
validator.is_valid('123.456.789-09') # => true
validator.is_valid('12345678910') # => false (invalid check digits)
validator.is_valid('00000000000') # => false (repeated digits)
Functional helper:
require 'cpf-val'
CpfVal.cpf_val('12345678909') # => true
CpfVal.cpf_val('123.456.789-09') # => true
CpfVal.cpf_val('12345678910') # => false
Usage
The main entry points are the class CpfVal::CpfValidator and the helper CpfVal.cpf_val.
CpfVal::CpfValidator
-
initialize: Takes no arguments. CPF validation has no configuration options. -
is_valid(cpf_input): Validates a CPF value.Input is normalized to a string (arrays of strings are concatenated). Every non-digit character is then stripped. If the sanitized length is not exactly 11, its base is an all-identical-digit sequence, or the check digits do not match (
CpfDV::CpfCheckDigitsfromcpf-dv), the method returnsfalseβ no exception is raised for validation failure.If the input is not a
Stringor anArrayof strings,CpfVal::TypeMismatchErroris raised.
require 'cpf-val'
validator = CpfVal::CpfValidator.new
validator.is_valid('123.456.789-09') # => true
validator.is_valid('12345678909') # => true
validator.is_valid(['123', '456', '789', '09']) # => true
validator.is_valid('12345678910') # => false (invalid check digits)
validator.is_valid('11111111111') # => false (repeated digits)
Functional helper
CpfVal.cpf_val builds a new CpfVal::CpfValidator and calls is_valid(cpf_input) once. It takes only the input value:
require 'cpf-val'
CpfVal.cpf_val('11144477735') # => true
CpfVal.cpf_val('111.444.777-35') # => true
CpfVal.cpf_val('11144477736') # => false
Input formats
String: Plain digits or a formatted CPF (e.g. 123.456.789-09, 499.784.420-90, 011_258_960_00). Non-digit characters are stripped before validation; the result must be exactly 11 digits.
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 CpfVal::TypeMismatchError.
require 'cpf-val'
CpfVal.cpf_val(['1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '9']) # => true
CpfVal.cpf_val(['123.456', '789-09']) # => true
Error handling
This package raises only for API misuse (wrong input type). Validation failures (wrong length, ineligible base such as repeated digits, invalid check digits) return false and do not raise.
Every custom error includes the CpfVal::Error marker module. This package defines no CpfVal::DomainError and no domain leaves β invalid CPF data never raises a domain error.
Summary
| Class | Inherits from | Category | Trigger condition |
|---|---|---|---|
CpfVal::TypeMismatchError |
CpfVal::TypeMismatchError < TypeError < StandardError (+ include CpfVal::Error) |
API misuse | CPF input is not a String or Array of strings |
CpfVal::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 CpfVal::Error
# everything this library raises
CpfVal::TypeMismatchError
- Inheritance:
CpfVal::TypeMismatchError < TypeError < StandardError(includesCpfVal::Error) - Category: API misuse β the caller passed a value of the wrong type.
- When it is raised: Raised when the CPF input is not a
Stringor anArrayof strings (including when an array contains a non-string element). - Example:
require 'cpf-val'
begin
CpfVal.cpf_val(12_345_678_909)
rescue CpfVal::TypeMismatchError => e
puts e.
# CPF input must be of type string or string[]. Got integer number.
end
- How to rescue it:
rescue CpfVal::TypeMismatchError
# this library's type-contract violation
rescue TypeError
# native type errors, including this library's TypeMismatchError
Rescue granularity
Each level is shown as its own standalone example (do not merge them into one rescue ladder β a broad TypeError handler would make narrower clauses unreachable).
require 'cpf-val'
# 1) Single native class β catches misuse errors of that kind,
# including non-library ones already handled elsewhere in the consumer's code.
begin
CpfVal.cpf_val(123)
rescue TypeError
# CpfVal::TypeMismatchError and any other TypeError (library or not)
end
require 'cpf-val'
# 2) CpfVal::DomainError β not applicable: this package defines no DomainError
# (and no domain leaves). Invalid CPF data returns false instead of raising.
# begin
# CpfVal.cpf_val(123)
# rescue CpfVal::DomainError # NameError β constant is not defined
# end
require 'cpf-val'
# 3) CpfVal::Error β catches everything the library raises, regardless of native ancestry.
begin
CpfVal.cpf_val(123)
rescue CpfVal::Error
# every custom error that includes CpfVal::Error
end
require 'cpf-val'
# 4) Specific leaf class β catches only that exact failure mode.
begin
CpfVal.cpf_val(123)
rescue CpfVal::TypeMismatchError
# only CpfVal::TypeMismatchError
end
Notable attributes on raised errors:
TypeMismatchError:actual_input,actual_type,expected_type
API
Exports
After require 'cpf-val':
CpfVal.cpf_val:(cpf_input) -> Booleanβ convenience helper.CpfVal::CpfValidator: Class to validate CPF (no options); acceptsStringorArray<String>inis_valid.CpfVal::CPF_LENGTH:11(constant).CpfVal::VERSION: gem version string.- Type predicate:
CpfVal::CpfInputβCpfVal::CpfInput.accept?(value)/CpfVal::CpfInput === valueis true only forStringorArray<String>. - Errors:
CpfVal::Error,CpfVal::TypeMismatchError.
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