Excelente, Adriano! <br><br>E vc já comparou o algoritmo do CheckDigits com o seu?<br><br>Aliás, pode dar uma explanada geral sobre onde as fórmulas foram encontradas? Isto é, quais seriam os testes típicos para essa entrada? Digo isso pois alguns verificadores ignoram as entradas &quot;canônicas&quot; como &quot;
111.111.111-11&quot;, por exemplo. Existem outras desse tipo? Nos seus arquivos de testes do BR::Ids tem comparações de 10 CPFs válidos, mas a verificação aleatória testa muito mais se não me engano (por isso perguntei).<br>
<br>Puxa, será que o Paul e o Mathias estão na Rio-PM tb? Ia ser uma discussão interessante ;-)<br><br>[]s<br><br>-b<br><br><div><span class="gmail_quote">On 5/2/07, <b class="gmail_sendername">Adriano Ferreira</b> &lt;<a href="mailto:a.r.ferreira@gmail.com">
a.r.ferreira@gmail.com</a>&gt; wrote:</span><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">Além dos módulos que você encontrou tem também<br>
<br><a href="http://search.cpan.org/~mamawe/Algorithm-CheckDigits-0.44/CheckDigits/M11_004.pm">http://search.cpan.org/~mamawe/Algorithm-CheckDigits-0.44/CheckDigits/M11_004.pm</a><br><br>que consegue tratar CPFs e título eleitoral.
<br><br>On 5/2/07, Adriano Ferreira &lt;<a href="mailto:a.r.ferreira@gmail.com">a.r.ferreira@gmail.com</a>&gt; wrote:<br>&gt; On 5/1/07, breno &lt;<a href="mailto:breno@rio.pm.org">breno@rio.pm.org</a>&gt; wrote:<br>&gt; &gt; Pessoal, olha a vergonha!!!
<br>&gt; &gt;<br>&gt; &gt; Achei na Internet um verificador em Java de CPF ***E*** CGC/CNPJ com apenas<br>&gt; &gt; 35 linhas, incluindo espaços e &quot;fecha-chaves&quot;. Procurando no CPAN, encontrei<br>&gt; &gt; um módulo de verificação de CPF com 29 linhas (sem contar os espaços!) e um
<br>&gt; &gt; de CGC/CNPJ com 76 (!!!!) linhas, também sem contar os espaços...<br>&gt; &gt;<br>&gt; &gt; O que acham de fazermos uma versão mais eficiente (e de preferencia mais<br>&gt; &gt; enxuta) desses verificadores em Perl, hein?!
<br>&gt; &gt;<br>&gt; &gt; Tá lançado o desafio (e possível golfe em paralelo) para a comunidade!!! O<br>&gt; &gt; melhor código vai pro novo site, e de repente até pro CPAN!!!<br>&gt; &gt;<br>&gt; &gt; []s<br>&gt; &gt;<br>
&gt; &gt; -b<br>&gt; &gt;<br>&gt; &gt; Para os que ficaram interessados, os links para os módulos do CPAN (do Paul<br>&gt; &gt; Hodel) estão em:<br>&gt; &gt; <a href="http://search.cpan.org/~hodel/Brasil-Checar-CPF-1.01a/Checar/CPF/CPF.pm">
http://search.cpan.org/~hodel/Brasil-Checar-CPF-1.01a/Checar/CPF/CPF.pm</a><br>&gt; &gt; <a href="http://search.cpan.org/~hodel/Brasil-Checar-CGC-1.01a/Checar/CGC/CGC.pm">http://search.cpan.org/~hodel/Brasil-Checar-CGC-1.01a/Checar/CGC/CGC.pm
</a><br>&gt; &gt;<br>&gt; &gt; Antes de enviar esse email procurei um pouco mais pelo CPAN e encontrei os<br>&gt; &gt; módulos do Adriano Ferreira, que parecem mais enxutos e podem ser<br>&gt; &gt; vistos/usados em:<br>&gt; &gt; 
<a href="http://search.cpan.org/src/FERREIRA/Business-BR-Ids-0.00_16/lib/Business/BR/CPF.pm">http://search.cpan.org/src/FERREIRA/Business-BR-Ids-0.00_16/lib/Business/BR/CPF.pm</a><br>&gt; &gt; <a href="http://search.cpan.org/~ferreira/Business-BR-Ids-0.00_16/lib/Business/BR/CNPJ.pm">
http://search.cpan.org/~ferreira/Business-BR-Ids-0.00_16/lib/Business/BR/CNPJ.pm</a><br>&gt;<br>&gt; Bem, o código para verificar se um CNPJ é válido no Business::BR::CNPJ é<br>&gt;<br>&gt; sub test_cnpj {<br>&gt;&nbsp;&nbsp; my $cnpj = canon_cnpj shift;
<br>&gt;&nbsp;&nbsp; return undef if length $cnpj != 14;<br>&gt;&nbsp;&nbsp; my @cnpj = split &#39;&#39;, $cnpj;<br>&gt;&nbsp;&nbsp; my $s1 = _dot([5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0], \@cnpj) % 11;<br>&gt;&nbsp;&nbsp; my $s2 = _dot([6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2, 1], \@cnpj) % 11;
<br>&gt;&nbsp;&nbsp; unless ($s1==0 || $s1==1 &amp;&amp; $cnpj[12]==0) {<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; return 0;<br>&gt;&nbsp;&nbsp; }<br>&gt;&nbsp;&nbsp; return ($s2==0 || $s2==1 &amp;&amp; $cnpj[13]==0) ? 1 : 0;<br>&gt; }<br>&gt;<br>&gt; que usa &quot;canon_cnpj&quot; para permitir usar CNPJs formatados
<br>&gt; &quot;11.111.111/0001-29&quot; ou não e &quot;_dot&quot; para calcular a soma ponderada. O<br>&gt; módulo de CPF é análogo.<br>&gt;<br>&gt; O resto do código dos módulos faz um pouco mais do que este teste de<br>
&gt; dígitos de verificação.<br>&gt;<br>&gt; Mais importante que o tamanho do código é a facilidade do uso. Eu<br>&gt; particularmente gosto de usar a interface oferecida por<br>&gt; Business::BR::Ids onde você pode testar CNPJs, CPFs, números de PIS e
<br>&gt; algumas inscrições estaduais com um código como:<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;use Business::BR::Ids qw(test_id);<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$ok = test_id( &#39;cnpj&#39;, &#39;28.282.192/0001-23&#39;);<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$ok = test_id( &#39;cpf&#39;, &#39;
28.818.188-00&#39; );<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$ok = test_id( &#39;pis&#39;, &#39;19.2992.2920-00&#39;);<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$ok = test_id( &#39;ie&#39;, &#39;PR&#39;, &#39;82902020802&#39;);<br>&gt;<br>&gt;<br>&gt; &gt;<br>&gt; &gt; e o código em Java segue abaixo:
<br>&gt; &gt; -----------8&lt;-----------<br>&gt; &gt;&nbsp;&nbsp;public class CNP {<br>&gt; &gt;&nbsp;&nbsp;&nbsp;&nbsp; private static final int[] pesoCPF = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2};<br>&gt; &gt;&nbsp;&nbsp;&nbsp;&nbsp; private static final int[] pesoCNPJ = {6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4,
<br>&gt; &gt; 3, 2};<br>&gt; &gt;<br>&gt; &gt;&nbsp;&nbsp;&nbsp;&nbsp; private static int calcularDigito(String str, int[] peso) {<br>&gt; &gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int soma = 0;<br>&gt; &gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (int indice=str.length()-1, digito; indice &gt;= 0; indice-- ) {
<br>&gt; &gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; digito = Integer.parseInt(str.substring(indice,indice+1));<br>&gt; &gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; soma += digito*peso[peso.length-str.length()+indice];<br>&gt; &gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&gt; &gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;soma = 11 - soma % 11;
<br>&gt; &gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return soma &gt; 9 ? 0 : soma;<br>&gt; &gt;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&gt; &gt;<br>&gt; &gt;&nbsp;&nbsp;&nbsp;&nbsp; public static boolean isValidCPF(String cpf) {<br>&gt; &gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ((cpf==null) || (cpf.length()!=11)) return false;<br>
&gt; &gt;<br>&gt; &gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Integer digito1 = calcularDigito(cpf.substring(0,9), pesoCPF);<br>&gt; &gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Integer digito2 = calcularDigito(cpf.substring(0,9) + digito1,<br>&gt; &gt; pesoCPF);<br>&gt; &gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return 
cpf.equals(cpf.substring(0,9) + digito1.toString() +<br>&gt; &gt; digito2.toString());<br>&gt; &gt;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&gt; &gt;<br>&gt; &gt;&nbsp;&nbsp;&nbsp;&nbsp; public static boolean isValidCNPJ(String cnpj) {<br>&gt; &gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ((cnpj==null)||(
cnpj.length()!=14)) return false;<br>&gt; &gt;<br>&gt; &gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Integer digito1 = calcularDigito(cnpj.substring(0,12), pesoCNPJ);<br>&gt; &gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Integer digito2 = calcularDigito(cnpj.substring(0,12) + digito1,<br>
&gt; &gt; pesoCNPJ);<br>&gt; &gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return cnpj.equals(cnpj.substring(0,12) + digito1.toString() +<br>&gt; &gt; digito2.toString());<br>&gt; &gt;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&gt; &gt;<br>&gt; &gt;&nbsp;&nbsp;&nbsp;&nbsp; public static void main(String[] args) {
<br>&gt; &gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.printf(&quot;CPF Valido:%s \n&quot;, CNP.isValidCPF(&quot;01115375502&quot;));<br>&gt; &gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.printf(&quot;CNPJ Valido:%s \n&quot;,<br>&gt; &gt; CNP.isValidCNPJ(&quot;13642634756318&quot;));
<br>&gt; &gt;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&gt; &gt;&nbsp;&nbsp;}<br>&gt; &gt; ------------8&lt;-----------------<br>&gt; &gt;<br>&gt; &gt; _______________________________________________<br>&gt; &gt; Rio-pm mailing list<br>&gt; &gt; <a href="mailto:Rio-pm@pm.org">
Rio-pm@pm.org</a><br>&gt; &gt; <a href="http://mail.pm.org/mailman/listinfo/rio-pm">http://mail.pm.org/mailman/listinfo/rio-pm</a><br>&gt; &gt;<br>&gt;<br>_______________________________________________<br>Rio-pm mailing list
<br><a href="mailto:Rio-pm@pm.org">Rio-pm@pm.org</a><br><a href="http://mail.pm.org/mailman/listinfo/rio-pm">http://mail.pm.org/mailman/listinfo/rio-pm</a><br></blockquote></div><br>