-
Notifications
You must be signed in to change notification settings - Fork 0
[v2][cnpj-dv] Create cnpj-dv package for CNPJ check digit calculation supporting alphanumeric format
#37
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
[v2][cnpj-dv] Create cnpj-dv package for CNPJ check digit calculation supporting alphanumeric format
#37
Changes from all commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
61d20f2
chore(cnpj-dv): create new package in monorepo
juliolmuller 032095f
feat(cnpj-dv): create errors and exceptions for package
juliolmuller e69c9cf
refactor(cpf-dv): remove duplicate constants definitions
juliolmuller 6d7f6c9
refactor(cpf-dv): rename private methods and encapsulate parsing logic
juliolmuller 6e523d2
feat(cnpj-dv): define constants for package
juliolmuller 289f4ff
feat(cnpj-dv): implement main class of the package
juliolmuller 97fafb9
test(cnpj-dv): create unit tests for all resources
juliolmuller 4a78f45
docs(cnpj-dv): create README documentation
juliolmuller 09c7f83
docs(cnpj-dv): create Portuguese version of documentation
juliolmuller 5962324
docs(cnpj-dv): create CHANGELOG file
juliolmuller 1b53ef2
refactor(cnpj-dv): remove duplicate constants definitions
juliolmuller File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| # lacus/cnpj-dv | ||
|
|
||
| ## 1.0.0 | ||
|
|
||
| ### 🚀 Stable Version Released! | ||
|
|
||
| Utility class to calculate check digits on CNPJ (Cadastro Nacional da Pessoa Jurídica). Main features: | ||
|
|
||
| - **Flexible input**: Accepts string or array of strings (formatted or raw). | ||
| - **Format agnostic**: Automatically strips non-numeric characters from input. | ||
| - **Lazy evaluation & caching**: Check digits are calculated only when accessed for the first time. | ||
| - **Minimal dependencies**: [`lacus/utils`](https://packagist.org/packages/lacus/utils) only. | ||
| - **Error handling**: Specific types for type, length, and invalid input scenarios (`TypeError` / `Exception` hierarchy). | ||
|
|
||
| For detailed usage and API reference, see the [README](./README.md). |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| MIT License | ||
|
|
||
| Copyright (c) 2026 Julio L. Muller | ||
|
|
||
| Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: | ||
|
|
||
| The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. | ||
|
|
||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,171 @@ | ||
|  | ||
|
|
||
| [](https://packagist.org/packages/lacus/cnpj-dv) | ||
| [](https://packagist.org/packages/lacus/cnpj-dv) | ||
| [](https://www.php.net/) | ||
| [](https://github.com/LacusSolutions/br-utils-php/actions) | ||
| [](https://github.com/LacusSolutions/br-utils-php) | ||
| [](https://github.com/LacusSolutions/br-utils-php/blob/main/LICENSE) | ||
|
|
||
| > 🚀 **Full support for the [new alphanumeric CNPJ format](https://github.com/user-attachments/files/23937961/calculodvcnpjalfanaumerico.pdf).** | ||
|
|
||
| > 🌎 [Acessar documentação em português](https://github.com/LacusSolutions/br-utils-php/blob/main/packages/cnpj-dv/README.pt.md) | ||
|
|
||
| A PHP utility to calculate check digits on CNPJ (Brazilian Business Tax ID). | ||
|
|
||
| ## PHP Support | ||
|
|
||
| |  |  |  |  | | ||
| | --- | --- | --- | --- | | ||
| | Passing ✔ | Passing ✔ | Passing ✔ | Passing ✔ | | ||
|
|
||
| ## Features | ||
|
|
||
| - ✅ **Alphanumeric CNPJ**: Full support for the new alphanumeric CNPJ format (introduced in 2026) | ||
| - ✅ **Flexible input**: Accepts `string` or `array` of strings | ||
| - ✅ **Format agnostic**: Strips non-alphanumeric characters from string input and uppercases letters | ||
| - ✅ **Auto-expansion**: Multi-character strings in arrays are joined and parsed like a single string | ||
| - ✅ **Input validation**: Rejects ineligible CNPJs (all-zero base ID `00000000`, all-zero branch `0000`, or 12 numeric-only repeated digits) | ||
| - ✅ **Lazy evaluation**: Check digits are calculated only when accessed (via properties) | ||
| - ✅ **Caching**: Calculated values are cached for subsequent access | ||
| - ✅ **Property-style API**: `first`, `second`, `both`, `cnpj` (via magic `__get`) | ||
| - ✅ **Minimal dependencies**: Only [`lacus/utils`](https://packagist.org/packages/lacus/utils) | ||
| - ✅ **Error handling**: Specific types for type, length, and invalid CNPJ scenarios (`TypeError` vs `Exception` semantics) | ||
|
|
||
| ## Installation | ||
|
|
||
| ```bash | ||
| # using Composer | ||
| $ composer require lacus/cnpj-dv | ||
| ``` | ||
|
|
||
| ## Quick Start | ||
|
|
||
| ```php | ||
| <?php | ||
|
|
||
| use Lacus\BrUtils\Cnpj\CnpjCheckDigits; | ||
|
|
||
| $checkDigits = new CnpjCheckDigits('914157320007'); | ||
|
|
||
| $checkDigits->first; // '9' | ||
| $checkDigits->second; // '3' | ||
| $checkDigits->both; // '93' | ||
| $checkDigits->cnpj; // '91415732000793' | ||
| ``` | ||
|
|
||
| With alphanumeric CNPJ (new format): | ||
|
|
||
| ```php | ||
| <?php | ||
|
|
||
| use Lacus\BrUtils\Cnpj\CnpjCheckDigits; | ||
|
|
||
| $checkDigits = new CnpjCheckDigits('MGKGMJ9X0001'); | ||
|
|
||
| $checkDigits->first; // '6' | ||
| $checkDigits->second; // '8' | ||
| $checkDigits->both; // '68' | ||
| $checkDigits->cnpj; // 'MGKGMJ9X000168' | ||
| ``` | ||
|
|
||
| ## Usage | ||
|
|
||
| The main resource of this package is the class `CnpjCheckDigits`. Through an instance, you access CNPJ check-digit information: | ||
|
|
||
| - **`__construct`**: `new CnpjCheckDigits(string|array $cnpjInput)` — 12–14 alphanumeric characters after sanitization (formatting stripped from strings; letters uppercased). Only the **first 12** characters are used as the base; if you pass 13 or 14 characters (e.g. a full CNPJ including prior check digits), characters 13–14 are **ignored** and the digits are recalculated. | ||
| - **`first`**: First check digit (13th character of the full CNPJ). Lazy, cached. | ||
| - **`second`**: Second check digit (14th character of the full CNPJ). Lazy, cached. | ||
| - **`both`**: Both check digits concatenated as a string. | ||
| - **`cnpj`**: The complete CNPJ as a string of 14 characters (12 base characters + 2 check digits). | ||
|
|
||
| ### Input formats | ||
|
|
||
| The `CnpjCheckDigits` class accepts multiple input formats: | ||
|
|
||
| **String input:** raw digits and/or letters, or formatted CNPJ (e.g. `91.415.732/0007-93`, `MG.KGM.J9X/0001-68`). Non-alphanumeric characters are removed; lowercase letters are uppercased. | ||
|
|
||
| **Array of strings:** each element must be a string; values are concatenated and then parsed like a single string (e.g. `['9','1','4',…]`, `['9141','5732','0007']`, `['MG','KGM','J9X','0001']`). Non-string elements are not allowed. | ||
|
|
||
| ### Errors & exceptions handling | ||
|
|
||
| This package uses **TypeError vs Exception** semantics: *type errors* indicate incorrect API use (e.g. wrong type); *exceptions* indicate invalid or ineligible data (e.g. invalid length or business rules). You can catch specific classes or use the abstract bases. | ||
|
|
||
| - **CnpjCheckDigitsTypeError** (_abstract_) — base for type errors; extends PHP’s `TypeError` | ||
| - **CnpjCheckDigitsInputTypeError** — input is not `string` or `array` of strings (or array contains a non-string element) | ||
| - **CnpjCheckDigitsException** (_abstract_) — base for data/flow exceptions; extends `Exception` | ||
| - **CnpjCheckDigitsInputLengthException** — sanitized length is not 12–14 | ||
| - **CnpjCheckDigitsInputInvalidException** — base ID `00000000`, branch ID `0000`, or 12 identical numeric digits (repeated-digit pattern) | ||
|
|
||
| ```php | ||
| <?php | ||
|
|
||
| use Lacus\BrUtils\Cnpj\CnpjCheckDigits; | ||
| use Lacus\BrUtils\Cnpj\Exceptions\CnpjCheckDigitsException; | ||
| use Lacus\BrUtils\Cnpj\Exceptions\CnpjCheckDigitsInputInvalidException; | ||
| use Lacus\BrUtils\Cnpj\Exceptions\CnpjCheckDigitsInputLengthException; | ||
| use Lacus\BrUtils\Cnpj\Exceptions\CnpjCheckDigitsInputTypeError; | ||
|
|
||
| // Input type (e.g. integer not allowed) | ||
| try { | ||
| new CnpjCheckDigits(12345678000100); | ||
| } catch (CnpjCheckDigitsInputTypeError $e) { | ||
| echo $e->getMessage(); | ||
| } | ||
|
|
||
| // Length (must be 12–14 alphanumeric characters after sanitization) | ||
| try { | ||
| new CnpjCheckDigits('12345678901'); | ||
| } catch (CnpjCheckDigitsInputLengthException $e) { | ||
| echo $e->getMessage(); | ||
| } | ||
|
|
||
| // Invalid (e.g. all-zero base or branch, or repeated numeric digits) | ||
| try { | ||
| new CnpjCheckDigits('000000000001'); | ||
| } catch (CnpjCheckDigitsInputInvalidException $e) { | ||
| echo $e->getMessage(); | ||
| } | ||
|
|
||
| // Any data exception from the package | ||
| try { | ||
| // risky code | ||
| } catch (CnpjCheckDigitsException $e) { | ||
| // handle | ||
| } | ||
| ``` | ||
|
|
||
| ### Other available resources | ||
|
|
||
| - **`CNPJ_MIN_LENGTH`**: `12` — class constant `CnpjCheckDigits::CNPJ_MIN_LENGTH`, and global `Lacus\BrUtils\Cnpj\CNPJ_MIN_LENGTH` when the autoloaded `cnpj-dv.php` file is loaded. | ||
| - **`CNPJ_MAX_LENGTH`**: `14` — class constant `CnpjCheckDigits::CNPJ_MAX_LENGTH`, and global `Lacus\BrUtils\Cnpj\CNPJ_MAX_LENGTH` when `cnpj-dv.php` is loaded. | ||
|
|
||
| ## Calculation algorithm | ||
|
|
||
| The package computes check digits with the official Brazilian modulo-11 rules extended to alphanumeric characters: | ||
|
|
||
| 1. **Character value:** each character contributes `ord(character) − 48` (so `0`–`9` stay 0–9; letters use their ASCII offset from `0`). | ||
| 2. **Weights:** from **right to left**, multiply by weights that cycle **2, 3, 4, 5, 6, 7, 8, 9**, then repeat from 2. | ||
| 3. **First check digit (13th position):** apply steps 1–2 to the first **12** base characters; let `r = sum % 11`. The digit is `0` if `r < 2`, otherwise `11 − r`. | ||
| 4. **Second check digit (14th position):** apply steps 1–2 to the first 12 characters **plus** the first check digit; same formula for `r`. | ||
|
|
||
| ## Contribution & Support | ||
|
|
||
| We welcome contributions! Please see our [Contributing Guidelines](https://github.com/LacusSolutions/br-utils-php/blob/main/CONTRIBUTING.md) for details. If you find this project helpful, please consider: | ||
|
|
||
| - ⭐ Starring the repository | ||
| - 🤝 Contributing to the codebase | ||
| - 💡 [Suggesting new features](https://github.com/LacusSolutions/br-utils-php/issues) | ||
| - 🐛 [Reporting bugs](https://github.com/LacusSolutions/br-utils-php/issues) | ||
|
|
||
| ## License | ||
|
|
||
| This project is licensed under the MIT License — see the [LICENSE](https://github.com/LacusSolutions/br-utils-php/blob/main/LICENSE) file for details. | ||
|
|
||
| ## Changelog | ||
|
|
||
| See [CHANGELOG](https://github.com/LacusSolutions/br-utils-php/blob/main/packages/cnpj-dv/CHANGELOG.md) for a list of changes and version history. | ||
|
|
||
| --- | ||
|
|
||
| Made with ❤️ by [Lacus Solutions](https://github.com/LacusSolutions) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,143 @@ | ||
|  | ||
|
|
||
| > 🚀 **Suporte total ao [novo formato alfanumérico de CNPJ](https://github.com/user-attachments/files/23937961/calculodvcnpjalfanaumerico.pdf).** | ||
|
|
||
| > 🌎 [Access documentation in English](https://github.com/LacusSolutions/br-utils-php/blob/main/packages/cnpj-dv/README.md) | ||
|
|
||
| Utilitário em PHP para calcular os dígitos verificadores de CNPJ (Cadastro Nacional da Pessoa Jurídica). | ||
|
|
||
| ## Recursos | ||
|
|
||
| - ✅ **CNPJ alfanumérico**: Suporte completo ao novo formato alfanumérico de CNPJ (a partir de 2026) | ||
| - ✅ **Entrada flexível**: Aceita `string` ou `array` de strings | ||
| - ✅ **Agnóstico ao formato**: Remove caracteres não alfanuméricos da entrada em string e converte letras para maiúsculas | ||
| - ✅ **Junção em array**: Strings com vários caracteres em arrays são concatenadas e interpretadas como uma única sequência | ||
| - ✅ **Validação de entrada**: Rejeita CNPJs inelegíveis (base toda zero `00000000`, filial `0000`, ou 12 dígitos numéricos repetidos) | ||
| - ✅ **Avaliação lazy**: Dígitos verificadores são calculados apenas quando acessados (via propriedades) | ||
| - ✅ **Cache**: Valores calculados são armazenados em cache para acessos subsequentes | ||
| - ✅ **API estilo propriedades**: `first`, `second`, `both`, `cnpj` (via `__get` mágico) | ||
| - ✅ **Dependências mínimas**: Apenas [`lacus/utils`](https://packagist.org/packages/lacus/utils) | ||
| - ✅ **Tratamento de erros**: Tipos específicos para tipo, tamanho e CNPJ inválido (semântica `TypeError` vs `Exception`) | ||
|
|
||
| ## Instalação | ||
|
|
||
| ```bash | ||
| # usando Composer | ||
| $ composer require lacus/cnpj-dv | ||
| ``` | ||
|
|
||
| ## Início rápido | ||
|
|
||
| ```php | ||
| <?php | ||
|
|
||
| use Lacus\BrUtils\Cnpj\CnpjCheckDigits; | ||
|
|
||
| $checkDigits = new CnpjCheckDigits('914157320007'); | ||
|
|
||
| $checkDigits->first; // '9' | ||
| $checkDigits->second; // '3' | ||
| $checkDigits->both; // '93' | ||
| $checkDigits->cnpj; // '91415732000793' | ||
| ``` | ||
|
|
||
| ## Utilização | ||
|
|
||
| O principal recurso deste pacote é a classe `CnpjCheckDigits`. Por meio da instância, você acessa as informações dos dígitos verificadores do CNPJ: | ||
|
|
||
| - **`__construct`**: `new CnpjCheckDigits(string|array $cnpjInput)` — 12–14 caracteres alfanuméricos após a sanitização (formatação removida em strings; letras em maiúsculas). Apenas os **primeiros 12** caracteres entram como base; com 13 ou 14 caracteres (ex.: CNPJ completo com DV anteriores), os caracteres 13 e 14 são **ignorados** e os dígitos são recalculados. | ||
| - **`first`**: Primeiro dígito verificador (13º caractere do CNPJ completo). Lazy, em cache. | ||
| - **`second`**: Segundo dígito verificador (14º caractere do CNPJ completo). Lazy, em cache. | ||
| - **`both`**: Ambos os dígitos verificadores concatenados em uma string. | ||
| - **`cnpj`**: O CNPJ completo como string de 14 caracteres (12 da base + 2 dígitos verificadores). | ||
|
|
||
| ### Formatos de entrada | ||
|
|
||
| A classe `CnpjCheckDigits` aceita múltiplos formatos de entrada: | ||
|
|
||
| **String:** dígitos e/ou letras crus, ou CNPJ formatado (ex.: `91.415.732/0007-93`, `MG.KGM.J9X/0001-68`). Caracteres não alfanuméricos são removidos; letras minúsculas viram maiúsculas. | ||
|
|
||
| **Array de strings:** cada elemento deve ser string; os valores são concatenados e interpretados como uma única string (ex.: `['9','1','4',…]`, `['9141','5732','0007']`, `['MG','KGM','J9X','0001']`). Elementos que não são string não são permitidos. | ||
|
|
||
| ### Erros e exceções | ||
|
|
||
| Este pacote usa a distinção **TypeError vs Exception**: *erros de tipo* indicam uso incorreto da API (ex.: tipo errado); *exceções* indicam dados inválidos ou inelegíveis (ex.: tamanho ou regras de negócio). Você pode capturar classes específicas ou as bases abstratas. | ||
|
|
||
| - **CnpjCheckDigitsTypeError** (_abstract_) — base para erros de tipo; estende o `TypeError` do PHP | ||
| - **CnpjCheckDigitsInputTypeError** — entrada não é `string` nem `array` de strings (ou o array contém elemento que não é string) | ||
| - **CnpjCheckDigitsException** (_abstract_) — base para exceções de dados/fluxo; estende `Exception` | ||
| - **CnpjCheckDigitsInputLengthException** — tamanho após sanitização não é 12–14 | ||
| - **CnpjCheckDigitsInputInvalidException** — base `00000000`, filial `0000`, ou 12 dígitos numéricos idênticos (padrão de repetição) | ||
juliolmuller marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| ```php | ||
| <?php | ||
|
|
||
| use Lacus\BrUtils\Cnpj\CnpjCheckDigits; | ||
| use Lacus\BrUtils\Cnpj\Exceptions\CnpjCheckDigitsException; | ||
| use Lacus\BrUtils\Cnpj\Exceptions\CnpjCheckDigitsInputInvalidException; | ||
| use Lacus\BrUtils\Cnpj\Exceptions\CnpjCheckDigitsInputLengthException; | ||
| use Lacus\BrUtils\Cnpj\Exceptions\CnpjCheckDigitsInputTypeError; | ||
|
|
||
| // Tipo de entrada (ex.: inteiro não permitido) | ||
| try { | ||
| new CnpjCheckDigits(12345); | ||
| } catch (CnpjCheckDigitsInputTypeError $e) { | ||
| echo $e->getMessage(); | ||
| } | ||
|
|
||
| // Tamanho (deve ser 12–14 caracteres alfanuméricos após sanitização) | ||
| try { | ||
| new CnpjCheckDigits('12345678901'); | ||
| } catch (CnpjCheckDigitsInputLengthException $e) { | ||
| echo $e->getMessage(); | ||
| } | ||
|
|
||
| // Inválido (ex.: base ou filial zeradas, ou dígitos numéricos repetidos) | ||
| try { | ||
| new CnpjCheckDigits('000000000001'); | ||
| } catch (CnpjCheckDigitsInputInvalidException $e) { | ||
| echo $e->getMessage(); | ||
| } | ||
|
|
||
| // Qualquer exceção de dados do pacote | ||
| try { | ||
| // código arriscado | ||
| } catch (CnpjCheckDigitsException $e) { | ||
| // tratar | ||
| } | ||
| ``` | ||
|
|
||
| ### Outros recursos disponíveis | ||
|
|
||
| - **`CNPJ_MIN_LENGTH`**: `12` — constante de classe `CnpjCheckDigits::CNPJ_MIN_LENGTH`, e constante global `Lacus\BrUtils\Cnpj\CNPJ_MIN_LENGTH` quando `cnpj-dv.php` é carregado pelo autoload do Composer. | ||
| - **`CNPJ_MAX_LENGTH`**: `14` — constante de classe `CnpjCheckDigits::CNPJ_MAX_LENGTH`, e constante global `Lacus\BrUtils\Cnpj\CNPJ_MAX_LENGTH` quando `cnpj-dv.php` é carregado pelo autoload do Composer. | ||
|
|
||
| ## Algoritmo de cálculo | ||
|
|
||
| O pacote calcula os dígitos verificadores com as regras oficiais brasileiras de módulo 11 estendidas a caracteres alfanuméricos: | ||
|
|
||
| 1. **Valor do caractere:** cada caractere contribui com `ord(caractere) − 48` (assim `0`–`9` permanecem 0–9; letras usam o deslocamento ASCII em relação a `0`). | ||
| 2. **Pesos:** da **direita para a esquerda**, multiplicar pelos pesos que ciclam **2, 3, 4, 5, 6, 7, 8, 9** e voltam a 2. | ||
| 3. **Primeiro dígito verificador (13ª posição):** aplicar os itens 1–2 aos **primeiros 12** caracteres da base; seja `r = soma % 11`. O dígito é `0` se `r < 2`, senão `11 − r`. | ||
| 4. **Segundo dígito verificador (14ª posição):** aplicar os itens 1–2 aos 12 primeiros caracteres **mais** o primeiro dígito verificador; mesma fórmula para `r`. | ||
|
|
||
| ## Contribuição e suporte | ||
|
|
||
| Contribuições são bem-vindas! Consulte as [Diretrizes de contribuição](https://github.com/LacusSolutions/br-utils-php/blob/main/CONTRIBUTING.md). Se o projeto for útil para você, considere: | ||
|
|
||
| - ⭐ Dar uma estrela no repositório | ||
| - 🤝 Contribuir com código | ||
| - 💡 [Sugerir novas funcionalidades](https://github.com/LacusSolutions/br-utils-php/issues) | ||
| - 🐛 [Reportar bugs](https://github.com/LacusSolutions/br-utils-php/issues) | ||
|
|
||
| ## Licença | ||
|
|
||
| Este projeto está sob a licença MIT — veja o arquivo [LICENSE](https://github.com/LacusSolutions/br-utils-php/blob/main/LICENSE). | ||
|
|
||
| ## Changelog | ||
|
|
||
| Veja o [CHANGELOG](https://github.com/LacusSolutions/br-utils-php/blob/main/packages/cnpj-dv/CHANGELOG.md) para alterações e histórico de versões. | ||
|
|
||
| --- | ||
|
|
||
| Feito com ❤️ por [Lacus Solutions](https://github.com/LacusSolutions) | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.