承接 lumensistemas/br-validation 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

lumensistemas/br-validation

Composer 安装命令:

composer require lumensistemas/br-validation

包简介

Validators, generators, and formatters for Brazilian identifiers (CPF, CNPJ, PIS, Título de Eleitor, CNH, Renavam, placa de veículo, CNS, chave PIX, CEP, telefone, boleto bancário, and NF-e access key).

README 文档

README

Tests Latest Stable Version Total Downloads

Validators, generators, and formatters for Brazilian identifiers (CPF, CNPJ, PIS, Título de Eleitor, CNH, Renavam, placa de veículo, CNS, chave PIX, CEP, telefone, boleto bancário, and NF-e access key) in PHP. Framework-agnostic and dependency-free at runtime.

Requirements

  • PHP 8.3 or newer
  • ext-mbstring

Installation

composer require lumensistemas/br-validation

Usage

CPF

use LumenSistemas\BrValidation\Cpf;

Cpf::isValid('856.981.040-77');   // true
Cpf::isValid('85698104077');      // true (raw form also accepted)
Cpf::isValid('11111111111');      // false (all-equal sequence)
Cpf::isValid(85698104077);        // false (non-string input)

Cpf::format('85698104077');       // '856.981.040-77'
Cpf::normalize('856.981.040-77'); // '85698104077'

Cpf::generate(); // a valid 11-digit CPF

CNPJ

use LumenSistemas\BrValidation\Cnpj;

Cnpj::isValid('11.222.333/0001-81');      // true (legacy numeric)
Cnpj::isValid('12ABC34501DE35');          // true (alphanumeric, 2026 rules)
Cnpj::isValid('12abc34501de35');          // true (case-insensitive)
Cnpj::isValid('00000000000000');          // false (all-equal sequence)

Cnpj::format('11222333000181');           // '11.222.333/0001-81'
Cnpj::format('12abc34501de35');           // '12.ABC.345/01DE-35'
Cnpj::normalize(' 11.222.333/0001-81 '); // '11222333000181'

Cnpj::generateNumeric();      // a valid 14-digit numeric CNPJ
Cnpj::generateAlphanumeric(); // a valid alphanumeric CNPJ

PIS / PASEP / NIS / NIT

use LumenSistemas\BrValidation\Pis;

Pis::isValid('120.65328.70-5'); // true
Pis::isValid('12065328705');    // true (raw form also accepted)
Pis::isValid('00000000000');    // false (all-equal sequence)
Pis::isValid(12065328705);      // false (non-string input)

Pis::format('12065328705');     // '120.65328.70-5'
Pis::normalize('120.65328.70-5'); // '12065328705'

Pis::generate(); // a valid 11-digit PIS

The same 11-digit number is issued under four different government program names — PIS, PASEP, NIS, NIT — and shares a single mod-11 check digit. Pis validates any of them.

Título de Eleitor

use LumenSistemas\BrValidation\TituloEleitor;

TituloEleitor::isValid('1234 5678 0396'); // true (RJ)
TituloEleitor::isValid('123456780396');   // true (raw form also accepted)
TituloEleitor::isValid('123456789905');   // false (UF 99 is not a TSE code)
TituloEleitor::isValid('111111111111');   // false (all-equal sequence)

TituloEleitor::format('123456780396');    // '1234 5678 0396'
TituloEleitor::normalize('1234 5678 0396'); // '123456780396'

TituloEleitor::generate(); // a valid 12-digit título

The UF code in positions 9–10 is the TSE's own numbering (01..28), not the IBGE UF code. São Paulo (01) and Minas Gerais (02) follow a special rule: whenever a check-digit calculation yields remainder 0, the digit is bumped to 1.

CNH

use LumenSistemas\BrValidation\Cnh;

Cnh::isValid('98765432109');         // true
Cnh::isValid('123.456.789-00');      // true (mask characters are stripped)
Cnh::isValid('12345678901');         // false (wrong check digits)
Cnh::isValid('11111111111');         // false (all-equal sequence)

Cnh::normalize(' 123.456.789-00 ');  // '12345678900'

Cnh::generate(); // a valid 11-digit CNH

The CNH número de registro has no canonical visual mask on the document, so no format() method is exposed — call normalize() for the 11-digit storage/display form.

Renavam

use LumenSistemas\BrValidation\Renavam;

Renavam::isValid('01234567897');     // true
Renavam::isValid('98765432103');     // true
Renavam::isValid('00000000000');     // false (all-equal sequence)
Renavam::isValid(1234567897);        // false (non-string input)

Renavam::normalize(' 01234567897 '); // '01234567897'

Renavam::generate(); // a valid 11-digit Renavam

Like CNH, Renavam has no canonical visual mask on the CRLV, so no format() method is exposed — call normalize() for the 11-digit storage/display form. Pre-2007 nine-digit Renavams must be left-padded with zeros by the caller before validation.

Placa de veículo

use LumenSistemas\BrValidation\Placa;

Placa::isValid('ABC-1234'); // true (old format)
Placa::isValid('abc1234');  // true (case-insensitive)
Placa::isValid('ABC1D23');  // true (Mercosul format)
Placa::isValid('ABCD123');  // false (wrong shape)

Placa::format('ABC1234');   // 'ABC-1234'
Placa::format('abc1d23');   // 'ABC1D23'
Placa::normalize(' abc-1234 '); // 'ABC1234'

Placa::generateOld();       // a valid old-format placa
Placa::generateMercosul();  // a valid Mercosul placa

Old and Mercosul plates coexist on the road indefinitely (vehicles only switch to Mercosul on first registration or transfer), so this is an accept-both library, not a transitional one. Placas carry no check digit; only the shape is validated.

CNS (Cartão Nacional de Saúde)

use LumenSistemas\BrValidation\Cns;

Cns::isValid('120 6532 8705 0007'); // true (definitive)
Cns::isValid('900000000000008');    // true (provisional, starts with 9)
Cns::isValid('320653287050007');    // false (first digit must be 1, 2, 7, 8, or 9)
Cns::isValid('100000000060026');    // false (definitive with non-000/001 appendix)

Cns::format('120653287050007');     // '120 6532 8705 0007'
Cns::normalize('120 6532 8705 0007'); // '120653287050007'

Cns::generateDefinitive();   // a valid definitive CNS (first digit 1 or 2)
Cns::generateProvisional();  // a valid provisional CNS (first digit 7, 8, or 9)

Two structural shapes share one mod-11 check: definitive cards (first digit 1 or 2) carry the citizen's PIS in positions 1–11 and a 000/001 appendix in positions 12–14; provisional cards (first digit 7, 8, or 9) carry no internal structure. The validator enforces the appendix pattern for definitive cards so that arithmetically-conforming numbers the SUS would never issue are still rejected.

Chave PIX

use LumenSistemas\BrValidation\Pix;

Pix::isValid('85698104077');                              // true (CPF key)
Pix::isValid('user@example.com');                         // true (email key)
Pix::isValid('+5511987654321');                           // true (phone key)
Pix::isValid('123e4567-e89b-42d3-a456-426614174000');     // true (EVP key)
Pix::isValid('11.222.333/0001-81');                       // true (CNPJ key)
Pix::isValid('not-a-key');                                // false

Pix::type('user@example.com');                            // 'email'
Pix::type('85698104077');                                 // 'cpf'

Pix::normalize('Test.User@Example.COM');                  // 'test.user@example.com'
Pix::normalize('856.981.040-77');                         // '85698104077'

Pix::generateEvp(); // a valid UUID v4 EVP key

Pix is a thin dispatcher over the five chave PIX shapes (CPF, CNPJ, e-mail, E.164 phone starting with +55, and UUID v4 EVP); CPF and CNPJ delegate to the existing validators. No format() method is exposed because the canonical display form depends on the type — use the type-specific Cpf::format() / Cnpj::format() when you need user-facing display.

CEP

use LumenSistemas\BrValidation\Cep;

Cep::isValid('01310-100');     // true
Cep::isValid('01310100');      // true (raw form also accepted)
Cep::isValid('0131010');       // false (too short)

Cep::format('01310100');       // '01310-100'
Cep::normalize('01310-100');   // '01310100'

Cep::generate(); // a shape-valid 8-digit CEP (not guaranteed to exist)

CEP has no check digit — this is shape validation only. Whether a given CEP corresponds to a real address requires a Correios lookup and is out of scope. All-equal sequences like 00000000 therefore pass; callers that need existence checks should integrate a lookup service separately.

Phone

use LumenSistemas\BrValidation\Phone;

Phone::isValid('(11) 98765-4321');  // true (mobile)
Phone::isValid('11987654321');      // true (mobile, raw)
Phone::isValid('(11) 3333-4444');   // true (landline)
Phone::isValid('+5511987654321');   // true (E.164)
Phone::isValid('11187654321');      // false (mobile must start with 9)

Phone::format('11987654321');       // '(11) 98765-4321'
Phone::format('1133334444');        // '(11) 3333-4444'
Phone::formatE164('11987654321');   // '+5511987654321'
Phone::normalize('+5511987654321'); // '11987654321'

Phone::generateMobile();    // a valid 11-digit mobile
Phone::generateLandline();  // a valid 10-digit landline

Enforces the post-2017 ANATEL mobile-9 mandate: 11-digit numbers must have a 9 as the first subscriber digit; 10-digit landlines must not. DDD is checked against the 11..99 range with no 0 in either position; semantic DDD allocation (which DDDs are actually issued by ANATEL) is left to callers, since the allocation list shifts over time.

Boleto bancário

use LumenSistemas\BrValidation\Boleto;

Boleto::isValid('00190.12343 56789.012343 56789.012343 1 99990000010000'); // true (linha digitável)
Boleto::isValid('00190123435678901234356789012343199990000010000');       // true (raw)
Boleto::isValid('00191999900000100000123456789012345678901234');          // true (44-digit barcode)
Boleto::isValid('00191123435678901234356789012343199990000010000');       // false (wrong field-1 DV)

Boleto::format('00190123435678901234356789012343199990000010000');
// '00190.12343 56789.012343 56789.012343 1 99990000010000'

Boleto::normalize('00190.12343 56789.012343 56789.012343 1 99990000010000');
// '00190123435678901234356789012343199990000010000'

Boleto::generate(); // a valid 47-digit linha digitável

Boleto::isValid accepts either the 47-digit linha digitável or the 44-digit código de barras and dispatches by length. A linha digitável is valid iff all three of its mod-10 field DVs match AND the barcode it reconstructs to passes the mod-11 general DV check. Targets boletos bancários only; concessionária slips (48-digit utility shape) are out of scope.

NF-e access key (chave de acesso)

use LumenSistemas\BrValidation\Nfe;

Nfe::isValid('35240111222333000181550010000000011123456788'); // true
Nfe::isValid('3524 0111 2223 3300 0181 5500 1000 0000 0111 2345 6788'); // true (masked)
Nfe::isValid('00000000000000000000000000000000000000000000');           // false (all-equal sequence)

Nfe::format('35240111222333000181550010000000011123456788');
// '3524 0111 2223 3300 0181 5500 1000 0000 0111 2345 6788'

Nfe::normalize('3524 0111 2223 3300 0181 5500 1000 0000 0111 2345 6788');
// '35240111222333000181550010000000011123456788'

Nfe::generate(); // a valid 44-digit access key

The same 44-digit shape and check-digit algorithm cover NF-e (modelo 55), NFC-e (modelo 65) and the broader SEFAZ document family (CT-e, MDF-e, BP-e). This validator does not constrain modelo.

Behavior

  • Validation never throws. isValid accepts any input type and returns false for non-string or malformed values. Callers can pass user input directly without try/catch.
  • All-equal sequences are rejected by validators with a checksum (11111111111, 00000000000000, …) even though some pass the underlying mod-11 algorithm — they are conventional placeholder values across the Brazilian validation ecosystem and never represent real identifiers. Cep and Placa are exceptions: neither carries a checksum to reject them against, so any shape-valid input is accepted and existence checks are left to the caller (Correios lookup for CEP, DETRAN for placa).
  • CNPJ is case-insensitive. Letters in alphanumeric CNPJs are normalized to uppercase before validation and formatting; both '12abc34501de35' and '12ABC34501DE35' validate equivalently, and format always produces the canonical uppercase masked form.
  • Numeric CNPJs remain valid in perpetuity alongside the 2026 alphanumeric format. This is an accept-both library, not a transitional one.
  • format() is tolerant. When the input shape doesn't match the canonical form, format() returns the input unchanged rather than raising. It does not validate check digits — that is isValid()'s job.

Laravel integration

A companion package lumensistemas/laravel-br-validation is planned, providing Rule classes and a service provider. It will be linked here once published.

Development

composer install
composer test

License

MIT. See LICENSE.

lumensistemas/br-validation 适用场景与选型建议

lumensistemas/br-validation 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 39 次下载、GitHub Stars 达 0, 最近一次更新时间为 2026 年 05 月 17 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「validator」 「validation」 「phone」 「nfe」 「cep」 「boleto」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 lumensistemas/br-validation 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 lumensistemas/br-validation 我们能提供哪些服务?
定制开发 / 二次开发

基于 lumensistemas/br-validation 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 39
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 43
  • 依赖项目数: 1
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-05-17