Validate CPF - C language

Asked

Viewed 814 times

0

I need to generate a random and valid Cpf for a college job

This is the code I’ve developed so far, it’s generating letters instead of numbers in the two-digit checkers

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main()
{
    char cpf[15];
    int i;
    
    srand(time(NULL));
    
    for(i = 0; i < 11; i++) cpf[i] = (rand() % 10 + '0');
    cpf[3] = '.';
    cpf[7] = '.';
    cpf[11] = '-';
    cpf[12] = ((((cpf[0] * 10) + (cpf[1] * 9) + (cpf[2] * 8) + (cpf[4] * 7) + (cpf[5] * 6) + (cpf[6] * 5) + (cpf[8] * 4) + (cpf[9] * 3) + (cpf[10] * 2)) % 11) + '0');
    cpf[13] = ((((cpf[0] * 11) + (cpf[1] * 10) + (cpf[2] * 9) + (cpf[4] * 8) + (cpf[5] * 7) + (cpf[6] * 6) + (cpf[8] * 5) + (cpf[9] * 4) + (cpf[10] * 3) + (cpf[12] * 2)) % 11) + '0');
    cpf[15] = '\0';
    
    printf("%s", cpf);
}
  • You are multiplying the code that represents the character and not the numerical value that this character represents (for each Cpf[i] subtracts '0' to multiply) and, moreover, you have not tested whether the rest of the division is >= 10.

  • See if this article can help: https://medium.com/dev-interior/checagem-de-cpf-em-c-a64fe7a386f5

2 answers

0

Hey, how you doing? So the program was displaying letters in the check digits because the multiplications were being done with characters instead of integers.

A "simple" solution to this is to decrease '0' of each multiplication made (which will transform the characters into integers):

dig = ((((cpf[0] - '0') * 10) + ((cpf[1] - '0') * 9) + ((cpf[2] - '0') * 8) + ((cpf[4] - '0') * 7) + ((cpf[5] - '0') * 6) + ((cpf[6] - '0') * 5) + ((cpf[8] - '0') * 4) + ((cpf[9] - '0') * 3) + ((cpf[10] - '0') * 2)) % 11);

After that, we then analyzed the remnant of that division (stored in the variable dig):

According to the calculation of the check digit, if the remnant is 0 or 1, the digit cpf[12] will be '0' (zero). If 2, 3, 4, 5, 6, 7, 8, 9 or 10, the digit cpf[12] will be (11 - dig) + '0'

if(dig == 0 || dig == 1){
        cpf[12] = '0';
}
    else{
        cpf[12] = (11 - dig) + '0';
}

Same process repeats for second digit checker.

Anyway, the whole code would look like this:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main()
{
    char cpf[15];
    int i;
    int dig;
    
    srand(time(NULL));
    
    for(i = 0; i < 11; i++){
        cpf[i] = (rand() % 10) + '0';
    }
    cpf[3] = '.';
    cpf[7] = '.';
    cpf[11] = '-';
    dig = ((((cpf[0] - '0') * 10) + ((cpf[1] - '0') * 9) + ((cpf[2] - '0') * 8) + ((cpf[4] - '0') * 7) + ((cpf[5] - '0') * 6) + ((cpf[6] - '0') * 5) + ((cpf[8] - '0') * 4) + ((cpf[9] - '0') * 3) + ((cpf[10] - '0') * 2)) % 11);
    if(dig == 0 || dig == 1){
        cpf[12] = '0';
    }
    else{
        cpf[12] = (11 - dig) + '0';
    }
    dig = ((((cpf[0] - '0') * 11) + ((cpf[1] - '0') * 10) + ((cpf[2] - '0') * 9) + ((cpf[4] - '0') * 8) + ((cpf[5] - '0') * 7) + ((cpf[6] - '0') * 6) + ((cpf[8] - '0') * 5) + ((cpf[9] - '0') * 4) + ((cpf[10] - '0') * 3) + ((cpf[12] - '0') * 2)) % 11);
    if(dig == 0 || dig == 1){
        cpf[13] = '0';
    }
    else{
        cpf[13] = (11 - dig) + '0';
    }
    cpf[15] = '\0';
    
    printf("%s \n", cpf);
}

I hope I’ve helped!

-1

Good evening, your problem is quite simple to be solved.

The numeric characters of a CPF field range from 0 to 9 when using srand(), use:

```
 srand() % 9 + '0'
```

So your random number will be between 0 and 9. I hope I’ve helped!

  • This will not generate a CPF, only a sequence of random numbers. CPF has validation rules...

  • The rest of the division of an integer by 9 will result in a number between 0 and 8. After all 9 / 9 gives as a result 1 with rest 0.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.