CNPJ (alphanumeric)
data specs/data/cnpj.kmd
Validation + format rules for the Brazilian CNPJ company identifier, including the RFB Instrução Normativa 2.229/2024 ALPHANUMERIC CNPJ that begins issuance July 2026. Date-versioned: legacy 14-digit numeric CNPJs stay valid forever; new ones may carry letters in the first 12 positions. The two check digits stay numeric and use the same mod-11 over an ASCII-based character value. Any Koder surface validating, storing, or masking a CNPJ MUST follow this.
When this spec applies
Primary triggers
- Implement CNPJ validation in a Koder component
All triggers
- Validate or store a CNPJ
- Mask/format a CNPJ input field
- Support the new alphanumeric CNPJ (IN RFB 2.229/2024)
Specification body
Spec — CNPJ (alphanumeric)
Status: v0.1.0 — Draft. Promoted from the gov.br (DS Gov) parity scan (meta/docs/stack #098). Source: Receita Federal IN RFB nº 2.229/2024 (alphanumeric CNPJ, issuance from 2026-07).
R1 — Structure (date-versioned)
A CNPJ has 14 positions, displayed NN.NNN.NNN/NNNN-DD:
| Positions | Era ≤ 2026-06 (legacy) | Era ≥ 2026-07 (alphanumeric) |
|---|---|---|
| 1–12 (base + branch) | digits 0-9 | alphanumeric 0-9 and A-Z (uppercase) |
13–14 (check digits DD) | digits 0-9 | digits 0-9 (always numeric) |
Both eras coexist permanently: legacy all-numeric CNPJs remain valid and are a strict subset of the alphanumeric rules. Never reject an existing numeric CNPJ because it lacks letters, and never reject a well-formed alphanumeric CNPJ because it has letters.
R2 — Character value (for the check digits)
Each of the first 12 positions contributes a numeric value:
value(c) = ASCII(c) − 48
So '0'..'9' → 0..9 and 'A'..'Z' → 17..42. This is the official RFB
rule and makes the legacy numeric algorithm a special case.
R3 — Check-digit algorithm (mod 11)
Identical to the legacy CNPJ algorithm, applied over value(c):
- DV1: weight positions 1–12 by
[5,4,3,2,9,8,7,6,5,4,3,2]; sumvalue(c)·weight;r = sum mod 11;DV1 = r < 2 ? 0 : 11 − r. - DV2: weight positions 1–13 (the 13th being DV1) by
[6,5,4,3,2,9,8,7,6,5,4,3,2]; samer/DV rule.
Positions 13–14 must equal DV1/DV2. Uppercase before computing
(lowercase letters are normalized to uppercase, R4).
R4 — Normalization
- Strip the mask punctuation (
.,/,-) before validating/storing. - Uppercase any letters; reject characters outside
[0-9A-Z]after stripping. - Persist the canonical 14-character unmasked value (per
specs/data/masks.kmdR "persist without mask"); apply the mask only for display/input.
R5 — Input & masking
- The
cnpjfield type accepts alphanumeric input in the alphanumeric era:inputmodeis notnumeric(letters are allowed) — use a text input with an uppercasing + alnum filter; the visual maskNN.NNN.NNN/NNNN-DDstill applies (seespecs/data/masks.kmd, whose numeric-only assumption forcnpjis superseded here for the alphanumeric era). - Reject-on-blur with a specific message
(
specs/errors/user-facing-messages.kmd): "Invalid CNPJ".
R6 — Accessibility & i18n
- The CNPJ format is BR-fixed and locale-independent (the mask never
changes with UI locale), per
specs/data/masks.kmd. - Error/label strings localize per
specs/i18n/contract.kmd; the format itself does not. - The field announces its expected format up front, not only on error.
Não-escopo
- CPF and CEP (their own rules; CPF stays 11 numeric digits).
- The numeric presentation mask mechanics (
specs/data/masks.kmd). - Server-side existence/active-status lookup at Receita Federal (a product integration, not a format rule).
References
specs/data/validation.kmdspecs/data/masks.kmdspecs/data/field-types.kmdspecs/i18n/contract.kmd