Busine...::CNPJ(3pm)

๐Ÿ“ฆ
version 0.0022 ยท 3 versions
, in ubuntu noble, ubuntu resolute, ubuntu stonking

๐Ÿ’– NAME ๐Ÿ’–

Okay bestie, so this is Busine...::CNPJ โ€” the 3pm Perl module page, and it does exactly one iconic thing: it tests whether a CNPJ number is correct. That's the whole vibe. โœจ


๐ŸŒธ SYNOPSIS ๐ŸŒธ

use Business::BR::CNPJ;

print "ok " if test_cnpj('90.117.749/7654-80'); # prints 'ok '
print "bad " unless test_cnpj('88.222.111/0001-10'); # prints 'bad '

๐ŸŽ€ DESCRIPTION ๐ŸŽ€

So the CNPJ number is an identification number for Brazilian companies, and it's emitted by the Brazilian Ministry of Revenue, which is called the "Ministรฉrio da Fazenda". ๐Ÿ’…

CNPJ stands for "Cadastro Nacional de Pessoa Jurรญdica" โ€” literally, national juridical person registration โ€” and it's the company-world counterpart to the CPF number, which is for natural persons. Sometime ago it was actually called CGC ("Cadastro Geral de Contribuinte", aka general taxpayer registration). The more you know. ๐Ÿฆ‹

The CNPJ is made up of a base of 8 digits, a 4-digits radical, and 2 check digits. It's usually written like '11.111.111/0001-55' so it's more human-readable. ๐Ÿซถ

This module hands you test_cnpj for checking that a CNPJ number is correct. And "a correct CNPJ number" here means:

  • it is 14 digits long
  • it satisfies the two check equations mentioned below

Before checking, any non-digit letter is stripped, which makes it super easy to test formatted entries like '11.111.111/0001-55' and entries with extra blanks like ' 43.337.004 / 0001-72 '. No cap. โœจ

๐Ÿ’œ test_cnpj

test_cnpj('48.999.764/0001-60') # incorrect CPF, returns 0
test_cnpj(' 43.337.004/0001-72 ') # is ok, returns 1
test_cnpj('888') # nope, returns undef

Tests whether a CNPJ number is correct. Before testing, any non-digit 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/0001-27 ') # is ok, returns 1

But extraneous inputs like 'a53##045%4-20**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/0001-12'); # 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 non-alphanumeric characters and returned as it is. ๐Ÿ’…

โญ format_cnpj

format_cnpj('00 000 000 0000 00'); # returns '00.000.000/0000-00'

Formats its input into '00.000.000/0000-00' 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/4444-00'); # { base => '11222333', filial => '4444' dv => '00' }

Splits a candidate for CNPJ number into base, radical and check digits (dv - dรญgitos de verificaรงรฃo). It canon's the argument before splitting it into 8-, 4- and 2-digits parts. In a list context, returns a three-element 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 8-digits 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. ๐Ÿ’€

โœจ EXPORT โœจ

"test_cnpj" is exported by default. "canon_cnpj", "format_cnpj", "parse_cnpj" and "random_cnpj" can be exported on demand. ๐Ÿ‘‘


๐Ÿ‘‘ THE CHECK EQUATIONS ๐Ÿ‘‘

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)

๐Ÿ˜ญ BUGS ๐Ÿ˜ญ

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. So like... maybe they're out there, lurking. ๐Ÿ™ˆ


๐ŸŒธ SEE ALSO ๐ŸŒธ

To make sure this module works, one can try the results obtained against those found with "Emissรฃo de Comprovante de Inscriรงรฃo e de Situaรงรฃo Cadastral de Pessoa Jurรญdica", 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 (14-digits-long with verified check digits), if it references a real company and if it is regular with the government body. ๐Ÿฆ‹

Given a bad CNPJ, the after-submit page tells "O nรบmero do CNPJ nรฃo รฉ vรกlido" (the CNPJ number is not valid). If the CNPJ is a good one but does not reference a real company, it says "CNPJ nรฃ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=Business-BR-Ids By doing so, the author will receive your reports and patches, as well as the problem and solutions will be documented. ๐Ÿซถ


๐Ÿ’– AUTHOR ๐Ÿ’–

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.


๐Ÿ™ˆ POD ERRORS ๐Ÿ™ˆ

Hey! The above document had some coding errors, which are explained below:

Around line 112:

Non-ASCII character seen before =encoding in '"Ministรฉrio'. Assuming
CP1252

And that's the whole page, bestie! This one was perl v5.36.0, dated 2022-10-13. Stay iconic, validate those check digits, and remember: correct entry โ‰  real company. ๐Ÿ’œโœจ

๐Ÿ“ฆ where this page comes from