CNPJ

Cadastro Nacional da Pessoa Jurídica, the 14-character Brazilian company registration number. Alphanumeric since July 2026, with two numeric mod-11 check digits.

  • Parity matrix

Validate

Validates a CNPJ: 12 base characters and 2 modulus 11 check digits.

  • options.version: 1 (default) accepts numeric CNPJs only. 2 also accepts the alphanumeric CNPJ, case-insensitively. Any other value is read as 1.
  • A numeric CNPJ whose digits are all the same is rejected. The alphanumeric format has no reserved list.
  • Since July 2026 new CNPJs may be alphanumeric, which the default version: 1 rejects. Pass version: 2 to accept them.
  • The official character set of the alphanumeric CNPJ is the capital letters A to Z and the digits; the 2 check digits are always digits. A lower case letter is accepted only as input normalization, like a mask character: the value is upper-cased first.
  • The Ex1 of question 23 of the Receita Federal Q&A on the alphanumeric CNPJ, AA345678/0003-29, is a misprint: its check digits are 86, so it is rejected.

Pending decision

The reference (JS) ignores the formatting characters (., -, /) and whitespace around and between groups. The other libraries accept digits only. See the open decision in docs/findings.md.

ParameterTypeRequired
cnpjstringyes
optionsIsValidCnpjOptionsno
options.version1 | 2no
returnsboolean

Check if a CNPJ is valid.

  • Options (IsValidCnpjOptions): version picks the accepted format: 1 (default) numeric only, 2 numeric and alphanumeric. Any other value is read as 1.
  • Since July 2026 new CNPJs may be alphanumeric, which the default version: 1 rejects: pass version: 2 to accept them.
  • A reserved number (all digits the same) is rejected under both versions; version 2 has no reserved list for letters.
  • The official character set of the alphanumeric CNPJ is the capital letters A to Z and the digits (the 2 check digits are always digits). A lower case letter is accepted only as input normalization, like a mask character: the input is upper-cased first.
  • The Ex1 of question 23 of the Receita Federal's Q&A on the alphanumeric CNPJ, AA345678/0003-29, is a misprint: its check digits are 86, so it is rejected.
import { isValidCnpj } from '@brazilian-utils/brazilian-utils';

isValidCnpj('15515147234255'); // false
isValidCnpj('q0slfmbd7vx439', { version: 2 }); // true (read as Q0SLFMBD7VX439)

Source: Instrução Normativa RFB nº 2.229/2024 (Anexo XV of IN RFB nº 2.119/2022, weights "da direita para esquerda" as corrected by the retificação in the DOU of 25/10/2024), Receita Federal, Manual do DV do CNPJ, CNPJ alfanumérico.

Code: brazilian-utils/javascript
Try it with JavaScript isValidCnpj
The inputs start with the first shared case. Change one to see the new result.

Runs @brazilian-utils/brazilian-utils 2.5.0 in your browser.

Shared test cases (42) and the result in each library cnpj.isValid

Format

Formats a CNPJ as 00.000.000/0000-00.

  • options.pad first left-pads the value with zeros to 14 characters.
  • options.version: 1 (default) keeps digits only. 2 (alphanumeric CNPJ) keeps letters (upper-cased) and digits. Any other value is read as 1.
  • options.obfuscate (default false, read for truthiness like pad) hides the first 2 characters and the 2 check digits with *, after padding. This is a convention of the library, with no official source: no law or Receita Federal act sets a masking rule for the CNPJ, whose data are public. It follows the rule the Leis de Diretrizes Orçamentárias set for the CPF.
  • A number is read only when it is a safe non-negative integer. A negative, fractional, non-finite or unsafe number returns an empty string (2.4.0 read the digits of any number).
  • A value with no characters the version keeps (empty, or only symbols) returns an empty string even with options.pad. Until 2.4.0 pad returned the whole zero mask (00.000.000/0000-00).
  • The value is read up to 14 characters: characters past the 14th are dropped, also with options.pad.
  • Since July 2026 new CNPJs may be alphanumeric. The default version: 1 drops their letters, so pass version: 2 to keep them. A number loses its leading zeros: pass a string, or use options.pad, for a CNPJ that starts with 0.

Pending decision

The reference (JS) formats only the characters an incomplete value has. It returns an empty string for empty or invalid input. The other libraries return null. See the open decision in docs/findings.md.

ParameterTypeRequired
valuestring | numberyes
optionsFormatCnpjOptionsno
options.padbooleanno
options.version1 | 2no
options.obfuscatebooleanno
returnsstring

Format a CNPJ.

  • Options (FormatCnpjOptions): pad left-pads the value with zeros to 14 characters before masking (default false); version picks the format, 1 (default) numeric only, 2 alphanumeric; obfuscate hides the first 2 digits and the 2 check digits. An empty value, or one without digits, gives '' even with pad.
  • Version 2 keeps letters and digits, a lower case letter upper-cased first since the official set is A to Z; version 1 keeps digits only. Since July 2026 new CNPJs may be alphanumeric, so pass version: 2 to keep their letters.
  • obfuscate works in both versions and is applied after pad. It is a convention of this library, not an official rule: no law or Receita Federal act sets a masking rule for the CNPJ, whose data are public, the ANPD says "não há um padrão para o mascaramento", and the Banco Central's Pix rules show the CNPJ in full where they mask the CPF; it hides the first 2 characters and the 2 check digits, after the CPF rule.
import { formatCnpj } from '@brazilian-utils/brazilian-utils';

formatCnpj('24522200000174'); // 24.522.200/0001-74
formatCnpj('245222000174', { pad: true }); // 00.245.222/0001-74
formatCnpj('12OUT345000199', { version: 2 }); // 12.OUT.345/0001-99
formatCnpj('12345678000195', { obfuscate: true }); // **.345.678/0001-**
Code: brazilian-utils/javascript
Try it with JavaScript formatCnpj
The inputs start with the first shared case. Change one to see the new result.

Runs @brazilian-utils/brazilian-utils 2.5.0 in your browser.

Shared test cases (99) and the result in each library cnpj.format

Parse

Removes CNPJ formatting and returns the normalized value, capped at 14 characters.

  • options.version: 1 (default) keeps digits only. 2 keeps letters and digits, upper-cased. Any other value is read as 1.
  • A number is read only when it is a safe non-negative integer. A negative, fractional, non-finite or unsafe number returns an empty string (2.4.0 read the digits of any number).
  • Since July 2026 new CNPJs may be alphanumeric. The default version: 1 drops their letters, so pass version: 2 to keep them. A lower case letter is upper-cased first, since the official set is A to Z.
ParameterTypeRequired
valuestring | numberyes
optionsParseCnpjOptionsno
options.version1 | 2no
returnsstring

Remove CNPJ formatting, return a normalized value, and cap the result to 14 characters.

  • Options (ParseCnpjOptions): version picks the format: 1 (default) keeps digits only, 2 keeps letters and digits, a lower case letter upper-cased since the official set is A to Z (parseCnpj('12.abc.345/01de-35', { version: 2 }) returns '12ABC34501DE35'). Since July 2026 new CNPJs may be alphanumeric, so the default drops their letters: pass version: 2 to keep them.
import { parseCnpj } from '@brazilian-utils/brazilian-utils';

parseCnpj('24.522.200/0001-74'); // 24522200000174
parseCnpj('12.OUT.345/0001-99', { version: 2 }); // 12OUT345000199
Code: brazilian-utils/javascript
Try it with JavaScript parseCnpj
The inputs start with the first shared case. Change one to see the new result.

Runs @brazilian-utils/brazilian-utils 2.5.0 in your browser.

Shared test cases (25) and the result in each library cnpj.parse

Generate

Generates a valid random CNPJ, unformatted.

  • versionOrParams picks the version: 1 (default, numeric) or 2 (alphanumeric). It can also be an object { version, branch }, where branch sets the branch (número de ordem), an integer from 1 to 9999. The branch is random by default, and an invalid branch is ignored.
  • A branch given in branch is written as 4 digits in both versions (3 gives 0003). A random branch under version 2 can carry letters, like the root.
  • A random branch is never 0000: the establishments of a root are numbered from 0001, the headquarters (matriz). 2.4.0 could return 0000, about once in 10,000 numeric CNPJs.
  • Invalid branch values (0, above 9999, fractional, not a number) are ignored and a random branch is used. A number versionOrParams other than 2 (or a value that is neither 2 nor an object) generates a numeric CNPJ.
ParameterTypeRequired
versionOrParams1 | 2 | GenerateCnpjParamsno
returnsstring

Generate a valid random CNPJ.

  • The first argument is either the version, 1 (default) numeric or 2 alphanumeric, or a GenerateCnpjParams object with version plus branch.
  • branch is the "número de ordem" (filial) block, an integer from 1 to 9999 (random by default). An invalid branch is ignored. The block stays numeric in both versions.
  • A random ordem block is never 0000: the establishments of a root are numbered from 0001, the matriz, on, so that block is never assigned.
import { generateCnpj } from '@brazilian-utils/brazilian-utils';

generateCnpj();
generateCnpj(2); // alphanumeric CNPJ, e.g. 'Q0SLFMBD7VX439'
generateCnpj({ branch: 3 }); // ordem block '0003', e.g. '12345678000357'
generateCnpj({ version: 2, branch: 1 }); // alphanumeric CNPJ whose ordem block is '0001'
Code: brazilian-utils/javascript
Try it with JavaScript generateCnpj
The inputs start with the first shared case. Change one to see the new result.

Runs @brazilian-utils/brazilian-utils 2.5.0 in your browser.

Shared test cases (9) and the result in each library cnpj.generate

Decode

Reads the fields of a CNPJ: root, branch and check digits, and whether the branch is 0001. Returns null exactly when cnpj.isValid is false for the same arguments.

  • root is positions 1 to 8. branch is positions 9 to 12, the número de ordem of the establishment. checkDigits is positions 13 and 14. The name branch is the same as in cnpj.generate.
  • options.version works as in cnpj.isValid: 1 (default) reads numeric CNPJs only, 2 reads numeric and alphanumeric CNPJs, and any other value is read as 1. An alphanumeric CNPJ read under version 1 returns null.
  • The fields of an alphanumeric CNPJ come back in upper case.
  • isInitialHeadquarters is true when the branch is 0001. It marks the headquarters (matriz) only at the time the CNPJ was created: a filial can become the matriz without having the branch 0001 (question 25 of the Receita Federal Q&A on the alphanumeric CNPJ). Only the Receita Federal registry tells the current headquarters.
  • The result has no format field. Use cnpj.format for the mask.
  • Returns a new object on every call.
ParameterTypeRequired
valuestringyes
optionsGetCnpjInfoOptionsno
options.version1 | 2no
returnsCnpjInfo | null

Parse a CNPJ into the fields the number encodes. Accepts the same input forms as isValidCnpj and returns null whenever it would return false for the same arguments, so an alphanumeric CNPJ read under version 1 is null.

  • Options (GetCnpjInfoOptions): version is read the way isValidCnpj reads it, 1 (default) the numeric-only format, 2 both the numeric and the alphanumeric one.
  • Returns a CnpjInfo, the 14 positions as Anexo XV lays them out: 8 (root, the raiz that identifies the entity) + 4 (branch, the establishment, called número de ordem by the Receita Federal) + 2 (checkDigits, always numeric). branch is named after the branch parameter of generateCnpj, which fills the same four positions.
  • isInitialHeadquarters tells whether the branch is 0001, the one the Receita Federal gives the headquarters (matriz) when the root is registered. A filial can later become the headquarters while keeping its número de ordem, so only the Receita Federal registry tells the current headquarters.
  • The fields of an alphanumeric CNPJ are returned upper cased.
import { getCnpjInfo } from '@brazilian-utils/brazilian-utils';

getCnpjInfo('12.345.678/0001-95');
// {
//   root: '12345678',
//   branch: '0001',
//   checkDigits: '95',
//   isInitialHeadquarters: true
// }

getCnpjInfo('12.abc.345/01de-35', { version: 2 });
// {
//   root: '12ABC345',
//   branch: '01DE',
//   checkDigits: '35',
//   isInitialHeadquarters: false
// }

getCnpjInfo('12.ABC.345/01DE-35'); // null (alphanumeric, read under version 1)
getCnpjInfo('12.345.678/0001-90'); // null (bad check digits)

Source: Instrução Normativa RFB nº 2.229/2024, whose Anexo Único is the Anexo XV of IN RFB nº 2.119/2022 and lays the 14 positions out, Receita Federal Q&A on the alphanumeric CNPJ (questions 21, 23 and 25).

Code: brazilian-utils/javascript
Try it with JavaScript getCnpjInfo
The inputs start with the first shared case. Change one to see the new result.

Runs @brazilian-utils/brazilian-utils 2.5.0 in your browser.

Shared test cases (26) and the result in each library cnpj.getInfo

Guides

Specification

Summary

The CNPJ is a unique identification number that the Brazilian Federal Revenue Service issues. It registers companies, public agencies and other entities in Brazil. It has 14 characters: 8 for the root, 4 for the order of the establishment and 2 check digits. CNPJs issued before the alphanumeric format started contain only digits. Since July 2026, new registrations can contain uppercase letters and digits in the first 12 characters. The 2 check digits stay numeric only.

Validation rules

  1. The input must contain exactly 14 characters.

  2. The first 12 characters can contain digits from 0 to 9 and letters from A to Z. With version: 2, validation reads lowercase letters as uppercase.

  3. The last 2 characters are the check digits and must be numeric.

  4. The check digits must come from the modulo 11 algorithm.

  5. To calculate the check digits, convert the first 12 characters into numeric values. Use the decimal ASCII code of each character and subtract 48.

    Examples:

    • 0 → 48 - 48 = 0
    • 9 → 57 - 48 = 9
    • A → 65 - 48 = 17
    • B → 66 - 48 = 18
    • Z → 90 - 48 = 42

Algorithm

  1. Check that the input contains exactly 14 characters.
  2. Check that the first 12 characters are alphanumeric and the last 2 are numeric.
  3. Convert the alphanumeric characters to numeric values:
    • Digits keep their original values.
    • Letters become their decimal ASCII values minus 48.
  4. Calculate the first check digit (DV1):
    • For the first 12 characters, give weights from 2 to 9 from right to left. Start again at 2 after weight 9.
    • Multiply each value by its weight and add the results.
    • Calculate the remainder of the sum divided by 11.
    • If the remainder is 0 or 1, DV1 is 0. If not, DV1 is 11 - remainder.
  5. Calculate the second check digit (DV2):
    • Add DV1 to the end of the sequence. For these 13 characters, give weights from 2 to 9 from right to left.
    • Multiply each value by its weight and add the results.
    • Calculate the remainder of the sum divided by 11.
    • If the remainder is 0 or 1, DV2 is 0. If not, DV2 is 11 - remainder.
  6. Compare the calculated check digits with the last two characters of the CNPJ.

Fields of the number

IN RFB nº 2.229/2024 (Anexo XV of IN RFB nº 2.119/2022) lays the 14 positions out as:

PositionsFieldgetCnpjInfo key
1 to 8root (raiz), shared by every establishment of the entityroot
9 to 12número de ordem of the establishmentbranch
13 and 14check digits, always numericcheckDigits
  • getCnpjInfo(value, { version }) returns these fields and isInitialHeadquarters. It returns null exactly when isValidCnpj(value, { version }) is false, so an alphanumeric CNPJ read under version 1 gives null. The fields of an alphanumeric CNPJ come back in upper case. The result has no format field.
  • isInitialHeadquarters is true when the branch is 0001. The Receita Federal gives 0001 to the headquarters (matriz) when the root is registered. A filial can later become the matriz without having the branch 0001 (question 25 of the Receita Federal Q&A on the alphanumeric CNPJ), so the flag only says what the number said at creation.
  • generateCnpj({ branch }) uses the same name. A random branch is never 0000, since establishments are numbered from 0001. 2.4.0 could return 0000 (about once in 10,000 numeric CNPJs).

Examples:

  • getCnpjInfo("12.345.678/0001-95") returns { root: "12345678", branch: "0001", checkDigits: "95", isInitialHeadquarters: true }.
  • getCnpjInfo("12.abc.345/01de-35", { version: 2 }) returns { root: "12ABC345", branch: "01DE", checkDigits: "35", isInitialHeadquarters: false }.
  • getCnpjInfo("12.ABC.345/01DE-35") returns null (alphanumeric, read under version 1).

Masking and numbers

  • formatCnpj(value, { obfuscate: true }) hides the first 2 characters and the 2 check digits (**.345.678/0001-**). This is a convention of the library, with no official source: no law or Receita Federal act sets a masking rule for the CNPJ, whose data are public. It follows the rule the Leis de Diretrizes Orçamentárias set for the CPF.
  • formatCnpj and parseCnpj also take a number. It is read only when it is a non-negative safe integer. A negative, fractional, non-finite or unsafe number returns an empty string. 2.4.0 read the digits of any number.

Regex

  • Unformatted CNPJ: ^[A-Z0-9]{12}[0-9]{2}$
  • Formatted CNPJ: ^[A-Z0-9]{2}\.[A-Z0-9]{3}\.[A-Z0-9]{3}/[A-Z0-9]{4}-[0-9]{2}$

Examples

  • Valid: 03560714000142 (valid numeric CNPJ)
  • Valid: 9359QAG9000184 (valid alphanumeric CNPJ)
  • 03.560.714/0001-42: pending decision. The reference (JS) accepts it, the other libraries do not.
  • Invalid: 00111222000133 (invalid check digits)
  • Invalid: 12ABC34501DE3X (the check digits must be numeric)
  • Invalid: 12ABC34501DE3 (must contain exactly 14 characters)
  • Invalid: 12ABC34501DE345 (must contain exactly 14 characters)

Official sources

See also CPF, State registration (IE), Legal nature

Last updated on

On this page