Business::BR::CNPJ  Perl module to test for correct CNPJ numbers
use Business::BR::CNPJ;
print "ok " if test_cnpj('90.117.749/765480'); # prints 'ok '
print "bad " unless test_cnpj('88.222.111/000110'); # prints 'bad '
The CNPJ number is an identification number of Brazilian companies emitted by
the Brazilian Ministry of Revenue, which is called "Ministerio da
Fazenda".
CNPJ stands for "Cadastro Nacional de Pessoa Juridica" (literally,
national juridical person registration) as opposed to the CPF number for
natural persons. Sometime ago, it was called CGC ("Cadastro Geral de
Contribuinte" or general taxpayer registration).
The CNPJ is comprised of a base of 8 digits, a 4digits radical and 2 check
digits. It is usually written like '11.111.111/000155' so as to be more
humanreadable.
This module provides "test_cnpj" for checking that a CNPJ number is
correct. Here a
correct CNPJ number means
 •
 it is 14 digits long
 •
 it satisfies the two check equations mentioned below
Before checking, any nondigit letter is stripped, making it easy to test
formatted entries like '11.111.111/000155' and entries with extra blanks like
' 43.337.004 / 000172 '.
 test_cnpj

test_cnpj('48.999.764/000160') # incorrect CPF, returns 0
test_cnpj(' 43.337.004/000172 ') # is ok, returns 1
test_cnpj('888') # nope, returns undef
Tests whether a CNPJ number is correct. Before testing, any nondigit
character is stripped. Then it is expected to be 14 digits long and to
satisfy two check equations which validate the last two check digits. See
"THE CHECK EQUATIONS".
The policy to get rid of '.', '/' and '' is very liberal. It indeeds
discards anything that is not a digit (0, 1, ..., 9) or letter. That is
handy for discarding spaces as well.
test_cnpj(' 66.818.021/000127 ') # is ok, returns 1
But extraneous inputs like 'a53##045%420**0001!50' are also accepted. If
you are worried about this kind of input, just check against a regex:
warn "bad CNPJ: only digits (14) expected"
unless ($cnpj =~ /^\d{14}$/);
warn "bad CNPJ: does not match mask '__.___.___/______'"
unless ($cnpj =~ /^\d{2}\.\d{3}\.\d{3}/\d{4}\d{2}$/);
NOTE. Integer numbers like 3337004000158 (or 3_337_004_0001_58) with fewer
than 14 digits will be normalized (eg. to 03_337_004_0001_58) before
testing.
 canon_cnpj

canon_cnpj(1); # returns '00000000000001'
canon_cnpj('99.999.222/000112'); # returns '99999222000112'
Canon's a candidate for a CNPJ number. In case, the argument is an integer,
it is formatted to at least fourteen digits. Otherwise, it is stripped of
any nonalphanumeric characters and returned as it is.
 format_cnpj

format_cnpj('00 000 000 0000 00'); # returns '00.000.000/000000'
Formats its input into '00.000.000/000000' mask. First, the argument is
canon'ed and then dots, slash and hyphen are added to the first 14 digits
of the result.
 parse_cnpj

($base, $filial, $dv) = parse_cnpj($cpf);
$hashref = parse_cnpj('11.222.333/444400'); # { base => '11222333', filial => '4444' dv => '00' }
Splits a candidate for CNPJ number into base, radical and check digits (dv 
digitos de verificaca~o). It canon's the argument before splitting it into
8, 4 and 2digits parts. In a list context, returns a threeelement list
with the base, the radical and the check digits. In a scalar context,
returns a hash ref with keys 'base', 'filial' and 'dv' and associated
values.
 random_cnpj

$rand_cnpj = random_cnpj($valid);
$good_cnpj = random_cnpj();
$cnpj = random_cnpj(1); # also a good one
$bad_cnpj = random_cnpj(0); # bad CNPJ
Generates a random CNPJ. If $valid is omitted or 1, it is guaranteed to be
correct. If $valid is 0, it is guaranteed to be incorrect.
This function is intented for mass test. (Use it wisely.)
The implementation is: generate a 8digits random number for the base, and
the variation is chosen 95% of the time to be '0001' and the other 5% a
skewed random distribution with the expression "int(sqr
rand(1E8))" is used. A uniform distribution is expected from
"rand". With the base and variation, the check digits are
computed. If $valid==0, the check digits are computed not to
satisfy the check equations.
"test_cnpj" is exported by default. "canon_cnpj",
"format_cnpj", "parse_cnpj" and "random_cnpj"
can be exported on demand.
A correct CNPJ number has two check digits which are computed from the 12 first
digits. Consider the CNPJ number written as 14 digits
c[1] c[2] c[3] c[4] c[5] c[6] c[7] c[8] c[9] c[10] c[11] c[12] dv[1] dv[2]
To check whether a CNPJ is correct or not, it has to satisfy the check
equations:
5*c[1]+4*c[2]+3*c[3]+2*c[4]+9*c[5]+
8*c[6]+7*c[7]+6*c[8]+5*c[9]+4*c[10]+
3*c[11]+2*c[12]+dv[1] = 0 (mod 11) or
= 1 (mod 11) (if dv[1]=0)
and
6*c[1]+5*c[2]+4*c[3]+3*c[4]+2*c[5]+
9*c[6]+8*c[7]+7*c[8]+6*c[9]+5*c[10]+
4*c[11]+3*c[12]+2*dv[1]+dv[2] = 0 (mod 11) or
= 1 (mod 11) (if dv[2]=0)
I heard that there are exceptions of CNPJ numbers which don't obey the check
equations and are still authentic. I have never found one of them.
To make sure this module works, one can try the results obtained against those
found with "Emissa~o de Comprovante de Inscrica~o e de Situaca~o
Cadastral de Pessoa Juridica", a web page which the Brazilian Ministry of
Revenue provides for public consultation on regularity status of the taxpayer.
This page tells if the CNPJ number is a correct entry (14digitslong with
verified check digits), if it references a real company and if it is regular
with the government body.
Given a bad CNPJ, the aftersubmit page tells "O numero do CNPJ na~o e
valido" (the CNPJ number is not valid). If the CNPJ is a good one but
does not reference a real company, it says "CNPJ na~o existe em nossa
base de dados" (CNPJ does not exist in our database). Otherwise, it shows
a details form for the identified taxpayer.
Note that this module only tests correctness. It doesn't enter the merit whether
the CNPJ number actually exists at the Brazilian government databases.
As you might have guessed, this is not the first Perl module to approach this
kind of functionality. Take a look at
http://search.cpan.org/search?module=Brasil::Checar::CGC
Please reports bugs via CPAN RT,
http://rt.cpan.org/NoAuth/Bugs.html?Dist=BusinessBRIds By doing so, the
author will receive your reports and patches, as well as the problem and
solutions will be documented.
A. R. Ferreira, <ferreira@cpan.org>
Copyright (C) 2005 by A. R. Ferreira
This library is free software; you can redistribute it and/or modify it under
the same terms as Perl itself, either Perl version 5.8.6 or, at your option,
any later version of Perl 5 you may have available.