terça-feira, 25 de setembro de 2012

Validando CPF ou CNPJ

Todo mundo que já desenvolveu um pouquinho teve que descobrir como validar o CPF e/ou o CNPJ de alguma pessoa física ou jurídica, não é? Neste post vou dar uma dica de como fazer isto.

Você obterá as melhores informações (não o melhor algoritmo) no site da Receita Federal. Clique aqui para ir para o local onde está a instrução da receita.

Neste post estou colocando duas classes, uma que faz todo o processo de validação e a outra instancia a classe de validação e executa uns exemplos de teste.

Vamos ver primeiro a classe de testes:
/*
 * classe de teste
 */

package com.blogspot.h3dema.validadores;

/**
 *
 * @author Henrique
 */

public class TestaValidadores {

    /**
     * @param args the command line arguments
     */

    public static void main(String[] args) {
        
       ValidadorDigitos vd = new ValidadorDigitos();
       
       // número gerados aleatoriamente ou via gerador de cpf em

       // http://geradorcpfcnpj.ureshino.org
       String[] cpf = {"01115375502", "77085771364", "963.046.360-16",

                        "62864231760", "511.336.941-10", "185.353.531-19",
                        "332.827.801-09"};
       for(int i = 0; i < cpf.length; i++) {
            System.out.printf("CPF [%s]:%s \n", cpf[i], vd.eValidoCPF(cpf[i]));
       }
             
       String[] cnpj= {"13.642.634/7563-18", "95681735000134",

                       "20595553000141", "1.1.4.5.1.6.4.8.0.0.0.1.0.9"};
       for(int i = 0; i < cnpj.length; i++) {
            System.out.printf("CNPJ [%s]:%s \n"

                               cnpj[i], vd.eValidoCNPJ(cnpj[i]));
       }  
    }
}


Vejam que criei 2 arrays para colocar os dados. Notem que na verdade as rotinas não exigem formatação correta. A rotina retira os itens de pontuação e testa o tamanho da string que sobrou.


/*
 * Classe com rotinas de validação
 * serve simultaneamente para CPF e CNPJ
 */

package com.blogspot.h3dema.validadores;

/**
 *
 * @author Henrique
 */

public class ValidadorDigitos {

 /*
 * as contas de CPF e CNPJ são baseadas no número de ordem do dígito na string
 * os arrays baixo armazenam a ordem para cada dígito
 */
 private static final int[] pesosCPF = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2};
 private static final int[] pesosCNPJ = {6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2};

 /*
  * rotina genérica para calcular qual o dígito verificador
  * @PARAM str   string que contem o CPF ou CNPJ
  * @PARAM peso  array dos pesos, podem ser pesoCPF ou pesoCNPJ
 */

 private static int calcularDigitoVerificador(String str, int[] peso) {
     int soma = 0;
     for (int indice=str.length()-1, digito; indice >= 0; indice-- ) {
       digito = Integer.parseInt(str.substring( indice, indice + 1) );
       soma += digito*peso[peso.length-str.length() + indice];
     }
     soma = 11 - soma % 11;
     return soma > 9 ? 0 : soma;
 }

 /*
 * @PARAM cpf no formato 99999999999 ou 999.999.999-99
 * @RETURN volta true se o CPF é válido
 */

 public static boolean eValidoCPF(String cpf) {
   if (cpf == null) { 
       return false
   }
   // remove "." e "-"
   cpf = 
cpf.replace(".",""); 
   cpf = cpf.replace("-",""); 
   if (cpf.length() != 11) {
       return false; // sai se não tem o tamanho esperado
   }

   // passo 1 - calcula somente para a string sem o digito verificador
   Integer digito1 = calcularDigitoVerificador(cpf.substring(0,9), pesosCPF); 
   // passo 2 - calculo novamente com o dígito obtido no passo 1
   Integer digito2 = calcularDigitoVerificador(cpf.substring(0,9) + digito1,

                                               pesosCPF);
   // retorna indicando se o CPF fornecido é igual o CPF com os 

   // digitos verificadores calculados 
   return cpf.equals(cpf.substring(0,9) + digito1.toString() +

                     digito2.toString());
 }

 /*
 * @PARAM cnpj no formato 99999999999999 ou 99.999.999/9999-99
 * @RETURN volta true se o CNPJ é válido
 */

 public static boolean eValidoCNPJ(String cnpj) {
   if (cnpj==null) {
       return false;
   }
   // remove "." e "-"
   
cnpj = cnpj.replace(".",""); 
   cnpj = cnpj.replace("-","");
   cnpj = cnpj.replace("/","");
   if (cnpj.length) != 14) { 
       return false;
   }
   // passo 1 - calcula somente para a string sem o digito verificador
   Integer digito1 = calcularDigitoVerificador(cnpj.substring(0,12), pesosCNPJ);
   // passo 2 - calculo novamente com o dígito obtido no passo 1
   Integer digito2 = calcularDigitoVerificador(cnpj.substring(0,12) + digito1,

                                               pesosCNPJ);
   return cnpj.equals(cnpj.substring(0,12) + digito1.toString() +

                      digito2.toString());
 }
    
}


Notem que uma opção para os .replace seria retirar todos os caracteres não numéricos da string ou utilizar uma expressão regex para simplificar as linhas mostradas.

O resultado é:


domingo, 2 de setembro de 2012