Logo do Brazilian Utils

Biblioteca de utilitários projetada para validar, gerar e manipular dados de acordo com as particularidades do Brasil.

GitHub LicensePackage versionrun-testscheck-static

Looking for the english version?

Introdução

Brazilian Utils é uma biblioteca com foco na resolução de problemas que enfrentamos diariamente no desenvolvimento de aplicações para negócios brasileiros.

Instalação

Adicione brutils ao seu rebar.config:

{deps, [
{brutils, "0.1.2"}
]}.

Build

Requer Erlang/OTP 25 ou superior (testado nas versões 25, 26 e 27).

rebar3 compile

Gere a documentação da API com:

rebar3 edoc

Utilização

Todas as funções estão disponíveis por meio do módulo fachada brutils e operam sobre binários UTF-8:

1> brutils:is_valid_cpf(<<"82178537464">>).
true

Cada utilitário também existe em seu próprio módulo (brutils_cpf, ...) com nomes sem sufixo (brutils_cpf:is_valid/1), caso você prefira depender diretamente do módulo de domínio.

Utilitários

CPF

is_valid_cpf

Retorna se os dígitos verificadores do CPF informado correspondem ao seu número-base. Esta função não verifica a existência do CPF; ela apenas valida o formato da string.

Argumentos:

Retorna:

Exemplo:

1> brutils:is_valid_cpf(<<"82178537464">>).
true
2> brutils:is_valid_cpf(<<"00011122233">>).
false

format_cpf

Formata um CPF válido para exibição, adicionando os símbolos visuais padrão (XXX.XXX.XXX-XX).

Argumentos:

Retorna:

Exemplo:

1> brutils:format_cpf(<<"82178537464">>).
{ok,<<"821.785.374-64">>}
2> brutils:format_cpf(<<"00011122233">>).
{error,invalid}

remove_symbols_cpf

Remove os símbolos . e - de uma string de CPF. Apenas esses dois caracteres são removidos; qualquer outro é preservado.

Argumentos:

Retorna:

Exemplo:

1> brutils:remove_symbols_cpf(<<"000.111.222-33">>).
<<"00011122233">>

generate_cpf

Gera um CPF válido aleatório como binário contendo apenas números.

Retorna:

Exemplo:

1> brutils:generate_cpf().
<<"44635843700">>
2> brutils:generate_cpf().
<<"06854668417">>

CNPJ

is_valid_cnpj

Retorna se os dígitos verificadores do CNPJ informado correspondem ao seu número-base. Tanto o formato numérico quanto o formato alfanumérico de 2026 (dígitos e letras maiúsculas nos 12 primeiros caracteres) são suportados. Esta função não verifica a existência do CNPJ; ela apenas valida o formato da string.

Argumentos:

Retorna:

Exemplo:

1> brutils:is_valid_cnpj(<<"03560714000142">>).
true
2> brutils:is_valid_cnpj(<<"00111222000133">>).
false
3> brutils:is_valid_cnpj(<<"6Q4E392H000190">>).
true

format_cnpj

Formata um CNPJ válido para exibição, adicionando os símbolos visuais padrão (XX.XXX.XXX/XXXX-XX).

Argumentos:

Retorna:

Exemplo:

1> brutils:format_cnpj(<<"03560714000142">>).
{ok,<<"03.560.714/0001-42">>}
2> brutils:format_cnpj(<<"00111222000133">>).
{error,invalid}

remove_symbols_cnpj

Remove os símbolos ., / e - de uma string de CNPJ. Apenas esses três caracteres são removidos; qualquer outro é preservado.

Argumentos:

Retorna:

Exemplo:

1> brutils:remove_symbols_cnpj(<<"03.560.714/0001-42">>).
<<"03560714000142">>

generate_cnpj

Gera um CNPJ válido aleatório. Um número de filial opcional pode ser informado (inteiro não negativo ou binário contendo apenas dígitos; o padrão é 1), e uma flag opcional permite usar o formato alfanumérico de 2026, em que a filial também pode conter letras maiúsculas e filiais inválidas são substituídas por 0001.

Retorna:

Exemplo:

1> brutils:generate_cnpj().
<<"95427181000143">>
2> brutils:generate_cnpj(1234).
<<"44122762123483">>
3> brutils:generate_cnpj(<<"AB12">>, true).
<<"X8641237AB1272">>

PIS

is_valid_pis

Retorna se o dígito verificador do PIS/PASEP informado corresponde ao seu número-base. Esta função não verifica a existência do PIS; ela apenas valida o formato da string.

Argumentos:

Retorna:

Exemplo:

1> brutils:is_valid_pis(<<"12056798818">>).
true
2> brutils:is_valid_pis(<<"12056798810">>).
false
3> brutils:is_valid_pis(<<"00000000000">>).
true

format_pis

Formata um PIS válido para exibição, adicionando os símbolos visuais padrão (NNN.NNNNN.NN-N).

Argumentos:

Retorna:

Exemplo:

1> brutils:format_pis(<<"12056798818">>).
{ok,<<"120.56798.81-8">>}
2> brutils:format_pis(<<"12056798810">>).
{error,invalid}

remove_symbols_pis

Remove os símbolos . e - de uma string de PIS. Apenas esses dois caracteres são removidos; qualquer outro é preservado.

Argumentos:

Retorna:

Exemplo:

1> brutils:remove_symbols_pis(<<"120.56798.81-8">>).
<<"12056798818">>

generate_pis

Gera um PIS válido aleatório como binário contendo apenas números. A base é sorteada uniformemente com zero incluído, então os resultados podem começar com zero.

Retorna:

Exemplo:

1> brutils:generate_pis().
<<"99360519414">>
2> brutils:generate_pis().
<<"95319303914">>

CNH

is_valid_cnh

Retorna se a CNH informada (registro da Carteira Nacional de Habilitação, layout 2022) é válida: após remover todos os caracteres não numéricos, devem restar exatamente 11 dígitos, e ambos os dígitos verificadores devem corresponder ao número-base. Layouts anteriores de CNH não são suportados. Esta função não verifica a existência da CNH; ela apenas valida o formato da string.

Diferentemente dos validadores de CPF/CNPJ/PIS, os símbolos não precisam ser removidos antes: entradas formatadas como <<"987654321-00">> são aceitas, e letras são removidas em vez de rejeitadas imediatamente.

Argumentos:

Retorna:

Exemplo:

1> brutils:is_valid_cnh(<<"98765432100">>).
true
2> brutils:is_valid_cnh(<<"987654321-00">>).
true
3> brutils:is_valid_cnh(<<"12345678901">>).
false
4> brutils:is_valid_cnh(<<"A2C45678901">>).
false

RENAVAM

is_valid_renavam

Retorna se o RENAVAM informado (número de registro do veículo) é válido: exatamente 11 dígitos cujo dígito verificador corresponde ao número-base. Esta função não verifica a existência do RENAVAM; ela apenas valida o formato da string.

Diferentemente de is_valid_cnh, os símbolos não são removidos: qualquer caractere não numérico (espaço, hífen, letra) torna a entrada inválida.

Argumentos:

Retorna:

Exemplo:

1> brutils:is_valid_renavam(<<"86769597308">>).
true
2> brutils:is_valid_renavam(<<"12345678901">>).
false
3> brutils:is_valid_renavam(<<"867695973-08">>).
false
4> brutils:is_valid_renavam(<<"12345678 901">>).
false

CEP

Um CEP não possui dígito verificador: a validação é puramente estrutural, com exatamente 8 dígitos, e não informa se o código postal realmente existe. Funções de busca de endereço via ViaCEP estão planejadas para uma futura versão.

is_valid_cep

Retorna se o CEP informado é válido: um binário com exatamente 8 dígitos. Qualquer sequência de 8 dígitos é estruturalmente válida, incluindo repetições como <<"00000000">>.

Argumentos:

Retorna:

Exemplo:

1> brutils:is_valid_cep(<<"01310200">>).
true
2> brutils:is_valid_cep(<<"1310200">>).
false
3> brutils:is_valid_cep(<<"01310-200">>).
false

format_cep

Formata um CEP válido para exibição, adicionando o hífen padrão (NNNNN-NNN).

Argumentos:

Retorna:

Exemplo:

1> brutils:format_cep(<<"01310200">>).
{ok,<<"01310-200">>}
2> brutils:format_cep(<<"1234567">>).
{error,invalid}

remove_symbols_cep

Remove os símbolos . e - de uma string de CEP. Apenas esses dois caracteres são removidos; qualquer outro é preservado.

Argumentos:

Retorna:

Exemplo:

1> brutils:remove_symbols_cep(<<"01310-200">>).
<<"01310200">>

generate_cep

Gera um CEP aleatório como binário contendo apenas números. Cada dígito é sorteado de forma independente, então os resultados podem começar com zero.

Retorna:

Exemplo:

1> brutils:generate_cep().
<<"22648357">>
2> brutils:generate_cep().
<<"98885103">>

Telefone

Números de telefone brasileiros são tratados sem o código do país +55 e com o DDD de dois dígitos incluído. Existem dois formatos:

TipoDígitosFormato
celular11DDD (1-9 cada) + 9 + 8 dígitos
fixo10DDD (1-9 cada) + um dígito de 2-5 + 7 dígitos

is_valid_phone

Retorna se o número de telefone informado é válido, aceitando qualquer um dos formatos na versão de um argumento, ou um formato específico quando o átomo mobile ou landline é informado. A função não verifica se o número realmente existe. Os símbolos não são removidos; limpe a entrada com remove_symbols_phone/1 antes.

Argumentos:

Retorna:

Exemplo:

1> brutils:is_valid_phone(<<"11994029275">>).
true
2> brutils:is_valid_phone(<<"1635014415">>).
true
3> brutils:is_valid_phone(<<"11994029275">>, mobile).
true
4> brutils:is_valid_phone(<<"11994029275">>, landline).
false

format_phone

Formata um número de telefone válido para exibição: DDD entre parênteses (sem espaço depois deles) e um hífen antes dos últimos quatro dígitos.

Argumentos:

Retorna:

Exemplo:

1> brutils:format_phone(<<"11994029275">>).
{ok,<<"(11)99402-9275">>}
2> brutils:format_phone(<<"1635014415">>).
{ok,<<"(16)3501-4415">>}

remove_symbols_phone

Remove a pontuação comum de uma string de telefone: (, ), -, + e espaços. Pontos NÃO são removidos.

Argumentos:

Retorna:

Exemplo:

1> brutils:remove_symbols_phone(<<"+55 (11) 99402-9275">>).
<<"5511994029275">>

remove_international_dialing_code

Remove o código internacional brasileiro (55) de um número de telefone: se a entrada contiver 55 e tiver mais de 11 caracteres (ignorando espaços), a primeira ocorrência de 55 é removida; caso contrário, a entrada é retornada sem alterações. Observe os casos de borda: um + inicial é preservado, e o 55 removido é a primeira ocorrência, esteja ela onde estiver.

Argumentos:

Retorna:

Exemplo:

1> brutils:remove_international_dialing_code(<<"5511994029275">>).
<<"11994029275">>
2> brutils:remove_international_dialing_code(<<"+5511994029275">>).
<<"+11994029275">>

generate_phone

Gera um número de telefone válido aleatório, de tipo aleatório quando chamada sem argumentos, ou do tipo informado (mobile ou landline).

Retorna:

Exemplo:

1> brutils:generate_phone().
<<"38950126454">>
2> brutils:generate_phone(mobile).
<<"59956385883">>
3> brutils:generate_phone(landline).
<<"7529936607">>

Passaporte

Um número de passaporte brasileiro possui 2 letras maiúsculas seguidas de 6 dígitos. Não há dígito verificador, então a validade não informa existência. Observe a divisão de responsabilidades: is_valid_passport é estrita (sensível a maiúsculas e minúsculas e sem remoção de símbolos), enquanto format_passport é mais tolerante, convertendo para maiúsculas e removendo símbolos antes de validar. Assim, a mesma entrada pode falhar em uma e passar na outra.

is_valid_passport

Retorna se o número de passaporte informado é válido: exatamente 2 letras maiúsculas seguidas de exatamente 6 dígitos. Letras minúsculas e símbolos tornam a entrada inválida. Use format_passport/1 para normalizar antes, se necessário.

Argumentos:

Retorna:

Exemplo:

1> brutils:is_valid_passport(<<"AB123456">>).
true
2> brutils:is_valid_passport(<<"Ab123456">>).
false
3> brutils:is_valid_passport(<<"AB-123456">>).
false

format_passport

Normaliza e formata um número de passaporte: converte letras ASCII para maiúsculas, remove os símbolos -, . e espaços, e depois valida o resultado.

Argumentos:

Retorna:

Exemplo:

1> brutils:format_passport(<<"ab-123456">>).
{ok,<<"AB123456">>}
2> brutils:format_passport(<<"111111">>).
{error,invalid}

remove_symbols_passport

Remove os símbolos -, . e espaços de uma string de passaporte. Apenas esses três caracteres são removidos, e a caixa das letras é preservada.

Argumentos:

Retorna:

Exemplo:

1> brutils:remove_symbols_passport(<<"Ab -. 123456">>).
<<"Ab123456">>

generate_passport

Gera um número de passaporte válido aleatório: 2 letras maiúsculas uniformes seguidas de 6 dígitos uniformes.

Retorna:

Exemplo:

1> brutils:generate_passport().
<<"AP051847">>
2> brutils:generate_passport().
<<"ZN446187">>

Placa de Veículo

Existem dois padrões brasileiros de placa:

Tipo atômicoPadrãoExemplo
old_formatLLLNNNN - 3 letras + 4 dígitosABC1234
mercosulLLLNLNN - 3 letras, dígito, letra, 2 dígitosABC1D23

A validação ignora maiúsculas e minúsculas e remove espaços nas extremidades; formatação e conversão sempre retornam letras maiúsculas.

is_valid_license_plate

Retorna se a placa informada é válida, aceitando qualquer um dos padrões na forma de um argumento, ou um padrão específico quando o tipo atômico é informado.

Argumentos:

Retorna:

Exemplo:

1> brutils:is_valid_license_plate(<<"ABC1234">>).
true
2> brutils:is_valid_license_plate(<<"abc1d23">>).
true
3> brutils:is_valid_license_plate(<<"ABC-1234">>).
false
4> brutils:is_valid_license_plate(<<"ABC1234">>, mercosul).
false

format_license_plate

Formata uma placa válida para exibição: placas do formato antigo recebem um hífen após as letras, enquanto placas Mercosul permanecem sem separador, ambas em maiúsculas.

Argumentos:

Retorna:

Exemplo:

1> brutils:format_license_plate(<<"abc1234">>).
{ok,<<"ABC-1234">>}
2> brutils:format_license_plate(<<"abc1e34">>).
{ok,<<"ABC1E34">>}

remove_symbols_license_plate

Remove o hífen (-) de uma string de placa. Apenas o hífen é removido; qualquer outro caractere é preservado.

Argumentos:

Retorna:

Exemplo:

1> brutils:remove_symbols_license_plate(<<"ABC-123">>).
<<"ABC123">>

convert_license_plate_to_mercosul

Converte uma placa do formato antigo para o padrão Mercosul, substituindo o dígito na quinta posição por uma letra (0 -> A, 1 -> B, ... 9 -> J). Uma placa já no formato Mercosul gera erro, em vez de ser tratada como no-op.

Argumentos:

Retorna:

Exemplo:

1> brutils:convert_license_plate_to_mercosul(<<"ABC4567">>).
{ok,<<"ABC4F67">>}
2> brutils:convert_license_plate_to_mercosul(<<"ABC1D23">>).
{error,invalid}

get_format_license_plate

Detecta o padrão de uma placa, retornando o átomo correspondente (old_format para LLLNNNN e mercosul para LLLNLNN). O resultado pode ser usado diretamente em is_valid_license_plate/2.

Argumentos:

Retorna:

Exemplo:

1> brutils:get_format_license_plate(<<"abc1234">>).
{ok,old_format}
2> brutils:get_format_license_plate(<<"ABC1D23">>).
{ok,mercosul}

generate_license_plate

Gera uma placa válida aleatória, Mercosul quando chamada sem argumentos, ou no padrão informado (<<"LLLNNNN">> ou <<"LLLNLNN">>, sem diferenciar maiúsculas de minúsculas).

Retorna:

Exemplo:

1> brutils:generate_license_plate().
{ok,<<"WMF1O31">>}
2> brutils:generate_license_plate(<<"LLLNNNN">>).
{ok,<<"BFX5517">>}

Título de Eleitor

Um título de eleitor brasileiro é lido da direita para a esquerda:

CampoDígitosPosição
número sequencial8 (ou 9 em alguns títulos de SP/MG)início
unidade federativa2antes dos dígitos verificadores
dígitos verificadores2final

Títulos normalmente possuem 12 dígitos; títulos de São Paulo e Minas Gerais podem ter 13 (um dígito sequencial extra que o checksum ignora). Os códigos de UF vão de 01 (SP) a 27 (TO), com 28 (ZZ) para títulos emitidos no exterior.

is_valid_voter_id

Retorna se o título de eleitor informado é válido: tamanho correto para sua UF, código em faixa válida, e ambos os dígitos verificadores correspondendo ao valor esperado. Esta função não verifica a existência do título; ela apenas valida o formato da string.

Argumentos:

Retorna:

Exemplo:

1> brutils:is_valid_voter_id(<<"690847092828">>).
true
2> brutils:is_valid_voter_id(<<"690847092820">>).
false
3> brutils:is_valid_voter_id(<<"3476353100183">>).
true

format_voter_id

Formata um título de eleitor válido de 12 dígitos para exibição com espaços visuais (NNNN NNNN NN NN). Títulos válidos de 13 dígitos de SP/MG retornam {error, invalid}: como a máscara não comporta o dígito extra, eles são rejeitados em vez de truncados.

Argumentos:

Retorna:

Exemplo:

1> brutils:format_voter_id(<<"690847092828">>).
{ok,<<"6908 4709 28 28">>}
2> brutils:format_voter_id(<<"3476353100183">>).
{error,invalid}

generate_voter_id

Gera um título de eleitor válido aleatório de 12 dígitos, emitido no exterior (ZZ) quando chamada sem argumentos, ou para a unidade federativa informada (código de duas letras, sem diferenciar maiúsculas de minúsculas).

Retorna:

Exemplo:

1> brutils:generate_voter_id().
{ok,<<"469000172810">>}
2> brutils:generate_voter_id(<<"sp">>).
{ok,<<"569431460183">>}
3> brutils:generate_voter_id(<<"XX">>).
{error,invalid}

Autor

Camilo Cunha de Azevedo camilotk@gmail.com

Novos Utilitários e Reportar Bugs

Caso queira sugerir novas funcionalidades ou reportar bugs, basta criar uma nova issue, e iremos lhe responder por lá.

(Para saber mais sobre GitHub Issues, confira a documentação oficial do GitHub.)

Dúvidas? Ideias?

Dúvidas sobre como utilizar a biblioteca? Novas ideias para o projeto? Quer compartilhar algo com a gente? Fique à vontade para criar um tópico em nosso Discussions, que iremos interagir por lá.

(Para saber mais sobre GitHub Discussions, confira a documentação oficial do GitHub.)

Contribuindo com o Código do Projeto

Sua colaboração é sempre muito bem-vinda. Enquanto este repositório ainda não possui um CONTRIBUTING.md, você pode contribuir abrindo uma discussão, issue ou pull request com contexto claro sobre a proposta.

Antes de abrir um PR, recomendamos:

  1. Garantir que o código compila com rebar3 compile.
  2. Rodar os testes com rebar3 eunit --cover.
  3. Rodar os testes de propriedade com rebar3 proper -n 200 -c.
  4. Verificar a análise estática com rebar3 xref, rebar3 dialyzer e rebar3 edoc.

Não hesite em nos perguntar no GitHub Discussions caso haja qualquer dificuldade ou dúvida. Toda ajuda conta.

Vamos construir juntos!