Sexta-feira, 06 de agosto de 2004 às 15h09

Algoritmo do CPF

Vamos entender um pouco como funciona o algoritmo do CPF. Na primeira parte estudaremos o funcionamento do cálculo do CPF para validar os dígitos verificadores que fazem a diferenciação de um CPF para outro.

Logo abaixo segue um código que faz a validação do CPF, mas mesmo que você queria desenvolver o seu próprio código, em javascript ou outra linguagem, abaixo segue uma breve explicação.

Esse algoritmo que é responsável pela validação do CPF foi feito de acordo com a regras do Ministério da Fazenda.

Conhecendo o cálculo do algoritmo do CPF

O CPF é composto por onze algarismos, onde os dois últimos são chamados de dígitos verificadores, ou seja, os dois últimos dígitos são criados a partir dos nove primeiros. O cálculo é feito em duas etapas utilizando o módulo de divisão 11.

Para exemplificar melhor, iremos calcular os dígitos verificadores de um CPF imaginário, por exemplo, 222.333.666-XX.

Fazendo o cálculo do primeiro dígito verificador

O primeiro dígito é calculado com a distribuição dos dígitos colocando-se os valores 10, 9, 8, 7, 6, 5, 4, 3, 2 conforme a representação abaixo:

Números do CPF

2

2

2

3

3

3

6

6

6

Valores definidos
para o calculo

10

9

8

7

6

5

4

3

2

Na seqüência multiplicaremos os valores de cada coluna, confira:

Números do CPF

2

2

2

3

3

3

6

6

6

Valores definidos
para o calculo

10

9

8

7

6

5

4

3

2

Total

20

18

16

21

18

15

24

18

12

Em seguida efetuaremos o somatório dos resultados (20+18+...+18+12), o resultado obtido (162) será divido por 11. Considere como quociente apenas o valor inteiro, o resto da divisão será responsável pelo cálculo do primeiro dígito verificador.

Vamos acompanhar: 162 dividido por 11 obtemos 14 de quociente e 8 de resto da divisão. Caso o resto da divisão seja menor que 2, o nosso primeiro dígito verificador se torna 0 (zero), caso contrário subtrai-se o valor obtido de 11, que é nosso caso, sendo assim nosso dígito verificador é 11-8, ou seja, 3 (três), já temos parte do CPF, confira: 222.333.666-3X.

Fazendo o cálculo do segundo dígito verificador

Para o cálculo do segundo dígito será usado o primeiro dígito verificador já calculado. Montaremos uma tabela semelhante à anterior, só que desta vez usaremos na segunda linha os valores 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, já que estamos incorporando mais um algarismo para esse cálculo. Veja:

Números do CPF

2

2

2

3

3

3

6

6

6

3

Valores definidos
para o calculo

11

10

9

8

7

6

5

4

3

2

Na próxima etapa faremos como na situação do cálculo do primeiro dígito verificador. Multiplicaremos os valores de cada coluna e efetuaremos o somatório dos resultados obtidos: 22+20+18+24+21+18+30+24+18+4=201.

Números do CPF

2

2

2

3

3

3

6

6

6

3

Valores definidos
para o calculo

11

10

9

8

7

6

5

4

3

2

Total

22

20

18

24

21

18

30

24

18

6

Agora pegamos esse valor e dividimos por 11. Considere novamente apenas o valor inteiro do quociente, e com o resto da divisão, no nosso caso 3, usaremos para o cálculo do segundo dígito verificador, assim como na primeira parte.

Caso o valor do resto da divisão seja menor que 2, esse valor passa automaticamente a ser zero, que é o nosso caso, caso contrário é necessário subtrair o valor obtido de 11 para se obter o dígito verificador.

Neste caso chegamos ao final dos cálculos e descobrimos que os dígitos verificadores do nosso CPF hipotético são os números 3 e 8, portanto o CPF ficaria assim: 222.333.666-38.

Exemplo pratico da validação do CPF

Agora que já conhecemos como funciona o algoritmo do CPF, vamos partir para a programação do nosso código.

O nosso código é composto por uma função que vai retornar um valor true ou false para que o formulário seja enviado ou não. Abaixo do código tem uma descrição para um melhor acompanhamento e no fim da matéria um link para o exemplo desenvolvido aqui.

Exemplo:

1 <script language="Javascript">
2         function validaCPF() {
3                 cpf = document.validacao.cpfID.value;
4                 erro = new String;
5                 if (cpf.length < 11) erro += "Sao necessarios 11 digitos para verificacao do CPF! \n\n";
6                 var nonNumbers = /\D/;
7                 if (nonNumbers.test(cpf)) erro += "A verificacao de CPF suporta apenas numeros! \n\n";
8                 if (cpf == "00000000000" || cpf == "11111111111" || cpf == "22222222222" || cpf == "33333333333" || cpf == "44444444444" || cpf == "55555555555" || cpf == "66666666666" || cpf == "77777777777" || cpf == "88888888888" || cpf == "99999999999"){
9                         erro += "Numero de CPF invalido!"
10               }
11               var a = [];
12               var b = new Number;
13               var c = 11;
14               for (i=0; i<11; i++){
15                       a[i] = cpf.charAt(i);
16                       if (i < 9) b += (a[i] * --c);
17               }
18               if ((x = b % 11) < 2) { a[9] = 0 } else { a[9] = 11-x }
19               b = 0;
20               c = 11;
21               for (y=0; y<10; y++) b += (a[y] * c--);
22               if ((x = b % 11) < 2) { a[10] = 0; } else { a[10] = 11-x; }
23               if ((cpf.charAt(9) != a[9]) || (cpf.charAt(10) != a[10])){
24                       erro +="Digito verificador com problema!";
25               }
26               if (erro.length > 0){
27                       alert(erro);
28                       return false;
29               }
30               return true;
31       }
32 </script>

Linha 3 – Declaração da variável cpf responsável por recuperar o valor da text box que tem o numero do CPF.

Linha 4 – Declaração da variável erro como nova String responsável por salvar os erros que aconteçam na validação.

Linha 5 – Verificação se o tamanho da variável cpf é menor que 11 caracteres. Se retornar true, a variável erro é acrescida de um texto referente ao erro.

Linha 6 – Declaração da variável nonNumbers responsável por conter o valor para a checagem utilizando Regular Expression.

Linha 7 – Verificação se a variável CPF contém caracteres que não são números. Se retornar true, a variável erro é acrescida de um texto referente ao erro.

Linha 8 – Verificação se a variável CPFé igual a 11 caracteres repetidos que vão de 0 a 9. Se retornar true, a variável erro é acrescida de um texto referente ao erro.

Linha 11 - Declaração da variável a como uma matriz usando literal notation.

Linha 12 - Declaração da variável b como novo número.

Linha 13 - Declaração da variável c como o valor igual a 11.

Linha 14 – Loop que vai ser executado 11 vezes.

Linha 15 – A matriz a indexada do valor da variável do loop recebe o caractere da variável CPF indexado do valor da variável do loop.

Linha 16 – Verificação se o valor de i é menor que 9. Se retornar true a variável b, é acrescida do valor da matriz a indexada do valor da variável do loop multiplicada pelo valor decrescido da variável c.

Linha 18 – Verificação se a variável x (que tem o valor do resto da divisão de b por 11) é menor que 2. Se retornar true, a matriz a indexada de 9 recebe o valor de 0. Se retornar false a matriz a indexada de 9 recebe o valor de 11 menos o valor de x.

Linha 19 e 20 – As variáveis b e c são reiniciadas.

Linha 21 – Loop que vai ser executado 10 vezes. A variável b é acrescida do valor da matriz a indexada do valor da variável do loop multiplicada pelo valor da variável c decrescido.

Linha 22 – Verificação se a variável x (que tem o valor do resto da divisão de b por 11) é menor que 2. Se retornar true a matriz a indexada de 10 recebe o valor de 0. Se retornar false a matriz a indexada de 10 recebe o valor de 11 menos o valor de x.

Linha 23 – Verificação se a variável cpf indexada de 9 é diferente da matriz a indexada de 9 e se a variável CPF indexada de 10 é diferente da matriz a indexada de 10. Se retornar true a variável erro é acrescida de um texto referente ao erro.

Linha 26 – Verificação se o tamanho da variável erro é maior que 0, se retornar true uma caixa de alerta é mostrada ao usuário com o(s) erro(s) da validação. O formulário retorna falso e não é enviado.

Linha 30 – A função retorna true, com isso o formulário é enviado com sucesso.

Como a função validaCPF pronta vamos partir para a parte HTML para criar o formulário que suportara o caixa de texto para digitar o numero do CPF. O evento onSubmit do formulário é usado para retornar um valor para verificar se o mesmo vai ser enviado ou nao.

Exemplo:

1 <form action="validaCPF.htm" name="validacao" onSubmit="return validaCPF()">
2         <input type="text" name="cpfID" id="cpfID" maxlength="11" value="">
3         <input name="Submit" type="submit" value="enviar">
4 </form>
5 Digite o numero do CPF sem utilizar os caracteres "." ou "-".

Com essa explicação você poderá montar sua própria rotina ou utilizar a que criamos, abaixo segue o link para o exemplo criado aqui.

Confira o exemplo do código: validaCPF.htm

 

15 comentários

 Julian Fernando
06/08/2004 20h27

MATERIA SOBRE CNPJ

EXCELENTE ESTA MATÉRIA SOBRE CPF, AGORA SÓ FALTA UMA MATÉRIA LEGAL COMO ESSA SOBRE CNPJ

 Thiago Prado
14/08/2004 19h11

Proxima coluna sobre CNPJ

Gostaria de dizer que a proxima materia sera' sobre validacao de CNPJ.

 alekiller
25/08/2004 13h13

Boleto bancário

Melhor ainda, seria se fosse abordado um alogaritmo sobre este assunto.

 Michelle Coelho
23/06/2005 19h49

CPF INVÁLIDO

Na verdade os CPF's compostos por apenas um algarismo como por exemplo 111.111.111-11 são válidos e existentes na base da receita.
Outo detalhe e que o CPF nao tem que possuir exatamente 11 algarimos.

 Leandro Covi
12/09/2005 04h21

Existe CPF com +/- de 11 caracteres?

O cara aí de cima falou que não precisa.

Gostaria de saber sobre isso.

 Eduardo Ruscingo
06/10/2005 11h40

Validação CPF

Se é para validação teria de dar a mensagem de CPF Válido, apenas ??? // Ele envia para onde a informação?

 Daniel Pellegrino
04/05/2006 10h34

Possível resolução

Algumas alterações nessa função ... isso resolveu o problema que foi citado pelo menos.


function validaCPF(obj) {
cpf = obj.value
erro = new String;
if (cpf.length < 11) {
if(cpf.length == 10){
cpf = "0" cpf;
obj.value=cpf;
}
else if (cpf.length == 9) {
cpf = "00" cpf;
obj.value=cpf;
}
else {
alert("Número de CPF inválido! \n\n");
obj.value = "";
obj.focus();
return false;
}
}

var nonNumbers = /\D/;
if (nonNumbers.test(cpf)) erro = "A verificacao de CPF suporta apenas numeros! \n\n";
// if (cpf == "00000000000" || cpf == "11111111111" || cpf == "22222222222" || cpf == "33333333333" || cpf == "44444444444" || cpf == "55555555555" || cpf == "66666666666" || cpf == "77777777777" || cpf == "88888888888" || cpf == "99999999999"){
// erro = "Numero de CPF invalido!"
//}
var a = [];
var b = new Number;
var c = 11;
for (i=0; i<11; i ){
a[i] = cpf.charAt(i);
if (i < 9) b = (a[i] * --c);
}
if ((x = b % 11) < 2) { a[9] = 0 } else { a[9] = 11-x }
b = 0;
c = 11;
for (y=0; y<10; y ) b = (a[y] * c--);
if ((x = b % 11) < 2) { a[10] = 0; } else { a[10] = 11-x; }
if ((cpf.charAt(9) != a[9]) || (cpf.charAt(10) != a[10])){
erro ="Digito verificador com problema!";
}
if (erro.length > 0){
alert(erro);
obj.value = "";
obj.focus();
obj.select();

return false;
}
return true;
}

 Daniel Pellegrino
04/05/2006 10h35

Possível resolução

Algumas alterações nessa função ... isso resolveu o problema que foi citado pelo menos.


function validaCPF(obj) {
cpf = obj.value
erro = new String;
if (cpf.length < 11) {
if(cpf.length == 10){
cpf = "0" cpf;
obj.value=cpf;
}
else if (cpf.length == 9) {
cpf = "00" cpf;
obj.value=cpf;
}
else {
alert("Número de CPF inválido! \n\n");
obj.value = "";
obj.focus();
return false;
}
}

var nonNumbers = /\D/;
if (nonNumbers.test(cpf)) erro = "A verificacao de CPF suporta apenas numeros! \n\n";
// if (cpf == "00000000000" || cpf == "11111111111" || cpf == "22222222222" || cpf == "33333333333" || cpf == "44444444444" || cpf == "55555555555" || cpf == "66666666666" || cpf == "77777777777" || cpf == "88888888888" || cpf == "99999999999"){
// erro = "Numero de CPF invalido!"
//}
var a = [];
var b = new Number;
var c = 11;
for (i=0; i<11; i ){
a[i] = cpf.charAt(i);
if (i < 9) b = (a[i] * --c);
}
if ((x = b % 11) < 2) { a[9] = 0 } else { a[9] = 11-x }
b = 0;
c = 11;
for (y=0; y<10; y ) b = (a[y] * c--);
if ((x = b % 11) < 2) { a[10] = 0; } else { a[10] = 11-x; }
if ((cpf.charAt(9) != a[9]) || (cpf.charAt(10) != a[10])){
erro ="Digito verificador com problema!";
}
if (erro.length > 0){
alert(erro);
obj.value = "";
obj.focus();
obj.select();

return false;
}
return true;
}

 Daniel Pellegrino
04/05/2006 10h35

Possível resolução

Algumas alterações nessa função ... isso resolveu o problema que foi citado pelo menos.


function validaCPF(obj) {
cpf = obj.value
erro = new String;
if (cpf.length < 11) {
if(cpf.length == 10){
cpf = "0" cpf;
obj.value=cpf;
}
else if (cpf.length == 9) {
cpf = "00" cpf;
obj.value=cpf;
}
else {
alert("Número de CPF inválido! \n\n");
obj.value = "";
obj.focus();
return false;
}
}

var nonNumbers = /\D/;
if (nonNumbers.test(cpf)) erro = "A verificacao de CPF suporta apenas numeros! \n\n";
// if (cpf == "00000000000" || cpf == "11111111111" || cpf == "22222222222" || cpf == "33333333333" || cpf == "44444444444" || cpf == "55555555555" || cpf == "66666666666" || cpf == "77777777777" || cpf == "88888888888" || cpf == "99999999999"){
// erro = "Numero de CPF invalido!"
//}
var a = [];
var b = new Number;
var c = 11;
for (i=0; i<11; i ){
a[i] = cpf.charAt(i);
if (i < 9) b = (a[i] * --c);
}
if ((x = b % 11) < 2) { a[9] = 0 } else { a[9] = 11-x }
b = 0;
c = 11;
for (y=0; y<10; y ) b = (a[y] * c--);
if ((x = b % 11) < 2) { a[10] = 0; } else { a[10] = 11-x; }
if ((cpf.charAt(9) != a[9]) || (cpf.charAt(10) != a[10])){
erro ="Digito verificador com problema!";
}
if (erro.length > 0){
alert(erro);
obj.value = "";
obj.focus();
obj.select();

return false;
}
return true;
}

 Daniel Pellegrino
04/05/2006 10h36

Possível resolução

Algumas alterações nessa função ... isso resolveu o problema que foi citado pelo menos.

"
function validaCPF(obj) {
cpf = obj.value
erro = new String;
if (cpf.length < 11) {
if(cpf.length == 10){
cpf = "0" cpf;
obj.value=cpf;
}
else if (cpf.length == 9) {
cpf = "00" cpf;
obj.value=cpf;
}
else {
alert("Número de CPF inválido! \n\n");
obj.value = "";
obj.focus();
return false;
}
}

var nonNumbers = /\D/;
if (nonNumbers.test(cpf)) erro = "A verificacao de CPF suporta apenas numeros! \n\n";
// if (cpf == "00000000000" || cpf == "11111111111" || cpf == "22222222222" || cpf == "33333333333" || cpf == "44444444444" || cpf == "55555555555" || cpf == "66666666666" || cpf == "77777777777" || cpf == "88888888888" || cpf == "99999999999"){
// erro = "Numero de CPF invalido!"
//}
var a = [];
var b = new Number;
var c = 11;
for (i=0; i<11; i ){
a[i] = cpf.charAt(i);
if (i < 9) b = (a[i] * --c);
}
if ((x = b % 11) < 2) { a[9] = 0 } else { a[9] = 11-x }
b = 0;
c = 11;
for (y=0; y<10; y ) b = (a[y] * c--);
if ((x = b % 11) < 2) { a[10] = 0; } else { a[10] = 11-x; }
if ((cpf.charAt(9) != a[9]) || (cpf.charAt(10) != a[10])){
erro ="Digito verificador com problema!";
}
if (erro.length > 0){
alert(erro);
obj.value = "";
obj.focus();
obj.select();

return false;
}
return true;
}"

 Daniel Pellegrino
04/05/2006 10h45

Possível resolução

Algumas alterações nessa função ... isso resolveu o problema que foi citado pelo menos.

"
function validaCPF(obj) {
cpf = obj.value
erro = new String;
if (cpf.length < 11) {
if(cpf.length == 10){
cpf = "0" cpf;
obj.value=cpf;
}
else if (cpf.length == 9) {
cpf = "00" cpf;
obj.value=cpf;
}
else {
alert("Número de CPF inválido! \n\n");
obj.value = "";
obj.focus();
return false;
}
}

var nonNumbers = /\D/;
if (nonNumbers.test(cpf)) erro = "A verificacao de CPF suporta apenas numeros! \n\n";
// if (cpf == "00000000000" || cpf == "11111111111" || cpf == "22222222222" || cpf == "33333333333" || cpf == "44444444444" || cpf == "55555555555" || cpf == "66666666666" || cpf == "77777777777" || cpf == "88888888888" || cpf == "99999999999"){
// erro = "Numero de CPF invalido!"
//}
var a = [];
var b = new Number;
var c = 11;
for (i=0; i<11; i ){
a[i] = cpf.charAt(i);
if (i < 9) b = (a[i] * --c);
}
if ((x = b % 11) < 2) { a[9] = 0 } else { a[9] = 11-x }
b = 0;
c = 11;
for (y=0; y<10; y ) b = (a[y] * c--);
if ((x = b % 11) < 2) { a[10] = 0; } else { a[10] = 11-x; }
if ((cpf.charAt(9) != a[9]) || (cpf.charAt(10) != a[10])){
erro ="Digito verificador com problema!";
}
if (erro.length > 0){
alert(erro);
obj.value = "";
obj.focus();
obj.select();

return false;
}
return true;
}"

 Daniel Pellegrino
04/05/2006 10h45

Possível resolução

Algumas alterações nessa função ... isso resolveu o problema que foi citado pelo menos.


function validaCPF(obj) {
cpf = obj.value
erro = new String;
if (cpf.length < 11) {
if(cpf.length == 10){
cpf = "0" cpf;
obj.value=cpf;
}
else if (cpf.length == 9) {
cpf = "00" cpf;
obj.value=cpf;
}
else {
alert("Número de CPF inválido! \n\n");
obj.value = "";
obj.focus();
return false;
}
}

var nonNumbers = /\D/;
if (nonNumbers.test(cpf)) erro = "A verificacao de CPF suporta apenas numeros! \n\n";
// if (cpf == "00000000000" || cpf == "11111111111" || cpf == "22222222222" || cpf == "33333333333" || cpf == "44444444444" || cpf == "55555555555" || cpf == "66666666666" || cpf == "77777777777" || cpf == "88888888888" || cpf == "99999999999"){
// erro = "Numero de CPF invalido!"
//}
var a = [];
var b = new Number;
var c = 11;
for (i=0; i<11; i ){
a[i] = cpf.charAt(i);
if (i < 9) b = (a[i] * --c);
}
if ((x = b % 11) < 2) { a[9] = 0 } else { a[9] = 11-x }
b = 0;
c = 11;
for (y=0; y<10; y ) b = (a[y] * c--);
if ((x = b % 11) < 2) { a[10] = 0; } else { a[10] = 11-x; }
if ((cpf.charAt(9) != a[9]) || (cpf.charAt(10) != a[10])){
erro ="Digito verificador com problema!";
}
if (erro.length > 0){
alert(erro);
obj.value = "";
obj.focus();
obj.select();

return false;
}
return true;
}

 Daniel Pellegrino
04/05/2006 11h00

Possível resolução

Algumas alterações nessa função ... isso resolveu o problema que foi citado pelo menos.


function validaCPF(obj) {
cpf = obj.value
erro = new String;
if (cpf.length < 11) {
if(cpf.length == 10){
cpf = "0" cpf;
obj.value=cpf;
}
else if (cpf.length == 9) {
cpf = "00" cpf;
obj.value=cpf;
}
else {
alert("Número de CPF inválido! \n\n");
obj.value = "";
obj.focus();
return false;
}
}

var nonNumbers = /\D/;
if (nonNumbers.test(cpf)) erro = "A verificacao de CPF suporta apenas numeros! \n\n";
// if (cpf == "00000000000" || cpf == "11111111111" || cpf == "22222222222" || cpf == "33333333333" || cpf == "44444444444" || cpf == "55555555555" || cpf == "66666666666" || cpf == "77777777777" || cpf == "88888888888" || cpf == "99999999999"){
// erro = "Numero de CPF invalido!"
//}
var a = [];
var b = new Number;
var c = 11;
for (i=0; i<11; i ){
a[i] = cpf.charAt(i);
if (i < 9) b = (a[i] * --c);
}
if ((x = b % 11) < 2) { a[9] = 0 } else { a[9] = 11-x }
b = 0;
c = 11;
for (y=0; y<10; y ) b = (a[y] * c--);
if ((x = b % 11) < 2) { a[10] = 0; } else { a[10] = 11-x; }
if ((cpf.charAt(9) != a[9]) || (cpf.charAt(10) != a[10])){
erro ="Digito verificador com problema!";
}
if (erro.length > 0){
alert(erro);
obj.value = "";
obj.focus();
obj.select();

return false;
}
return true;
}

 Luis Oliveira
20/04/2007 01h07

Perfect again.

Thiago, novamente uma "mão-na-roda".

E desta vez, por duas razões: Primeira, porque o código está mais "enxuto" que os "tradicionais". Segundo, porque com esse código a validação pode ser feita no lado cliente, poupando tempo e tráfego.

Se há algum detalhe não muito adequado ou correto na função, cabe ao leitor adaptar ás suas necessidades e/ou interpretação, a base que você passa aqui está totalmente funcional. O mesmo vale para o CNPJ, claro.

Obs: Pessoalmente desconheço que haja a possibilidade de CPF / CNPJ com quantidades diferenciadas de dígitos. Acredito ser algum mal entendido, mas caso não seja, seria interessante e útil receber mais detalhes sobre o assunto.

 EDSON GUIMARÃES SILVA
21/06/2007 11h19

Link quebrado

O link para o cpf.html está quebrado...

Cancelar resposta

Qual a sua opinião?

Faça login abaixo ou cadastre-se rapidamente.


Sobre o Autor
Thiago Prado Atua profissionalmente com desenvolvimento de projetos web em Flash, PHP e Java.

2001 - iMasters FFPA Informática Ltda - Todos os direitos reservados.