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

Validar, gerar e formatar CPF em Java

Classe utilitária em Java 17 para validar, gerar e formatar CPF com o módulo 11, testes com JUnit 5 @ParameterizedTest e chamada à API com HttpClient.

Roberto GuerraPublicado em 05 de outubro de 2026Editar no GitHub

Em Java, o lugar natural para validar CPF é uma classe utilitária final, sem estado, que pode ser chamada de um controller Spring, de um validador do Bean Validation ou de um teste. O código abaixo usa apenas o JDK e compila em Java 17. A lógica é idêntica à das ferramentas do site; o guia do algoritmo do módulo 11 mostra a conta completa.

Validar CPF em Java

Cpf.java
import java.security.SecureRandom;
import java.util.regex.Pattern;

public final class Cpf {
  private static final Pattern SEPARADORES = Pattern.compile("[.\\-\\s]");
  private static final Pattern ONZE_DIGITOS = Pattern.compile("[0-9]{11}");
  private static final SecureRandom RANDOM = new SecureRandom();

  private Cpf() {}

  static int calcularDigito(String digitos, int pesoInicial) {
      int soma = 0;
      for (int i = 0; i < digitos.length(); i++) {
          soma += (digitos.charAt(i) - '0') * (pesoInicial - i);
      }
      int resto = soma % 11;
      return resto < 2 ? 0 : 11 - resto;
  }

  public static boolean validar(String valor) {
      if (valor == null) return false;
      String cpf = SEPARADORES.matcher(valor).replaceAll("");
      if (!ONZE_DIGITOS.matcher(cpf).matches()) return false;
      if (cpf.chars().allMatch(c -> c == cpf.charAt(0))) return false;
      int dv1 = calcularDigito(cpf.substring(0, 9), 10);
      int dv2 = calcularDigito(cpf.substring(0, 10), 11);
      return cpf.charAt(9) - '0' == dv1 && cpf.charAt(10) - '0' == dv2;
  }
}

Pontos que merecem atenção:

  • Pattern pré-compilado. String.replaceAll e String.matches recompilam a expressão a cada chamada. Em validar, que roda a cada requisição, vale manter os padrões em constantes.
  • [0-9]{11} com matches() exige que a string inteira seja de dígitos ASCII. Letras ou símbolos que sobraram da limpeza derrubam a validação.
  • charAt(i) - '0' converte o caractere em número sem criar objetos, o que é mais barato que Integer.parseInt em um laço.
  • A checagem de repetidos vem antes da conta. 111.111.111-11 passa no módulo 11, mas sequências assim não são consideradas válidas.

Com 529.982.247-25, a primeira soma é 295 (resto 9, dígito 2) e a segunda é 347 (resto 6, dígito 5), e validar devolve true. Com 529.982.247-26, o último caractere vale 6, o dígito calculado é 5, e o resultado é false.

Para usar com Bean Validation, crie uma anotação @CpfValido com um ConstraintValidator<CpfValido, String> cujo isValid chama Cpf.validar. Lembre que null aqui é inválido; se o campo for opcional, trate null como válido no validador e use @NotNull quando ele for obrigatório.

Gerar CPF válido em Java

Os métodos a seguir ficam dentro da mesma classe Cpf. SecureRandom evita sequências previsíveis.

Cpf.java
    public static String gerar(boolean formatado) {
      String base;
      do {
          StringBuilder sb = new StringBuilder(9);
          for (int i = 0; i < 9; i++) sb.append(RANDOM.nextInt(10));
          base = sb.toString();
      } while (base.matches("(\\d)\\1{8}"));
      int dv1 = calcularDigito(base, 10);
      int dv2 = calcularDigito(base + dv1, 11);
      String cpf = base + dv1 + dv2;
      return formatado ? formatar(cpf) : cpf;
  }

O número gerado é válido pelo algoritmo e pode coincidir com um CPF real por acaso; use-o em testes e massas de dados fictícias. O guia de massa de teste e LGPD traz boas práticas para isso.

Formatar e limpar CPF em Java

Cpf.java
    public static String limpar(String valor) {
      return valor == null ? "" : valor.replaceAll("[^0-9]", "");
  }

  public static String formatar(String valor) {
      String d = limpar(valor);
      if (d.length() != 11) {
          throw new IllegalArgumentException("CPF precisa de 11 dígitos, recebeu " + d.length());
      }
      return d.substring(0, 3) + "." + d.substring(3, 6) + "." + d.substring(6, 9) + "-" + d.substring(9);
  }

Cpf.formatar("52998224725") devolve "529.982.247-25" e Cpf.limpar("529.982.247-25") devolve "52998224725". Persista a versão limpa em uma coluna CHAR(11), nunca em BIGINT, que descarta o zero à esquerda; o guia sobre validar CPF no banco de dados cobre o lado do PostgreSQL e do MySQL.

Testes

Com JUnit 5, @ParameterizedTest e @CsvSource rodam o mesmo método para cada linha. O JUnit converte "true" e "false" em boolean automaticamente e ignora os espaços depois da vírgula.

CpfTest.java
import static org.junit.jupiter.api.Assertions.assertEquals;

import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;

class CpfTest {
  @ParameterizedTest(name = "{0} -> {1}")
  @CsvSource({
      "529.982.247-25, true",
      "111.111.111-11, false",
      "529.982.247-26, false",
  })
  void validaOsTresCasos(String cpf, boolean esperado) {
      assertEquals(esperado, Cpf.validar(cpf));
  }
}

O artefato junit-jupiter-params precisa estar no classpath de teste; no Spring Boot ele já vem com spring-boot-starter-test. Para ampliar a tabela, veja os erros comuns ao validar CPF.

Usar a API em vez de reimplementar

A API do cpf.dev.br valida e gera CPFs por HTTP, sem chave, com limite de 60 requisições por minuto por IP. O HttpClient do Java 11 em diante resolve sem dependências.

ApiCpf.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 ApiCpf {
  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/cpf/validar/529.982.247-25")).GET().build();
      HttpResponse<String> resp = http.send(req, HttpResponse.BodyHandlers.ofString());
      System.out.println(resp.body());
      // {"valido":true,"cpf":"52998224725","formatado":"529.982.247-25","uf":["ES","RJ"]}

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

Para transformar o JSON em objeto, use Jackson ou Gson com um record de quatro campos. Em validação de entrada, a classe local é mais rápida e não depende de rede. Para conferir um número à mão, use o validador de CPF.

Leia também