CPF (Cadastro de Pessoas Físicas) é um documento que possui o objetivo de registrar os dados de uma pessoa na Receita Federal. Esse é um documento único, que é composto por 11 dígitos. Uma validação muito comum em qualquer Sistema Web envolve justamente verificar se um CPF é válido. Contudo, já parou para pensar qual regra matemática está relacionada com essa validação? Neste artigo, iremos desenvolver juntos uma função em PHP para realizar essa verificação, ao mesmo tempo que iremos considerar as regras necessárias para que ela ocorra.
Criando a função
Vamos dar o nome de validateCPF() para a função. O primeiro filtro que iremos aplicar será retirar qualquer tipo de máscara ou pontuação do número do CPF. Para isso, usaremos uma expressão regular, que nos retornará apenas os dígitos numéricos do documento e daí substituiremos qualquer outro dígito por uma string vazia, removendo-o do número completo. Neste caso podemos utilizar o recurso de uma expressão regular e fazer uso da função preg_replace() para realizar a substituição. O código ficará assim:
function validateCPF($number) {
$cpf = preg_replace('/[^0-9]/', "", $number);
}
Agora que criamos a função, iremos realizar três verificações no número do CPF: 1) se o CPF possui exatamente 11 dígitos; 2) se o documento não possui todos seus números repetidos e 3) se o CPF atende à regra matemática necessária.
Primeira regra
Nesta função, iremos utilizar retornos em booleano para definir se o CPF é válido. Dessa forma, se o documento for válido, retornaremos true, mas se não for, retornaremos false.
A primeira verificação envolve saber se o CPF possui exatamente 11 dígitos. Para isso, podemos usar a função strlen() para identificar o peso, ou quantidade de caracteres no CPF. Se ela for diferente de 11, retornaremos false. O código será este:
if (strlen($cpf) != 11) {
return false;
}
Segunda Regra
A segunda regra envolve verificar se o CPF não possui todos os seus 11 dígitos iguais. Essa verificação é necessária pois quando um CPF possui todos os números iguais, ele se adequa à regra matemática que iremos analisar daqui a pouco, mas continua sendo uma CPF inválido.
Para realizar a verificação dessa exceção, iremos usar uma nova expressão regular, mas agora usando a função preg_match(), que tem o objetivo de verificar se uma string corresponde ao que está na expressão. Esse código será adicionado ao nosso if() junto com o operador lógico OR (||), desta forma:
if (strlen($cpf) != 11 || preg_match('/([0-9])\1{10}/', $cpf)) {
return false;
}
Terceira Regra
A partir de agora iremos entender qual é a regra matemática para um CPF ser válido. Neste artigo iremos usar o CPF fictício “904.554.270-62” para testes. Para saber se um CPF é válido, precisamos fazer duas equações.
Primeira Equação
Primeiro precisamos somar o resultado da multiplicação de cada um dos 9 primeiros números do CPF pela sequência de 10 até 2 de maneira decrescente. Pode parecer confuso, mas com um exemplo fica mais fácil de entender.
Se usássemos o exemplo do CPF acima, teríamos a seguinte equação:
(9 x 10) + (0 x 9) + (4 x 8) + (5 x 7) + (5 x 6) + (4 x 5) + (2 x 4) + (7 x 3) + (0 x 2) = 236
Em itálico estão os 9 primeiros números do CPF e em negrito estão os números da sequência decrescente começando em 10. Percebemos que o resultado deu 236.
Como segundo passo, precisamos multiplicar esse resultado por 10 e depois dividir por 11.
236 x 10 = 2360
2360 / 11 = 214
O resultado deu 214. Contudo, o que nos interessa é o resto da equação. Esse número deve ser igual ao primeiro número do CPF após o hífen, ou seja, o décimo número.
Se dividirmos 2360 / 14, veremos que o resto é 6, exatamente o décimo número do CPF em questão. Logo, o primeiro número é válido e a primeira verificação foi um sucesso.
Segunda Equação
A segunda verificação envolve uma equação similar, mas para verificar a validade do segundo número do CPF após o hífen, ou seja, o último número.
Iremos realizar a mesma equação que fizemos acima. A única diferença é que iremos começar a multiplicação a partir de 11 e iremos multiplicar 10 números do CPF:
(9 x 11) + (0 x 10) + (4 x 9) + (5 x 8) + (5 x 7) + (4 x 6) + (2 x 5) + (7 x 4) + (0 x 3) + (6 x 2) = 284
Também iremos multiplicar esse valor por 10 e dividi-lo por 11:
284 x 10 = 2840
2840 / 11 = 258
O resto dessa equação é 2, que é o último número do CPF. Como os dois restos das operações correspondem aos últimos números do CPF, podemos concluir que esse documento é válido.
Regra muito interessante, não é mesmo? No início podemos achar que é bem complexa, mas quando a analisamos melhor, percebemos que ela não é nenhum “monstro”.
Implementando as regras ao código
Como poderíamos realizar essas equações de maneira dinâmica no código?
Vamos começar criando algumas variáveis. A primeira conterá o valor do número que será realizado na multiplicação. No caso do primeiro dígito, vimos que começamos a multiplicar de 10 até 2 de maneira decrescente. Assim, vamos criar uma variável chamada $number_to_multiplicate, que possuirá o valor inicial 10 e depois terá seu valor decrescido conforme a equação vai ocorrendo. Também vamos criar uma variável chamada $sum, que possuirá o valor inicial igual a 0 e depois terá seu valor incrementado pelos resultados das multiplicações. O código inicial ficará assim:
$sum = 0;
$number_to_multiplicate = 10;
Para realizar a multiplicação de maneira decrescente, iremos usar um laço de repetição for(). Vamos criar uma variável $index que terá o valor inicial 0 e o laço executará enquanto essa variável for menor que 9. Ou seja, esse laço se repetirá 9 vezes, como é necessário na primeira equação.
Dentro deste laço, iremos multiplicar o dígito do CPF que estiver na posição do índice atual do for() pela variável $number_to_multiplicate e depois diminuir o valor desse número em 1, usando o operador decremental (--).
Por fim, iremos acrescentar o valor de cada multiplicação na variável $sum. Nosso for() ficará assim:
for ($index = 0; $index < 9; $index++) {
$sum += $cpf[$index] * ($number_to_multiplicate--);
}
Fora deste laço de repetição, iremos recuperar o valor da soma de todas as multiplicações. Mas, além disso, lembre que é necessário multiplicar o valor total da soma por 10 e depois dividir por 11. Contudo, não queremos o resultado dessa nova equação, mas apenas o resto. O PHP possui um operador que nos retorna justamente isso, que é o sinal de porcentagem (%). Essa parte do código ficará assim:
$result = (($sum * 10) % 11);
Esse é o código básico para realizar a validação de um número do CPF. Contudo, esse laço de repetição nos ajudaria a validar apenas o primeiro número do CPF após o hífen. Para conseguir fazer a validação do último número, precisaríamos repetir o mesmo laço. Sabemos, entretanto, que repetir o mesmo trecho de código não é uma boa prática. Assim, precisamos deixar nosso código ainda mais abstrato e dinâmico.
Para isso, vamos analisar quais são as similaridades entre as duas equações e quais são suas diferenças.
Ao analisar as duas fórmulas, percebemos que há apenas duas diferenças entre elas:
1 - A primeira equação realiza a multiplicação 9 vezes. A segunda realiza a multiplicação 10 vezes.
2 - A primeira equação começa a multiplicação a partir do número 10. A segunda começa a multiplicação do número 11.
Dessa forma, conseguimos ver uma relação entre eles e percebemos que a variação é bem pequena. Com isso em mente, vamos criar um array em nosso código onde iremos armazenar os números 9 e 10 em uma variável chamada $number_quantity_to_loop.
Iremos realizar um foreach() nessa variável e identificaremos cada número nesse laço de repetição com o nome $item. Essa será a variável que informaremos na segunda declaração do for(). Ou seja, o laço de repetição ocorrerá enquanto a variável $index for menor que a variável $item.
Além disso, a variável $number_to_multiplicate possuirá o valor da variável $item + 1. Nosso código ficará assim:
$number_quantity_to_loop = [9, 10];
foreach ($number_quantity_to_loop as $item) {
$sum = 0;
$number_to_multiplicate = $item + 1;
for ($index = 0; $index < $item; $index++) {
$sum += $cpf[$index] * ($number_to_multiplicate--);
}
$result = (($sum * 10) % 11);
}
Com isso, nosso código estará realizando a validação dos dois números do CPF após o hífen de maneira correta, excelente!!!
Vamos adicionar agora mais um if(), que estará fora do for(), abaixo da declaração da variável $result. A verificação que realizaremos será a seguinte: se o valor do resultado for diferente do número do CPF após o hífen, retornaremos false. O código será este:
if ($cpf[$item] != $result) {
return false;
};
Por fim, para certificar que a validação foi um sucesso, basta adicionar um return true fora do foreach().
Nosso código está pronto. Você pode verificar o código completo desenvolvido neste artigo acessando nosso GitHub.
Nós falamos sobre validação de CPF com mais detalhes e usando exemplos reais em nosso Curso Completo de PHP 7.
Esperamos que tenha gostado do conteúdo. Você pode enviar suas sugestões de tema clicando aqui.
A gente se vê no próximo artigo :)