Pular para o conteúdo
ValidadorCNPJ Gerar CNPJ

Java · código pronto

Validar CNPJ alfanumérico em Java

Validador de CNPJ alfanumérico em Java 17, com anotação Bean Validation pronta para Spring Boot.

Testar um CNPJ agora Gerar massa de teste

Classe utilitária em Java 17 sem dependências, mais a anotação @Cnpj de Bean Validation (Jakarta) para usar direto nos DTOs do Spring Boot.

O algoritmo é sempre o mesmo: cada caractere vale o seu código ASCII menos 48 (0=0 … 9=9, A=17 … Z=42), os pesos vão de 2 a 9 da direita para a esquerda, soma-se tudo, divide-se por 11 e o dígito é 0 quando o resto é menor que 2, ou 11 menos o resto. Ver a conta detalhada.

Código completo

validação de CNPJ alfanumérico em Java
package br.com.exemplo.cnpj;

import java.util.Locale;
import java.util.regex.Pattern;

public final class Cnpj {

    private static final Pattern NAO_ALFANUMERICO = Pattern.compile("[^0-9A-Z]");
    private static final Pattern FORMATO = Pattern.compile("[0-9A-Z]{12}\\d{2}");
    private static final Pattern REPETIDO = Pattern.compile("(.)\\1{13}");

    private Cnpj() {
    }

    /** Remove máscara e normaliza para maiúsculas. */
    public static String limpar(String valor) {
        if (valor == null) {
            return "";
        }
        return NAO_ALFANUMERICO.matcher(valor.toUpperCase(Locale.ROOT)).replaceAll("");
    }

    /** Calcula um dígito do módulo 11 (valor do caractere = ASCII - 48). */
    private static int digito(String sequencia) {
        int soma = 0;
        int tamanho = sequencia.length();

        for (int i = 0; i < tamanho; i++) {
            int valor = sequencia.charAt(i) - 48;
            int peso = ((tamanho - 1 - i) % 8) + 2;
            soma += valor * peso;
        }

        int resto = soma % 11;

        return resto < 2 ? 0 : 11 - resto;
    }

    /** Devolve os dois dígitos verificadores da base de 12 caracteres. */
    public static String calcularDv(String base) {
        int primeiro = digito(base);
        int segundo = digito(base + primeiro);
        return String.valueOf(primeiro) + segundo;
    }

    /** Valida CNPJ numérico ou alfanumérico, com ou sem máscara. */
    public static boolean valido(String valor) {
        String cnpj = limpar(valor);

        if (!FORMATO.matcher(cnpj).matches() || REPETIDO.matcher(cnpj).matches()) {
            return false;
        }

        return calcularDv(cnpj.substring(0, 12)).equals(cnpj.substring(12));
    }

    /** Aplica a máscara 00.000.000/0000-00. */
    public static String formatar(String valor) {
        String cnpj = limpar(valor);

        if (cnpj.length() != 14) {
            return cnpj;
        }

        return cnpj.substring(0, 2) + "." + cnpj.substring(2, 5) + "."
                + cnpj.substring(5, 8) + "/" + cnpj.substring(8, 12)
                + "-" + cnpj.substring(12);
    }
}

Testes e integração com o framework

Bean Validation + JUnit 5
// Anotação reutilizável nos DTOs
@Documented
@Constraint(validatedBy = CnpjValidator.class)
@Target({ ElementType.FIELD, ElementType.PARAMETER })
@Retention(RetentionPolicy.RUNTIME)
public @interface CnpjValido {
    String message() default "CNPJ inválido";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

public class CnpjValidator implements ConstraintValidator<CnpjValido, String> {
    @Override
    public boolean isValid(String valor, ConstraintValidatorContext contexto) {
        return valor == null || valor.isBlank() || Cnpj.valido(valor);
    }
}

// Teste
class CnpjTest {

    @Test
    void validaExemploOficial() {
        assertEquals("35", Cnpj.calcularDv("12ABC34501DE"));
        assertTrue(Cnpj.valido("12.ABC.345/01DE-35"));
        assertTrue(Cnpj.valido("12abc34501de35"));
    }

    @Test
    void mantemCompatibilidadeComNumerico() {
        assertTrue(Cnpj.valido("11.222.333/0001-81"));
        assertFalse(Cnpj.valido("11.222.333/0001-82"));
    }
}

Detalhes que costumam quebrar em Java

Casos de teste recomendados

Cubra pelo menos estes cenários — eles pegam praticamente todos os erros de implementação:

EntradaEsperadoO que testa
12.ABC.345/01DE-35válidoexemplo oficial, com máscara
12abc34501de35válidonormalização para maiúsculas
11.222.333/0001-81válidocompatibilidade com o formato numérico
11.222.333/0001-82inválidodígito verificador errado
12ABC34501DEABinválidoletra no dígito verificador
12ABC34501DE3inválidotamanho incorreto
00.000.000/0000-00inválidosequência repetida
"" / nullinválidoentrada vazia sem exceção

Precisa de mais massa de teste? O gerador produz até 500 CNPJs alfanuméricos válidos de uma vez, com opção de baixar em .txt.

O mesmo algoritmo em outras linguagens

Dúvidas sobre CNPJ alfanumérico em Java

Preciso de alguma biblioteca para validar CNPJ alfanumérico em Java?

Não. O código desta página usa apenas a biblioteca padrão de Java — são cerca de 30 linhas. Bibliotecas de terceiros só valem a pena se você também precisa de formatação, geração e validação de outros documentos; e, nesse caso, confira se a versão instalada já suporta o formato alfanumérico.

A mesma função valida CNPJ numérico e alfanumérico em Java?

Sim. Como o valor de cada dígito é o próprio dígito (código ASCII menos 48), o algoritmo alfanumérico produz o mesmo resultado do antigo para números. Você não precisa manter duas funções nem ramificar por formato.

Como testar se a implementação está certa?

Use o exemplo oficial da Receita Federal: a base 12ABC34501DE tem dígitos verificadores 35, formando 12.ABC.345/01DE-35. Confira também um CNPJ numérico conhecido, como 11.222.333/0001-81, e um inválido, como 11.222.333/0001-82.

O que mais precisa mudar além da função de validação?

O tipo da coluna no banco (de numérico para VARCHAR(14)), qualquer conversão para inteiro no caminho do dado, as máscaras de entrada e as regex espalhadas por validações e relatórios. A função de validação costuma ser a parte mais fácil da migração.