Biblioteca para validação e manipulação de documentos brasileiros (CPF, CNPJ, RG, etc)
$ dotnet add package Tsaas.Documents.BrUma biblioteca .NET moderna e robusta para validacao e formatacao de documentos brasileiros (CPF e CNPJ) com suporte a CNPJs alfanumericos.
IDocument para extensibilidadedotnet add package Tsaas.Documents.BrOu via Package Manager Console:
Install-Package Tsaas.Documents.Brusing Tsaas.Documents.Br.Documents;
using Tsaas.Documents.Br.Exceptions;
// Criar um CPF valido
var cpf = new Cpf("123.456.789-09");
// Propriedades disponiveis
Console.WriteLine(cpf.Value); // "123.456.789-09" (valor original)
Console.WriteLine(cpf.UnformattedValue); // "12345678909" (sem formatacao)
Console.WriteLine(cpf.FormattedValue); // "123.456.789-09" (formatado)
Console.WriteLine(cpf.IsValid); // true (com cache)
// CPF sem formatacao tambem funciona
var cpf2 = new Cpf("12345678909");
Console.WriteLine(cpf2.FormattedValue); // "123.456.789-09"// TryCreate - retorna null se invalido
var cpfValido = Cpf.TryCreate("987.654.321-00");
if (cpfValido != null)
{
Console.WriteLine($"CPF valido: {cpfValido.FormattedValue}");
}
var cpfInvalido = Cpf.TryCreate("111.111.111-11");
Console.WriteLine(cpfInvalido == null); // true
// TryParse - padrao .NET
if (Cpf.TryParse("111.444.777-35", out var cpf))
{
Console.WriteLine($"CPF parseado: {cpf.FormattedValue}");
}var cpf = new Cpf("123.456.789-09");
// Conversao implicita para string
string cpfString = cpf;
Console.WriteLine(cpfString); // "123.456.789-09"
// ToString() tambem funciona
Console.WriteLine(cpf.ToString()); // "123.456.789-09"var cpf1 = new Cpf("123.456.789-09");
var cpf2 = new Cpf("12345678909");
var cpf3 = new Cpf("111.444.777-35");
Console.WriteLine(cpf1 == cpf2); // true (mesmo valor, formatacao diferente)
Console.WriteLine(cpf1 != cpf3); // true (valores diferentes)
Console.WriteLine(cpf1.Equals(cpf2)); // true
Console.WriteLine(cpf1.GetHashCode() == cpf2.GetHashCode()); // true
// Funciona em colecoes
var cpfSet = new HashSet<Cpf> { cpf1, cpf2, cpf3 };
Console.WriteLine(cpfSet.Count); // 2 (cpf1 e cpf2 sao considerados iguais)try
{
var cpfInvalido = new Cpf("123.456.789-00"); // DV incorreto
}
catch (InvalidDocumentException ex)
{
Console.WriteLine(ex.Message); // "O documento CPF '123.456.789-00' e invalido."
Console.WriteLine(ex.DocumentType); // "CPF"
Console.WriteLine(ex.DocumentValue); // "123.456.789-00"
}Validacoes aplicadas:
using Tsaas.Documents.Br.Documents;
// CNPJ numerico
var cnpj = new Cnpj("11.222.333/0001-81");
Console.WriteLine(cnpj.Value); // "11.222.333/0001-81"
Console.WriteLine(cnpj.UnformattedValue); // "11222333000181"
Console.WriteLine(cnpj.FormattedValue); // "11.222.333/0001-81"
Console.WriteLine(cnpj.IsValid); // true
// CNPJ sem formatacao
var cnpj2 = new Cnpj("90021382000122");
Console.WriteLine(cnpj2.FormattedValue); // "90.021.382/0001-22"
// CNPJ alfanumerico (A-Z e 0-9)
var cnpjAlfa = new Cnpj("12ABC34501DE35");
Console.WriteLine(cnpjAlfa.FormattedValue); // "12.ABC.345/01DE-35"
Console.WriteLine(cnpjAlfa.IsValid); // true// TryCreate
var cnpjValido = Cnpj.TryCreate("90.024.778/0001-23");
var cnpjInvalido = Cnpj.TryCreate("11.111.111/1111-11");
Console.WriteLine(cnpjValido.FormattedValue); // "90.024.778/0001-23"
Console.WriteLine(cnpjInvalido == null); // true
// TryParse
if (Cnpj.TryParse("90021382000122", out var cnpj))
{
Console.WriteLine($"CNPJ parseado: {cnpj.FormattedValue}");
}var cnpj1 = new Cnpj("11.222.333/0001-81");
var cnpj2 = new Cnpj("11222333000181");
// Conversao implicita
string cnpjString = cnpj1;
Console.WriteLine(cnpjString); // "11.222.333/0001-81"
// Comparacao
Console.WriteLine(cnpj1 == cnpj2); // true (mesmo valor)
Console.WriteLine(cnpj1.GetHashCode() == cnpj2.GetHashCode()); // true
// Em colecoes
var cnpjSet = new HashSet<Cnpj> { cnpj1, cnpj2 };
Console.WriteLine(cnpjSet.Count); // 1 (sao considerados iguais)try
{
var cnpj = new Cnpj("00.000.000/0000-00"); // CNPJ zerado
}
catch (InvalidDocumentException ex)
{
Console.WriteLine(ex.Message); // "O documento CNPJ '00.000.000/0000-00' e invalido."
}
try
{
var cnpj = new Cnpj("1345c3A5000106"); // Letra minuscula (invalido)
}
catch (InvalidDocumentException ex)
{
Console.WriteLine(ex.Message); // "O documento CNPJ '1345c3A5000106' e invalido."
}Validacoes aplicadas:
Trabalhe de forma generica com diferentes tipos de documentos:
using Tsaas.Documents.Br.Abstractions;
using Tsaas.Documents.Br.Documents;
void ProcessarDocumento(IDocument documento)
{
Console.WriteLine($"Tipo: {documento.GetType().Name}");
Console.WriteLine($"Original: {documento.Value}");
Console.WriteLine($"Formatado: {documento.FormattedValue}");
Console.WriteLine($"Sem formatacao: {documento.UnformattedValue}");
Console.WriteLine($"Valido: {documento.IsValid}");
}
IDocument cpf = new Cpf("123.456.789-09");
IDocument cnpj = new Cnpj("11.222.333/0001-81");
ProcessarDocumento(cpf);
ProcessarDocumento(cnpj);Cpf cpfNulo = null;
Cnpj cnpjNulo = null;
// Conversao implicita retorna string vazia
string cpfString = cpfNulo; // ""
string cnpjString = cnpjNulo; // ""
Console.WriteLine(cpfNulo == null); // true
Console.WriteLine(cnpjNulo == null); // true
### Componentes Principais
#### IDocument
Interface que define o contrato para todos os documentos:
```csharp
public interface IDocument
{
string Value { get; } // Valor original fornecido
string UnformattedValue { get; } // Valor sem formatacao (cached)
string FormattedValue { get; } // Valor formatado (padrao brasileiro)
bool IsValid { get; } // Validacao (cached)
}
Classe abstrata que implementa funcionalidades comuns:
UnformattedValue e IsValidpublic abstract class DocumentBase : IDocument
{
protected DocumentBase(string value);
public string Value { get; }
public string UnformattedValue { get; } // Lazy cached
public abstract string FormattedValue { get; }
public bool IsValid { get; } // Lazy cached
protected abstract bool Validate();
}Implementam o Value Object Pattern completo:
Excecao especializada que contem informacoes detalhadas:
public class InvalidDocumentException : Exception
{
public string DocumentType { get; } // "CPF" ou "CNPJ"
public string DocumentValue { get; } // Valor que causou a excecao
public override string Message { get; } // Mensagem formatada
}Exemplo de calculo para CNPJ alfanumerico:
Base: 12ABC3450001
Pesos: [5,4,3,2,9,8,7,6,5,4,3,2]
'1' = ASCII 49 -> (49-48) * 5 = 5
'2' = ASCII 50 -> (50-48) * 4 = 8
'A' = ASCII 65 -> (65-48) * 3 = 51
...
O projeto inclui 100% de cobertura de testes com xUnit:
# Executar todos os testes
dotnet test
# Com cobertura
dotnet test /p:CollectCoverage=trueCPF:
CNPJ:
Seguimos Semantic Versioning:
Este projeto esta sob a licenca MIT. Veja o arquivo LICENSE para mais detalhes.
Contribuicoes sao bem-vindas! Por favor:
git checkout -b feature/MinhaFeature)git commit -m 'Adiciona MinhaFeature')git push origin feature/MinhaFeature)Encontrou um bug? Por favor, abra uma issue com:
Funcionalidades planejadas:
TSaaS Solutions - GitHub
Obrigado a todos que contribuiram para este projeto!
Se este projeto foi util para voce, considere dar uma estrela no GitHub!