Ver tambem: https://pt.wikipedia.org/wiki/D%C3%ADgito_verificador Dados os nove digitos iniciais dos onze digitos de um CPF hipotetico 1 2 2 3 4 4 5 6 6 - x y calcular, ou verificar a correcao dos dois ultimos digitos (x y). a) calculo do primeiro digito verificador: Multiplicar os nove primeiros algarismos, um a um, pela serie decrescente dos naturais de dez a dois ("pesos") 10 09 08 07 06 05 04 03 02 x x x x x x x x x 1 2 2 3 4 4 5 6 6 10 x 1 = 10 09 x 2 = 18 08 x 2 = 16 07 x 3 = 21 06 x 4 = 24 05 x 4 = 20 04 x 5 = 20 03 x 6 = 18 02 x 6 = 12 Somar os resultados de cada produto: total = 159 (= 10 + 18 + 16 + 21 + 24 + 20 + 20 + 18 + 12) Obter o resto da divisao do total por onze: 159 modulo 11 = 5 (resto da divisao 159/11) Subtrair o resto de onze: 11 - 5 = 6 [Se o resultado da subtracao for 10 ou 11, considerar ZERO como digito resultante: Por exemplo, se o resto da divisao por onze fosse zero ou um, a subtracao (11 - 0 = 11) ou (11 - 1 = 10) teria como digito resultante o ZERO] Este resultado 6 corresponde ao primeiro digito verificador (x), o decimo algarismo do CPF hipotetico do exemplo: 1 2 2 3 4 4 5 6 6 - 6 y b) calculo do segundo digito verificador: Multiplicar os dez primeiros algarismos (incluindo o recem calculado), um a um, pela serie decrescente dos naturais de onze a dois 11 10 09 08 07 06 05 04 03 02 x x x x x x x x x x 1 2 2 3 4 4 5 6 6 6 11 x 1 = 11 10 x 2 = 20 09 x 2 = 18 08 x 3 = 24 07 x 4 = 28 06 x 4 = 24 05 x 5 = 25 04 x 6 = 24 03 x 6 = 18 02 x 6 = 12 Somar os resultados de cada produto: total = 204 (= 11 + 20 + 18 + 24 + 28 + 24 + 25 + 24 + 18 + 12) Obter o resto da divisao do total por onze: 204 modulo 11 = 6(resto da divisao 204/11) Subtrair o resto de onze: 11 - 6 = 5 [Se o resultado da subtracao for 10 ou 11, considerar ZERO como digito resultante: Por exemplo, se o resto da divisao por onze fosse zero ou um, a subtracao (11 - 0 = 11) ou (11 - 1 = 10) teria como digito resultante o ZERO] Este resultado 5 corresponde ao segundo digito verificador (y), o decimo primeiro algarismo do CPF hipotetico do exemplo: 1 2 2 3 4 4 5 6 6 - 6 6 ======================= Para calcular os digitos verificadores do seguinte CNPJ hipotetico 1 2 3 4 5 6 7 8 0 0 0 1 - x y as regras sao semelhantes, mas os "pesos" sao diferentes 05 04 03 02 09 08 07 06 05 04 03 02 Multiplicando os primeiros doze algarismos do CNPJ pelos "pesos" correspondentes 05 04 03 02 09 08 07 06 05 04 03 02 x x x x x x x x x x x x 1 2 3 4 5 6 7 8 0 0 0 1 05 x 1 = 05 04 x 2 = 08 03 x 3 = 09 02 x 4 = 08 09 x 5 = 45 08 x 6 = 48 07 x 7 = 49 06 x 8 = 48 05 x 0 = 00 04 x 0 = 00 03 x 0 = 00 02 x 1 = 02 Somar os resultados de cada produto: total = 222 (= 5 + 8 + 9 + 8 + 45 + 48 + 49 + 48 + 0 + 0 + 0 + 2) Obter o resto da divisao do total por onze: 222 modulo 11 = 2 (resto da divisao 222/11) Subtrair o resto de onze: 11 - 2 = 9 [Se o resultado da subtracao for 10 ou 11, considerar ZERO como digito resultante: Por exemplo, se o resto da divisao por onze fosse zero ou um, a subtracao (11 - 0 = 11) ou (11 - 1 = 10) teria como digito resultante o ZERO] Este resultado 9 corresponde ao primeiro digito verificador (x), o decimo algarismo do CNPJ hipotetico do exemplo: 1 2 3 4 5 6 7 8 0 0 0 1 - 9 y b) calculo do segundo digito verificador: Multiplicar os treze primeiros algarismos (incluindo o recem calculado), um a um, pelos "pesos" 06 05 04 03 02 09 08 07 06 05 04 03 02 x x x x x x x x x x x x x 1 2 3 4 5 6 7 8 0 0 0 1 9 06 x 1 = 06 05 x 2 = 10 04 x 3 = 12 03 x 4 = 12 02 x 5 = 10 09 x 6 = 54 08 x 7 = 56 07 x 8 = 56 06 x 0 = 00 05 x 0 = 00 04 x 0 = 00 03 x 1 = 03 02 x 9 = 18 Somar os resultados de cada produto: total = 237 (= 06 + 10 + 12 + 12 + 10 + 54 + 56 + 56 + 00 + 00 + 00 + 03 + 18) Obter o resto da divisao do total por onze: 237 modulo 11 = 6(resto da divisao 237/11) Subtrair o resto de onze: 11 - 6 = 5 [Se o resultado da subtracao for 10 ou 11, considerar ZERO como digito resultante: Por exemplo, se o resto da divisao por onze fosse zero ou um, a subtracao (11 - 0 = 11) ou (11 - 1 = 10) teria como digito resultante o ZERO] Este resultado 5 corresponde ao segundo digito verificador (y), o decimo quarto algarismo do CNPJ hipotetico do exemplo: 1 2 3 4 5 6 7 8 0 0 0 1 - 9 5 ============================= A titulo de ilustracao, abaixo estao dois pequenos programas em C para gerar digitos verificadores, um a partir dos primeiros nove algarismos de um CPF e o outro a partir dos doze primeiros algarismos de um CNPJ. Baixe os programas assim: wget web.cip.com.br/pater/SI2020/geracic.c wget web.cip.com.br/pater/SI2020/geracnpj.c Para compilar os programas, digite na linha de comando gcc -ogeracic geracic.c gcc -ogeracnpj geracnpj.c e, para executa-los, digite na linha de comando: ./geracic 123456789 substituindo 123456789 pelos primeiros nove algarismos do CPF, ou digite na linha de comando: ./geracnpj 0123456789ab susbstituindo 0123456789ab pelos primeiros doze algarismos do CNPJ CODIGOS-FONTE DOS PROGRAMAS: /*** CODIGO C geracic.c ***/ //calcula digitos verificadores para um cic #include int main(int argc, char **argv){ int cpf[11],j,erro=0,dv1=0,dv2=0,cdv=11; //`erro' detecta e acumula nao-algarismos no parametro for (j=0;j<9;j++) { cpf[j]=argv[1][j]-48; //asc to int ((cpf[j]<0) || (cpf[j]>9))?++erro:0;} //ou erro+=[cond]?1:0; if (erro) printf("erros: %d\n",erro); else { //else(nao houve erro) for(j=0;j<9;j++){ //para cada [0..8] algarismo digitado printf("%d",cpf[j]); //eco algarismo digitado dv2+=cpf[j]*cdv--; //acumula dv2, decrementa cdv: 11..3 dv1+=cpf[j]*cdv; //acumula dv1, aproveita cdv: 10..2 } /*****************coeficientes***************/ //-- 11 10 09 08 07 06 05 04 03 02 /********************************************/ //calcula dois ultimos algarismos [9..10] (dvs) (cpf[j]=11-dv1%11)>9?cpf[j]=0:0; (cpf[j+1]=11-((dv2+=cpf[j]*2)%11))>9?cpf[j+1]=0:0; //ecoa dois ultimos algarismos [9..10] (dvs) printf("%d%d\n",cpf[j],cpf[j+1]); } //fim-do-else(nao houve erro) return 0; } /**************************/ /*** CODIGO C geracnpj.c ***/ //calcula digitos verificadores para um cnpj #include int main(int argc, char **argv){ int cnpj[14],j,erro=0,dv1=0,dv2=0,cdvr=12; //`erro' detecta e acumula nao-algarismos no parametro for (j=0;j9))?++erro:0;} //ou erro+=[cond]?1:0; if (erro) printf("erros: %d\n",erro); else { //else(nao houve erro) for(j=0;j<12;j++){ //para cada [0..11] algarismo digitado printf("%d",cnpj[j]); //eco algarismo digitado dv2+=cnpj[j]*(cdvr--%8+2); //acumula dv2, decrementa cdvr:12..1 dv1+=cnpj[j]*(cdvr%8+2); //acumula dv1, aproveita cdvr: 11..0 } /*****************coeficientes***************/ //-- 12 11 10 09 08 07 06 05 04 03 02 01 00 //%8 4 3 2 1 0 7 6 5 4 3 2 1 0 //%8+2 6 5 4 3 2 9 8 7 6 5 4 3 2 /********************************************/ //calcula dois ultimos algarismos [9..10] (dvs) (cnpj[j]=11-dv1%11)>9?cnpj[j]=0:0; (cnpj[j+1]=11-((dv2+=cnpj[j]*2)%11))>9?cnpj[j+1]=0:0; //ecoa dois ultimos algarismos [12..13] (dvs) printf("%d%d\n",cnpj[j],cnpj[j+1]); } //fim-do-else(nao houve erro) return 0; } /**************************/