Creating a function in PHP to validate CPF

Ronaldo B.August 1, 20229 min read

In this article

CPF (Cadastro de Pessoas Físicas) is a document aimed at registering a person's data with the Federal Revenue. It is a unique document composed of 11 digits. A very common validation in any Web System involves checking if a CPF is valid. However, have you ever stopped to think about what mathematical rule is related to this validation? In this article, we will develop together a function in PHP to perform this verification, while we will also consider the necessary rules for it to occur.

Creating the function

We will name the function validateCPF(). The first filter we will apply will be to remove any type of mask or punctuation from the CPF number. For this, we will use a regular expression, which will return only the numeric digits of the document, and we will then replace any other digit with an empty string, removing it from the entire number. In this case, we can use the feature of a regular expression and use the preg_replace() function to perform the replacement. The code will look like this: 

function validateCPF($number) {

    $cpf = preg_replace('/[^0-9]/', "", $number);

}

Now that we have created the function, we will perform three checks on the CPF number: 1) whether the CPF has exactly 11 digits; 2) whether the document does not have all its numbers the same, and 3) whether the CPF meets the necessary mathematical rule.

First rule

In this function, we will use boolean returns to determine if the CPF is valid. Thus, if the document is valid, we will return true, but if it is not, we will return false.

The first check involves knowing whether the CPF has exactly 11 digits. For this, we can use the strlen() function to identify the weight, or number of characters in the CPF. If it is different from 11, we will return false. The code will be as follows:

if (strlen($cpf) != 11) {
    return false;
}

Second Rule

The second rule involves checking if the CPF does not have all its 11 digits the same. This check is necessary because when a CPF has all the numbers the same, it fits the mathematical rule that we will analyze shortly, but it is still an invalid CPF.

To perform this exception check, we will use a new regular expression, now using the preg_match() function, which aims to check if a string matches what is in the expression. This code will be added to our if() along with the logical OR (||) operator, as follows:

if (strlen($cpf) != 11 || preg_match('/([0-9])\1{10}/', $cpf)) {
    return false;
}

Third Rule

From now on, we will understand what the mathematical rule is for a CPF to be valid. In this article, we will use the fictitious CPF “904.554.270-62” for testing. To know if a CPF is valid, we need to do two equations.

First Equation

First, we need to sum the result of multiplying each of the 9 initial numbers of the CPF by the sequence from 10 to 2 in a descending manner. It may seem confusing, but with an example, it becomes easier to understand.

If we used the example of the above CPF, we would have the following equation:

(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

In italics are the first 9 numbers of the CPF, and in bold are the numbers of the descending sequence starting from 10. We see that the result is 236.

As a second step, we need to multiply this result by 10 and then divide by 11.

236 x 10 = 2360

2360 / 11 = 214

The result is 214. However, what interests us is the remainder of the equation. This number must be equal to the first number of the CPF after the hyphen, that is, the tenth number.

If we divide 2360 / 14, we will see that the remainder is 6, exactly the tenth number of the CPF in question. Thus, the first number is valid and the first check was a success.

Second Equation

The second verification involves a similar equation, but to check the validity of the second number of the CPF after the hyphen, that is, the last number.

We will perform the same equation we did above. The only difference is that we will start multiplying from 11 and we will multiply 10 numbers of the 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

We will also multiply this value by 10 and divide it by 11:

284 x 10 = 2840

2840 / 11 = 258

The remainder of this equation is 2, which is the last number of the CPF. Since the two remainders of the operations correspond to the last numbers of the CPF, we can conclude that this document is valid.

Quite an interesting rule, isn’t it? At first, we might think it is quite complex, but upon closer examination, we realize it is not a “monster” at all.

Implementing the rules in the code

How could we perform these equations dynamically in the code?

Let's start by creating some variables. The first will contain the value of the number to be used in the multiplication. In the case of the first digit, we saw that we started multiplying from 10 to 2 in a descending order. Thus, we will create a variable called $number_to_multiplicate, which will have the initial value of 10 and then its value will decrease as the equation progresses. We will also create a variable called $sum, which will start with an initial value of 0 and will later be incremented by the results of the multiplications. The initial code will look like this:

$sum = 0;
$number_to_multiplicate = 10;

To perform the multiplication in a descending order, we will use a for() loop. We will create a variable $index that will have the initial value of 0, and the loop will execute while this variable is less than 9. In other words, this loop will repeat 9 times, as required in the first equation.

Inside this loop, we will multiply the digit of the CPF that is at the current index position of the for() by the $number_to_multiplicate variable and then decrease the value of that number by 1 using the decrement operator (--).

Finally, we will add the value of each multiplication to the $sum variable. Our for() will look like this:

for ($index = 0; $index < 9; $index++) {
    $sum += $cpf[$index] * ($number_to_multiplicate--);
}

Outside this loop, we will retrieve the value of the sum of all multiplications. Moreover, remember that it is necessary to multiply the total value of the sum by 10 and then divide it by 11. However, we do not want the result of this new equation, but just the remainder. PHP has an operator that returns exactly that, which is the percentage sign (%). This part of the code will look like this:

$result = (($sum * 10) % 11);

This is the basic code to validate a CPF number. However, this loop would only help us validate the first number of the CPF after the hyphen. To validate the last number, we would need to repeat the same loop. However, we know that repeating the same piece of code is not a good practice. Hence, we need to make our code even more abstract and dynamic.

To do this, let's analyze the similarities between the two equations and what their differences are.

When analyzing the two formulas, we see that there are only two differences between them:

1 - The first equation multiplies 9 times. The second multiplies 10 times.

2 - The first equation starts multiplying from the number 10. The second starts multiplying from the number 11.

Thus, we can see a relationship between them, and we realize that the variation is very small. Keeping this in mind, let's create an array in our code where we will store the numbers 9 and 10 in a variable called $number_quantity_to_loop.

We will perform a foreach() on this variable and identify each number in this loop with the name $item. This will be the variable we will provide in the second declaration of the for(). In other words, the loop will occur while the variable $index is less than the variable $item.

In addition, the $number_to_multiplicate variable will have the value of the variable $item + 1. Our code will look like this:

$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);

}

With this, our code will be validating both numbers of the CPF after the hyphen correctly, excellent!!!

Now, let's add one more if(), which will be outside the for(), below the declaration of the $result variable. The check we will perform will be the following: if the value of the result is different from the CPF number after the hyphen, we will return false. The code will be as follows:

if ($cpf[$item] != $result) {
	return false;
};

Finally, to ensure that the validation was a success, just add a return true outside the foreach().

Our code is ready. You can check the complete code developed in this article by accessing our GitHub.

We talked about CPF validation in more detail and using real examples in our Complete PHP 7 Course.

We hope you enjoyed the content. You can send your topic suggestions by clicking here.

See you in the next article :)

Keep learning with Hcode

Sign up for the course platform and follow the next blog guides.