Utilities for the Brazilian CNPJ (Cadastro Nacional da Pessoa Jurídica).
A CNPJ is a 14-character company identifier: an 8-character root, a
4-character branch number (usually 0001) and 2 numeric check
digits. It is commonly displayed as "XX.XXX.XXX/XXXX-XX". Since
the 2026 Receita Federal change the first 12 characters may be
alphanumeric (digits and uppercase letters); the check digits are
always numeric.
cnpj() = <<_:112>>
A raw CNPJ: 14 characters, digits or uppercase letters with numeric
check digits, e.g. <<"03560714000142">>.
formatted_cnpj() = <<_:144>>
A display-formatted CNPJ, e.g. <<"03.560.714/0001-42">>.
| format/1 | Formats a valid CNPJ for display, adding the standard visual
aid symbols: <<"XX.XXX.XXX/XXXX-XX">>. |
| generate/0 | Generates a random valid CNPJ with branch number 0001. |
| generate/1 | Generates a random valid CNPJ with the given branch number. |
| generate/2 | Generates a random valid CNPJ, optionally alphanumeric. |
| is_valid/1 | Returns whether the given term is a valid CNPJ: a 14-character binary whose first 12 characters are digits or uppercase letters, whose last 2 characters are digits, which is not a sequence of one repeated character, and whose two check digits match the ones computed from its 12-character base. |
| remove_symbols/1 | Removes the formatting symbols ., / and - from a CNPJ
string. |
format(Cnpj::binary()) -> {ok, formatted_cnpj()} | {error, invalid}
Formats a valid CNPJ for display, adding the standard visual
aid symbols: <<"XX.XXX.XXX/XXXX-XX">>.
The input must be a raw, symbols-free CNPJ accepted by
is_valid/1 — numeric or alphanumeric; anything else yields
{error, invalid}.
1> brutils_cnpj:format(<<"03560714000142">>).
{ok,<<"03.560.714/0001-42">>}
2> brutils_cnpj:format(<<"00111222000133">>).
{error,invalid}
generate() -> cnpj()
Generates a random valid CNPJ with branch number 0001.
Equivalent to generate(1).
1> brutils_cnpj:generate(). <<"05864803000108">>
generate(Branch::non_neg_integer() | binary()) -> cnpj()
Generates a random valid CNPJ with the given branch number.
The branch may be a non-negative integer or a digits-only binary. It is normalized to 4 digits: reduced modulo 10000, bumped to 1 when the reduction yields 0, and zero-padded. A negative integer or a binary containing anything but ASCII digits is out of contract and raises.
1> brutils_cnpj:generate(42). <<"38082273004273">> 2> brutils_cnpj:generate(<<"12">>). <<"12695023001208">>
generate(Branch::non_neg_integer() | binary(), Alphanumeric::boolean()) -> cnpj()
Generates a random valid CNPJ, optionally alphanumeric.
With Alphanumeric = false this is exactly generate/1.
With Alphanumeric = true the 8-character root is drawn from
digits and uppercase letters (digits three times as likely), and
the branch is normalized as text: truncated to its first 4
characters when longer, left-padded with 0 when shorter, and
replaced by 0001 when it is 0000 or contains anything but
digits and uppercase letters — alphanumeric mode repairs invalid
branches instead of raising.
1> brutils_cnpj:generate(<<"AB12">>, true). <<"2P9Q0746AB1220">> 2> brutils_cnpj:generate(<<"ab12">>, true). <<"RS7646P1000114">>
is_valid(Cnpj::term()) -> boolean()
Returns whether the given term is a valid CNPJ: a 14-character binary whose first 12 characters are digits or uppercase letters, whose last 2 characters are digits, which is not a sequence of one repeated character, and whose two check digits match the ones computed from its 12-character base.
Only the format is verified — the CNPJ is not checked for
existence. Lowercase letters are always invalid — they are never
case-folded. Formatting symbols are not stripped, so a formatted
CNPJ such as <<"03.560.714/0001-42">> is invalid; clean it with
remove_symbols/1 first. The function is total: any
non-binary term returns false rather than raising.
1> brutils_cnpj:is_valid(<<"03560714000142">>). true 2> brutils_cnpj:is_valid(<<"00111222000133">>). false
remove_symbols(Cnpj::binary()) -> binary()
Removes the formatting symbols ., / and - from a CNPJ
string.
Only those three characters are removed; any other character (letters, spaces, ...) is kept unchanged. This is a pure character filter: it does not validate the input.
1> brutils_cnpj:remove_symbols(<<"03.560.714/0001-42">>). <<"03560714000142">> 2> brutils_cnpj:remove_symbols(<<"a-b c!">>). <<"ab c!">>
Generated by EDoc