Skip to content

Instantly share code, notes, and snippets.

@eduardoedson
Last active June 20, 2022 13:30
Show Gist options
  • Save eduardoedson/8f991b6d234a9ebdcbe3 to your computer and use it in GitHub Desktop.
Save eduardoedson/8f991b6d234a9ebdcbe3 to your computer and use it in GitHub Desktop.
//Retorno: [1] - Se for válido | [0] - Se for inválido
int validarCPF(char *cpf)
{
int i, j, digito1 = 0, digito2 = 0;
if(strlen(cpf) != 11)
return 0;
else if((strcmp(cpf,"00000000000") == 0) || (strcmp(cpf,"11111111111") == 0) || (strcmp(cpf,"22222222222") == 0) ||
(strcmp(cpf,"33333333333") == 0) || (strcmp(cpf,"44444444444") == 0) || (strcmp(cpf,"55555555555") == 0) ||
(strcmp(cpf,"66666666666") == 0) || (strcmp(cpf,"77777777777") == 0) || (strcmp(cpf,"88888888888") == 0) ||
(strcmp(cpf,"99999999999") == 0))
return 0; ///se o CPF tiver todos os números iguais ele é inválido.
else
{
///digito 1---------------------------------------------------
for(i = 0, j = 10; i < strlen(cpf)-2; i++, j--) ///multiplica os números de 10 a 2 e soma os resultados dentro de digito1
digito1 += (cpf[i]-48) * j;
digito1 %= 11;
if(digito1 < 2)
digito1 = 0;
else
digito1 = 11 - digito1;
if((cpf[9]-48) != digito1)
return 0; ///se o digito 1 não for o mesmo que o da validação CPF é inválido
else
///digito 2--------------------------------------------------
{
for(i = 0, j = 11; i < strlen(cpf)-1; i++, j--) ///multiplica os números de 11 a 2 e soma os resultados dentro de digito2
digito2 += (cpf[i]-48) * j;
digito2 %= 11;
if(digito2 < 2)
digito2 = 0;
else
digito2 = 11 - digito2;
if((cpf[10]-48) != digito2)
return 0; ///se o digito 2 não for o mesmo que o da validação CPF é inválido
}
}
return 1;
}
@kugland
Copy link

kugland commented Jun 20, 2022

#include <stdio.h> /* Needed just for main() */

#include <stdlib.h>
#include <string.h>

int
cpf_compute_check_digits(const char *in, char *out)
{
    int i, j, v;

    /* Return false if either parameter is NULL or if input is less than
       9 characters long. */
    if (in == NULL || out == NULL || strlen(in) < 9)
        return 0;

    /* Return false if any of the first 9 chars in input is not a digit. */
    for (i = 0; i < 9; i++)
        if (in[i] < '0' || in[i] > '9')
            return 0;

    /* Copy input to output if pointers are not aliased. */
    if (in != out)
        strncpy(out, in, 9);

    /* Compute check digits. */
    for (i = 9; i < 11; i++) {
        for (j = v = 0; j < i; j++)
            v += (out[j] - '0') * ((i + 1) - j);
        out[i] = (((v * 10) % 11) % 10) + '0';
    }
    out[11] = 0;

    return 1;
}

int
cpf_verify_check_digits(const char *cpf)
{
    int i;
    char out[12];

    /* Compute the CPF with check digits, return false on error. */
    if (cpf_compute_check_digits(cpf, out) == 0)
        return 0;

    /* Return false if the check digits don't match. */
    if (strncmp(cpf, out, 12) != 0)
        return 0;

    /* Check if all digits are the same. */
    for (i = 1; i < 11 && out[i] == out[0]; i++)
        if (i == 10)
            return 0;

    /* If we got here, then it's a valid CPF. */
    return 1;
}


int
main(void)
{
    char str[16];
    for (int i = 0; i < 10; i++) {
        sprintf(str, "%d%d%d%d%d%d%d%d%d%d%d", i, i, i, i, i, i, i, i, i, i, i);
        cpf_compute_check_digits(str, str);
        printf("%s -> ", str);
        printf("%d\n", cpf_verify_check_digits(str));
    }
    for (unsigned prefix = 0; prefix < 99999999ul; prefix++) {
        sprintf(str, "%08u000", prefix);
        cpf_compute_check_digits(str, str);
        printf("%s -> ", str);
        printf("%d\n", cpf_verify_check_digits(str));
    }
    return 0;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment