Skip to content

Commit aeccf97

Browse files
authored
CNPJ alphanumeric (Brasil) (#282)
* Starting in July 2026, the CNPJ may contain alphanumeric characters. * Starting in July 2026, the CNPJ may contain alphanumeric characters. * Starting in July 2026, the CNPJ may contain alphanumeric characters. * Starting in July 2026, the CNPJ may contain alphanumeric characters. * Starting in July 2026, the CNPJ may contain alphanumeric characters. * Using mb_* functions
1 parent fff9acb commit aeccf97

2 files changed

Lines changed: 27 additions & 11 deletions

File tree

‎src/Validation/BrValidation.php‎

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -114,26 +114,26 @@ public static function cpf(string $check): bool
114114
*/
115115
public static function cnpj(string $check): bool
116116
{
117-
$check = trim($check);
117+
$check = mb_strtoupper(trim($check));
118118
// sometimes the user submits a masked CNPJ
119-
if (preg_match('/^\d\d.\d\d\d.\d\d\d\/\d\d\d\d\-\d\d/', $check)) {
119+
if (preg_match('/^([A-Z0-9]{2}).([A-Z0-9]{3}).([A-Z0-9]{3})\/([A-Z0-9]{4})\-\d\d/', $check)) {
120120
$check = str_replace(['-', '.', '/'], '', $check);
121-
} elseif (!ctype_digit($check)) {
121+
} elseif (!ctype_alnum($check)) {
122122
return false;
123123
}
124-
125-
if (strlen($check) !== 14) {
124+
$charVal = fn(int $key) => ord($check[$key]) - 48;
125+
if (mb_strlen($check) !== 14) {
126126
return false;
127127
}
128-
$firstSum = ((int)$check[0] * 5) + ((int)$check[1] * 4) + ((int)$check[2] * 3) + ((int)$check[3] * 2) +
129-
((int)$check[4] * 9) + ((int)$check[5] * 8) + ((int)$check[6] * 7) + ((int)$check[7] * 6) +
130-
((int)$check[8] * 5) + ((int)$check[9] * 4) + ((int)$check[10] * 3) + ((int)$check[11] * 2);
128+
$firstSum = ($charVal(0) * 5) + ($charVal(1) * 4) + ($charVal(2) * 3) + ($charVal(3) * 2) +
129+
($charVal(4) * 9) + ($charVal(5) * 8) + ($charVal(6) * 7) + ($charVal(7) * 6) +
130+
($charVal(8) * 5) + ($charVal(9) * 4) + ($charVal(10) * 3) + ($charVal(11) * 2);
131131

132132
$firstVerificationDigit = $firstSum % 11 < 2 ? 0 : 11 - ($firstSum % 11);
133133

134-
$secondSum = ((int)$check[0] * 6) + ((int)$check[1] * 5) + ((int)$check[2] * 4) + ((int)$check[3] * 3) +
135-
((int)$check[4] * 2) + ((int)$check[5] * 9) + ((int)$check[6] * 8) + ((int)$check[7] * 7) +
136-
((int)$check[8] * 6) + ((int)$check[9] * 5) + ((int)$check[10] * 4) + ((int)$check[11] * 3) +
134+
$secondSum = ($charVal(0) * 6) + ($charVal(1) * 5) + ($charVal(2) * 4) + ($charVal(3) * 3) +
135+
($charVal(4) * 2) + ($charVal(5) * 9) + ($charVal(6) * 8) + ($charVal(7) * 7) +
136+
($charVal(8) * 6) + ($charVal(9) * 5) + ($charVal(10) * 4) + ($charVal(11) * 3) +
137137
((int)$check[12] * 2);
138138

139139
$secondVerificationDigit = $secondSum % 11 < 2 ? 0 : 11 - ($secondSum % 11);

‎tests/TestCase/Validation/BrValidationTest.php‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,19 @@ public function testSsn()
125125
$this->assertTrue(BrValidation::personId('04.295.166/0001-33'));
126126
$this->assertTrue(BrValidation::personId('33.530.486/0001-29'));
127127

128+
//Testing alphanumeric CNPJ
129+
$this->assertFalse(BrValidation::cnpj('ABC123Z4000110'));
130+
$this->assertFalse(BrValidation::cnpj('9AB5B5FF0001AB'));
131+
$this->assertFalse(BrValidation::cnpj('9AB5B5FF0001AB'));//Last two chars must be numeric
132+
$this->assertFalse(BrValidation::cnpj('12.@BC.345/01#E-35'));//bad chars @#
133+
$this->assertFalse(BrValidation::cnpj('XOX&@!B0K000156'));//Bad chars &@!
134+
135+
$this->assertTrue(BrValidation::cnpj('XOXDNB0K000156'));
136+
$this->assertTrue(BrValidation::cnpj('F9Z3AJUJ000108'));
137+
$this->assertTrue(BrValidation::cnpj('f9z3AjUj000108'));//lowercase must work
138+
$this->assertTrue(BrValidation::cnpj('NGZ9C1T4000145'));
139+
$this->assertTrue(BrValidation::cnpj('12.ABC.345/01DE-35'));
140+
128141
// Testing ssn
129142
$this->assertFalse(BrValidation::personId('04295165000133'));
130143
$this->assertFalse(BrValidation::personId('33530485000129'));
@@ -134,10 +147,13 @@ public function testSsn()
134147
$this->assertFalse(BrValidation::personId('33.530.485/0001-29'));
135148
$this->assertFalse(BrValidation::personId('04.295.166/0001-01'));
136149
$this->assertFalse(BrValidation::personId('33.530.486/0001-30'));
150+
$this->assertFalse(BrValidation::personId('ABC123Z4000110'));
137151
$this->assertTrue(BrValidation::personId('04295166000133'));
138152
$this->assertTrue(BrValidation::personId('33530486000129'));
139153
$this->assertTrue(BrValidation::personId('04.295.166/0001-33'));
140154
$this->assertTrue(BrValidation::personId('33.530.486/0001-29'));
155+
$this->assertTrue(BrValidation::personId('NGZ9C1T4000145'));
156+
$this->assertTrue(BrValidation::personId('12.ABC.345/01DE-35'));
141157

142158
// Testing invalid input
143159
$this->assertFalse(BrValidation::personId('3712093712890371289073901287390812'));

0 commit comments

Comments
 (0)