[Rio-pm] Verificador CPF/CGC/CNPJ

Adriano Ferreira a.r.ferreira em gmail.com
Quarta Maio 2 03:00:06 PDT 2007


On 5/1/07, breno <breno at rio.pm.org> wrote:
> Pessoal, olha a vergonha!!!
>
> Achei na Internet um verificador em Java de CPF ***E*** CGC/CNPJ com apenas
> 35 linhas, incluindo espaços e "fecha-chaves". Procurando no CPAN, encontrei
> um módulo de verificação de CPF com 29 linhas (sem contar os espaços!) e um
> de CGC/CNPJ com 76 (!!!!) linhas, também sem contar os espaços...
>
> O que acham de fazermos uma versão mais eficiente (e de preferencia mais
> enxuta) desses verificadores em Perl, hein?!
>
> Tá lançado o desafio (e possível golfe em paralelo) para a comunidade!!! O
> melhor código vai pro novo site, e de repente até pro CPAN!!!
>
> []s
>
> -b
>
> Para os que ficaram interessados, os links para os módulos do CPAN (do Paul
> Hodel) estão em:
> http://search.cpan.org/~hodel/Brasil-Checar-CPF-1.01a/Checar/CPF/CPF.pm
> http://search.cpan.org/~hodel/Brasil-Checar-CGC-1.01a/Checar/CGC/CGC.pm
>
> Antes de enviar esse email procurei um pouco mais pelo CPAN e encontrei os
> módulos do Adriano Ferreira, que parecem mais enxutos e podem ser
> vistos/usados em:
> http://search.cpan.org/src/FERREIRA/Business-BR-Ids-0.00_16/lib/Business/BR/CPF.pm
> http://search.cpan.org/~ferreira/Business-BR-Ids-0.00_16/lib/Business/BR/CNPJ.pm

Bem, o código para verificar se um CNPJ é válido no Business::BR::CNPJ é

sub test_cnpj {
  my $cnpj = canon_cnpj shift;
  return undef if length $cnpj != 14;
  my @cnpj = split '', $cnpj;
  my $s1 = _dot([5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0], \@cnpj) % 11;
  my $s2 = _dot([6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2, 1], \@cnpj) % 11;
  unless ($s1==0 || $s1==1 && $cnpj[12]==0) {
    return 0;
  }
  return ($s2==0 || $s2==1 && $cnpj[13]==0) ? 1 : 0;
}

que usa "canon_cnpj" para permitir usar CNPJs formatados
"11.111.111/0001-29" ou não e "_dot" para calcular a soma ponderada. O
módulo de CPF é análogo.

O resto do código dos módulos faz um pouco mais do que este teste de
dígitos de verificação.

Mais importante que o tamanho do código é a facilidade do uso. Eu
particularmente gosto de usar a interface oferecida por
Business::BR::Ids onde você pode testar CNPJs, CPFs, números de PIS e
algumas inscrições estaduais com um código como:

     use Business::BR::Ids qw(test_id);

     $ok = test_id( 'cnpj', '28.282.192/0001-23');
     $ok = test_id( 'cpf', '28.818.188-00' );
     $ok = test_id( 'pis', '19.2992.2920-00');
     $ok = test_id( 'ie', 'PR', '82902020802');


>
> e o código em Java segue abaixo:
> -----------8<-----------
>  public class CNP {
>     private static final int[] pesoCPF = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2};
>     private static final int[] pesoCNPJ = {6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4,
> 3, 2};
>
>     private static int calcularDigito(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;
>     }
>
>     public static boolean isValidCPF(String cpf) {
>        if ((cpf==null) || (cpf.length()!=11)) return false;
>
>        Integer digito1 = calcularDigito(cpf.substring(0,9), pesoCPF);
>        Integer digito2 = calcularDigito(cpf.substring(0,9) + digito1,
> pesoCPF);
>        return cpf.equals(cpf.substring(0,9) + digito1.toString() +
> digito2.toString());
>     }
>
>     public static boolean isValidCNPJ(String cnpj) {
>        if ((cnpj==null)||(cnpj.length()!=14)) return false;
>
>        Integer digito1 = calcularDigito(cnpj.substring(0,12), pesoCNPJ);
>        Integer digito2 = calcularDigito(cnpj.substring(0,12) + digito1,
> pesoCNPJ);
>        return cnpj.equals(cnpj.substring(0,12) + digito1.toString() +
> digito2.toString());
>     }
>
>     public static void main(String[] args) {
>        System.out.printf("CPF Valido:%s \n", CNP.isValidCPF("01115375502"));
>        System.out.printf("CNPJ Valido:%s \n",
> CNP.isValidCNPJ("13642634756318"));
>     }
>  }
> ------------8<-----------------
>
> _______________________________________________
> Rio-pm mailing list
> Rio-pm at pm.org
> http://mail.pm.org/mailman/listinfo/rio-pm
>


Mais detalhes sobre a lista de discussão Rio-pm