Ferramentas gratuitas para desenvolvedores. Nenhum dado real de pessoas é consultado ou armazenado.Como funciona o algoritmo do CPF →
Java

Validar, gerar e formatar CNPJ em Java

Classe utilitária em Java 17 para validar, gerar e formatar CNPJ numérico e alfanumérico, testes com JUnit 5 @ParameterizedTest e chamada à API.

Roberto GuerraPublicado em 05 de outubro de 2026Editar no GitHub

Em sistemas Java, o CNPJ costuma estar espalhado em entidades JPA, validadores do Bean Validation e integrações com outros sistemas. Com o CNPJ alfanumérico, todo código que faz Long.parseLong ou Character.getNumericValue no CNPJ passa a quebrar ou, pior, a calcular errado. A classe abaixo usa apenas o JDK, compila em Java 17 e trata os dois formatos com a mesma conta: cada caractere vale c - 48, ou seja, o código ASCII menos 48. Dígitos continuam valendo 0 a 9; A vale 17 e Z vale 42. O guia CNPJ alfanumérico: o que muda no seu sistema lista os outros pontos de atenção.

Validar CNPJ em Java (numérico e alfanumérico)

Cnpj.java
import java.security.SecureRandom;
import java.util.Locale;
import java.util.regex.Pattern;

public final class Cnpj {
  private static final int[] PESOS_1 = {5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2};
  private static final int[] PESOS_2 = {6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2};
  private static final Pattern SEPARADORES = Pattern.compile("[./\\-\\s]");
  private static final Pattern FORMATO = Pattern.compile("[A-Z0-9]{12}[0-9]{2}");
  private static final SecureRandom RANDOM = new SecureRandom();

  private Cnpj() {}

  static int calcularDigito(String base, int[] pesos) {
      int soma = 0;
      for (int i = 0; i < base.length(); i++) {
          soma += (base.charAt(i) - 48) * pesos[i];
      }
      int resto = soma % 11;
      return resto < 2 ? 0 : 11 - resto;
  }

  public static boolean validar(String valor) {
      if (valor == null) return false;
      String cnpj = SEPARADORES.matcher(valor.toUpperCase(Locale.ROOT)).replaceAll("");
      if (!FORMATO.matcher(cnpj).matches()) return false;
      String base = cnpj.substring(0, 12);
      if (base.chars().allMatch(c -> c == base.charAt(0))) return false;
      int dv1 = calcularDigito(base, PESOS_1);
      int dv2 = calcularDigito(base + dv1, PESOS_2);
      return cnpj.substring(12).equals("" + dv1 + dv2);
  }

Detalhes que fazem diferença:

  • toUpperCase(Locale.ROOT) evita surpresas com a localidade da JVM. Em turco, por exemplo, "i".toUpperCase() não vira "I".
  • matches() exige que a string inteira siga o padrão: 12 caracteres de A-Z0-9 e dois dígitos no fim.
  • allMatch recusa bases com os 12 primeiros caracteres iguais, como 00.000.000/0000-00, que fecham a conta, mas não são válidas.
  • base.charAt(i) - 48 faz aritmética direta com o char. Não use Character.getNumericValue: para letras ele devolve 10 a 35, e o resultado fica errado.

Com 11.222.333/0001-81, a primeira soma é 102, o resto é 3 e o dígito é 8; a segunda soma é 120, o resto é 10 e o dígito é 1. Com 12.ABC.345/01DE-35, as somas são 459 e 424, os restos 8 e 6, e os dígitos 3 e 5. Para usar com Bean Validation, crie uma anotação @CnpjValido cujo ConstraintValidator chame Cnpj.validar.

Gerar CNPJ válido em Java

Cnpj.java
    private static final String DIGITOS = "0123456789";
  private static final String ALFANUMERICOS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";

  public static String gerar(boolean alfanumerico, boolean formatado) {
      String alfabeto = alfanumerico ? ALFANUMERICOS : DIGITOS;
      String base;
      do {
          StringBuilder sb = new StringBuilder(12);
          for (int i = 0; i < 12; i++) {
              sb.append(alfabeto.charAt(RANDOM.nextInt(alfabeto.length())));
          }
          base = sb.toString();
      } while (base.matches("(.)\\1{11}"));
      int dv1 = calcularDigito(base, PESOS_1);
      int dv2 = calcularDigito(base + dv1, PESOS_2);
      String cnpj = base + dv1 + dv2;
      return formatado ? formatar(cnpj) : cnpj;
  }

SecureRandom evita sequências previsíveis. O CNPJ gerado passa na validação, mas pode coincidir com um CNPJ real por acaso; use-o só em testes e dados fictícios. Para gerar filiais de uma mesma raiz, mantenha os 8 primeiros caracteres e varie a ordem, como mostra o guia da estrutura do CNPJ. O gerador de CNPJ em lote faz isso sem código.

Formatar e limpar CNPJ em Java

Cnpj.java
    public static String limpar(String valor) {
      return valor == null ? "" : valor.toUpperCase(Locale.ROOT).replaceAll("[^A-Z0-9]", "");
  }

  public static String formatar(String valor) {
      String c = limpar(valor);
      if (c.length() != 14) {
          throw new IllegalArgumentException("CNPJ precisa de 14 caracteres");
      }
      return c.substring(0, 2) + "." + c.substring(2, 5) + "." + c.substring(5, 8)
              + "/" + c.substring(8, 12) + "-" + c.substring(12);
  }
}

Cnpj.formatar("12abc34501de35") devolve "12.ABC.345/01DE-35", e aplicar o método de novo no resultado não muda nada. Na entidade JPA, mapeie o CNPJ como String com @Column(length = 14) e grave a versão limpa; um campo Long não comporta letras. Para validar o formato com máscara em uma anotação @Pattern, veja o guia de regex de CNPJ.

Testes

Com JUnit 5, @ParameterizedTest e @CsvSource geram um teste por linha. O artefato junit-jupiter-params precisa estar no classpath.

CnpjTest.java
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.junit.jupiter.params.provider.ValueSource;

class CnpjTest {
  @ParameterizedTest
  @CsvSource({
      "11.222.333/0001-81, true",
      "12.ABC.345/01DE-35, true",
      "11.222.333/0001-82, false",
      "00.000.000/0000-00, false",
  })
  void validar(String cnpj, boolean esperado) {
      assertEquals(esperado, Cnpj.validar(cnpj));
  }

  @ParameterizedTest
  @ValueSource(booleans = {false, true})
  void geradosSaoValidos(boolean alfanumerico) {
      for (int i = 0; i < 1000; i++) {
          assertTrue(Cnpj.validar(Cnpj.gerar(alfanumerico, false)));
      }
  }

  @Test
  void formatarEhIdempotente() {
      assertEquals("12.ABC.345/01DE-35", Cnpj.formatar(Cnpj.formatar("12abc34501de35")));
  }
}

Mais números para a tabela estão nos exemplos de CNPJ alfanumérico para teste.

Usar a API em vez de reimplementar

A API do cpf.dev.br valida e gera CNPJs por HTTP, sem chave, com limite de 60 requisições por minuto por IP. Envie o CNPJ sem máscara ou com a barra codificada como %2F. O HttpClient do JDK 11 em diante resolve sem dependências.

ApiCnpj.java
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;

public class ApiCnpj {
  public static void main(String[] args) throws Exception {
      HttpClient http = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(5)).build();
      HttpRequest req = HttpRequest.newBuilder(
              URI.create("https://www.cpf.dev.br/api/v1/cnpj/validar/12ABC34501DE35")).build();
      String json = http.send(req, HttpResponse.BodyHandlers.ofString()).body();
      System.out.println(json);
      // {"valido":true,"cnpj":"12ABC34501DE35","formatado":"12.ABC.345/01DE-35",
      //  "formato":"alfanumerico","raiz":"12ABC345","ordem":"01DE","matriz":false}

      HttpRequest lote = HttpRequest.newBuilder(URI.create(
              "https://www.cpf.dev.br/api/v1/cnpj/gerar?quantidade=5&formato=alfanumerico&formatado=true")).build();
      System.out.println(http.send(lote, HttpResponse.BodyHandlers.ofString()).body());
  }
}

Para ler o JSON em objetos, use a biblioteca que o projeto já tiver, como Jackson ou Gson. Em formulários, a classe local continua sendo a melhor opção. Para conferir um número à mão, use o validador de CNPJ.

Leia também