CPF (Cadastro de Personas Físicas) es un documento que tiene como objetivo registrar los datos de una persona en la Receita Federal. Este es un documento único, que se compone de 11 dígitos. Una validación muy común en cualquier Sistema Web implica justamente verificar si un CPF es válido. Sin embargo, ¿te has detenido a pensar qué regla matemática está relacionada con esta validación? En este artículo, desarrollaremos juntos una función en PHP para realizar esta verificación, al mismo tiempo que consideraremos las reglas necesarias para que ocurra.
Creando la función
Vamos a llamar a la función validateCPF(). El primer filtro que aplicaremos será eliminar cualquier tipo de máscara o puntuación del número del CPF. Para ello, utilizaremos una expresión regular, que nos devolverá solo los dígitos numéricos del documento y luego reemplazaremos cualquier otro dígito por una cadena vacía, eliminándolo del número completo. En este caso, podemos utilizar el recurso de una expresión regular y hacer uso de la función preg_replace() para realizar la sustitución. El código será así:
function validateCPF($number) {
$cpf = preg_replace('/[^0-9]/', "", $number);
}
Ahora que hemos creado la función, realizaremos tres verificaciones en el número del CPF: 1) si el CPF tiene exactamente 11 dígitos; 2) si el documento no tiene todos sus números repetidos y 3) si el CPF cumple con la regla matemática necesaria.
Primera regla
En esta función, utilizaremos retornos en booleano para definir si el CPF es válido. De este modo, si el documento es válido, devolveremos true, pero si no lo es, devolveremos false.
La primera verificación implica saber si el CPF tiene exactamente 11 dígitos. Para ello, podemos usar la función strlen() para identificar el peso, o cantidad de caracteres en el CPF. Si es diferente de 11, devolveremos false. El código será este:
if (strlen($cpf) != 11) {
return false;
}
Segunda Regla
La segunda regla implica verificar si el CPF no tiene todos sus 11 dígitos iguales. Esta verificación es necesaria porque cuando un CPF tiene todos los números iguales, se ajusta a la regla matemática que analizaremos en breve, pero sigue siendo un CPF inválido.
Para realizar la verificación de esta excepción, utilizaremos una nueva expresión regular, pero ahora usando la función preg_match(), que tiene como objetivo verificar si una cadena coincide con lo que está en la expresión. Este código se añadirá a nuestro if() junto con el operador lógico OR (||), de esta forma:
if (strlen($cpf) != 11 || preg_match('/([0-9])\1{10}/', $cpf)) {
return false;
}
Tercera Regla
A partir de ahora comprenderemos cuál es la regla matemática para que un CPF sea válido. En este artículo usaremos el CPF ficticio “904.554.270-62” para realizar pruebas. Para saber si un CPF es válido, necesitamos hacer dos ecuaciones.
Primera Ecuación
Primero necesitamos sumar el resultado de la multiplicación de cada uno de los 9 primeros números del CPF por la secuencia de 10 a 2 de manera decreciente. Puede parecer confuso, pero con un ejemplo es más fácil de entender.
Si utilizáramos el ejemplo del CPF anterior, tendríamos la siguiente ecuación:
(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
En cursiva están los 9 primeros números del CPF y en negrita están los números de la secuencia decreciente comenzando en 10. Nos damos cuenta de que el resultado es 236.
Como segundo paso, necesitamos multiplicar este resultado por 10 y luego dividir por 11.
236 x 10 = 2360
2360 / 11 = 214
El resultado es 214. Sin embargo, lo que nos interesa es el resto de la ecuación. Este número debe ser igual al primer número del CPF después del guion, es decir, el décimo número.
Si dividimos 2360 / 14, veremos que el resto es 6, exactamente el décimo número del CPF en cuestión. Por lo tanto, el primer número es válido y la primera verificación ha sido un éxito.
Segunda Ecuación
La segunda verificación involucra una ecuación similar, pero para verificar la validez del segundo número del CPF después del guion, es decir, el último número.
Iremos a realizar la misma ecuación que hicimos arriba. La única diferencia es que comenzaremos la multiplicación a partir de 11 y multiplicaremos 10 números del 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
También multiplicaremos este valor por 10 y lo dividiremos por 11:
284 x 10 = 2840
2840 / 11 = 258
El resto de esta ecuación es 2, que es el último número del CPF. Como los dos restos de las operaciones corresponden a los últimos números del CPF, podemos concluir que este documento es válido.
Regla muy interesante, ¿no? Al principio podemos pensar que es bastante compleja, pero cuando la analizamos mejor, nos damos cuenta de que no es ningún “monstruo”.
Implementando las reglas al código
¿Cómo podríamos realizar estas ecuaciones de manera dinámica en el código?
Empecemos creando algunas variables. La primera contendrá el valor del número que será realizado en la multiplicación. En el caso del primer dígito, vimos que empezamos a multiplicar de 10 a 2 de manera decreciente. Así, crearemos una variable llamada $number_to_multiplicate, que tendrá el valor inicial 10 y luego su valor disminuirá a medida que la ecuación se desarrolle. También crearemos una variable llamada $sum, que tendrá el valor inicial igual a 0 y luego su valor se incrementará con los resultados de las multiplicaciones. El código inicial será así:
$sum = 0;
$number_to_multiplicate = 10;
Para realizar la multiplicación de manera decreciente, utilizaremos un bucle de repetición for(). Crearemos una variable $index que tendrá el valor inicial 0 y el bucle se ejecutará mientras esta variable sea menor que 9. Es decir, este bucle se repetirá 9 veces, como es necesario en la primera ecuación.
Dentro de este bucle, multiplicaremos el dígito del CPF que esté en la posición del índice actual del for() por la variable $number_to_multiplicate y luego restaremos 1 al valor de este número, utilizando el operador decremental (--).
Finalmente, añadiremos el valor de cada multiplicación a la variable $sum. Nuestro for() será así:
for ($index = 0; $index < 9; $index++) {
$sum += $cpf[$index] * ($number_to_multiplicate--);
}
Fuera de este bucle de repetición, recuperaremos el valor de la suma de todas las multiplicaciones. Pero, además, recuerda que es necesario multiplicar el valor total de la suma por 10 y luego dividir por 11. Sin embargo, no queremos el resultado de esta nueva ecuación, sino solo el resto. PHP tiene un operador que nos devuelve precisamente eso, que es el signo de porcentaje (%). Esta parte del código será así:
$result = (($sum * 10) % 11);
Este es el código básico para realizar la validación de un número del CPF. Sin embargo, este bucle de repetición solo nos ayudaría a validar el primer número del CPF después del guion. Para poder validar el último número, necesitaríamos repetir el mismo bucle. Sin embargo, sabemos que repetir el mismo fragmento de código no es una buena práctica. Así que necesitamos hacer que nuestro código sea aún más abstracto y dinámico.
Para ello, analicemos cuáles son las similitudes entre las dos ecuaciones y cuáles son sus diferencias.
Al analizar las dos fórmulas, nos damos cuenta de que solo hay dos diferencias entre ellas:
1 - La primera ecuación realiza la multiplicación 9 veces. La segunda realiza la multiplicación 10 veces.
2 - La primera ecuación comienza la multiplicación a partir del número 10. La segunda comienza la multiplicación del número 11.
De esta forma, conseguimos ver una relación entre ellas y notamos que la variación es bastante pequeña. Con esto en mente, crearemos un array en nuestro código donde almacenaremos los números 9 y 10 en una variable llamada $number_quantity_to_loop.
Realizaremos un foreach() en esta variable e identificaremos cada número en este bucle de repetición con el nombre $item. Esta será la variable que informaremos en la segunda declaración del for(). Es decir, el bucle de repetición ocurrirá mientras la variable $index sea menor que la variable $item.
Además, la variable $number_to_multiplicate tendrá el valor de la variable $item + 1. Nuestro código será así:
$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);
}
Con esto, nuestro código estará realizando la validación de los dos números del CPF después del guion correctamente, ¡excelente!
Ahora vamos a añadir otro if(), que estará fuera del for(), debajo de la declaración de la variable $result. La verificación que realizaremos será la siguiente: si el valor del resultado es diferente del número del CPF después del guion, devolveremos false. El código será este:
if ($cpf[$item] != $result) {
return false;
};
Por último, para certificar que la validación fue un éxito, solo hay que añadir un return true fuera del foreach().
Nuestro código está listo. Puedes verificar el código completo desarrollado en este artículo accediendo a nuestro GitHub.
Hablamos sobre la validación de CPF con más detalles y usando ejemplos reales en nuestro Curso Completo de PHP 7.
Esperamos que hayas disfrutado del contenido. Puedes enviar tus sugerencias de tema haciendo clic aquí.
¡Nos vemos en el próximo artículo :)