Gerar CPF em Go: Função com Testes go test
Quando o gerador de CPF online não basta e você precisa produzir CPFs válidos dentro de um binário Go, a solução é implementar o algoritmo de módulo 11 no próprio código. A função abaixo produz CPFs sintaticamente válidos, ideais para testes automatizados e benchmarks.
Código
package cpf
import (
"fmt"
"math/rand"
"regexp"
)
// GerarCPF gera um CPF válido com 11 dígitos numéricos.
func GerarCPF() string {
digits := make([]int, 11)
// Gera 9 dígitos aleatórios
for i := 0; i < 9; i++ {
digits[i] = rand.Intn(10)
}
// Primeiro dígito verificador
soma := 0
for i := 0; i < 9; i++ {
soma += digits[i] * (10 - i)
}
resto := soma % 11
if resto < 2 {
digits[9] = 0
} else {
digits[9] = 11 - resto
}
// Segundo dígito verificador
soma = 0
for i := 0; i < 10; i++ {
soma += digits[i] * (11 - i)
}
resto = soma % 11
if resto < 2 {
digits[10] = 0
} else {
digits[10] = 11 - resto
}
return fmt.Sprintf("%d%d%d%d%d%d%d%d%d%d%d",
digits[0], digits[1], digits[2], digits[3], digits[4],
digits[5], digits[6], digits[7], digits[8], digits[9], digits[10])
}
// ValidarCPF verifica se um CPF (somente dígitos) é válido.
func ValidarCPF(cpf string) bool {
re := regexp.MustCompile(`\D`)
cpf = re.ReplaceAllString(cpf, "")
if len(cpf) != 11 {
return false
}
// Rejeita CPFs com todos os dígitos iguais
allSame := true
for i := 1; i < 11; i++ {
if cpf[i] != cpf[0] {
allSame = false
break
}
}
if allSame {
return false
}
digits := make([]int, 11)
for i, c := range cpf {
digits[i] = int(c - '0')
}
// Verifica primeiro dígito
soma := 0
for i := 0; i < 9; i++ {
soma += digits[i] * (10 - i)
}
resto := soma % 11
esperado := 0
if resto >= 2 {
esperado = 11 - resto
}
if digits[9] != esperado {
return false
}
// Verifica segundo dígito
soma = 0
for i := 0; i < 10; i++ {
soma += digits[i] * (11 - i)
}
resto = soma % 11
esperado = 0
if resto >= 2 {
esperado = 11 - resto
}
if digits[10] != esperado {
return false
}
return true
}Análise do código
A função GerarCPF começa gerando nove dígitos aleatórios com rand.Intn(10), que retorna um inteiro entre 0 e 9 inclusive. Esses nove dígitos formam a base numérica do CPF, representando informações como a região fiscal de origem.
O cálculo dos dígitos verificadores segue rigorosamente o algoritmo módulo 11. Para o primeiro dígito, multiplica-se cada um dos nove dígitos por pesos decrescentes de 10 a 2, soma-se os resultados e aplica-se o módulo 11. Se o resto for menor que 2, o dígito é 0; caso contrário, subtrai-se o resto de 11. O segundo dígito repete o processo com os dez dígitos já conhecidos e pesos de 11 a 2.
A função ValidarCPF realiza o caminho inverso: remove caracteres não numéricos com uma expressão regular, verifica o comprimento de 11 dígitos, rejeita sequências com todos os dígitos iguais (como 00000000000) e recalcula ambos os dígitos verificadores para comparar com os informados. Essa função é essencial para confirmar que o gerador produz CPFs corretos.
Uso
package main
import (
"fmt"
"seu-modulo/cpf"
)
func main() {
novoCpf := cpf.GerarCPF()
fmt.Println("CPF gerado:", novoCpf)
fmt.Println("Válido:", cpf.ValidarCPF(novoCpf))
}Testes
package cpf_test
import (
"testing"
"seu-modulo/cpf"
)
func TestGerarCPFTem11Digitos(t *testing.T) {
resultado := cpf.GerarCPF()
if len(resultado) != 11 {
t.Errorf("esperava 11 dígitos, obteve %d: %s", len(resultado), resultado)
}
}
func TestGerarCPFEhValido(t *testing.T) {
for i := 0; i < 100; i++ {
resultado := cpf.GerarCPF()
if !cpf.ValidarCPF(resultado) {
t.Errorf("CPF gerado não passou na validação: %s", resultado)
}
}
}
func TestGerarCPFProduceDiferentes(t *testing.T) {
a := cpf.GerarCPF()
b := cpf.GerarCPF()
c := cpf.GerarCPF()
if a == b && b == c {
t.Error("três chamadas consecutivas geraram o mesmo CPF")
}
}Execute os testes com go test ./... no diretório do pacote. O segundo teste gera 100 CPFs e valida cada um, garantindo que o algoritmo de geração está correto em escala.
Para validar CPFs existentes em Go, consulte o guia completo de validação em Go. Para gerar CPFs rapidamente sem código, use o gerador online.