Last active
December 12, 2015 03:08
-
-
Save paulofreitas/4704673 to your computer and use it in GitHub Desktop.
PHP data validation class for Brazil
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Data validation class for Brazil | |
* | |
* @category Validate | |
* @package Validate_BR | |
* @author Paulo Freitas <me@paulofreitas.me> | |
* @version 20130204 | |
* @copyright 2005-2013 Paulo Freitas | |
* @license http://creativecommons.org/licenses/by-sa/3.0 | |
*/ | |
class Validate_BR | |
{ | |
/* | |
* Credit card flag constants | |
*/ | |
const CARD_AMEX = 1; | |
const CARD_DINERS = 2; | |
const CARD_DISCOVER = 4; | |
const CARD_MASTERCARD = 8; | |
const CARD_VISA = 16; | |
const CARD_ALL = 31; | |
/** | |
* Validates credit card | |
* | |
* @param string $cc credit card number to validate | |
* @param int $flag card flag to validate | |
* @return bool TRUE if the number is a valid credit card, FALSE otherwise | |
* @access public | |
* @since 20060317 | |
*/ | |
public static function CC($cc, $flag = Validate_BR::CARD_ALL) | |
{ | |
// Canonicalize input | |
$cc = preg_replace('{\D}', '', $cc); | |
// Validate choosed flags | |
$er = array(); | |
if ($flag & self::CARD_AMEX) { | |
$er[] = '^3[47].{13}$'; | |
} | |
if ($flag & self::CARD_DINERS) { | |
$er[] = '^3(0[0-5].{11}|6.{12})$'; | |
} | |
if ($flag & self::CARD_DISCOVER) { | |
$er[] = '^6(011.{12}|5.{14})$'; | |
} | |
if ($flag & self::CARD_MASTERCARD) { | |
$er[] = '^5[1-5].{14}$'; | |
} | |
if ($flag & self::CARD_VISA) { | |
$er[] = '^4.{15}$'; | |
} | |
if (empty($er) || !preg_match('~' . implode('|', $er) . '~', $cc)) { | |
return false; | |
} | |
// Validate digits using a modulus 10 algorithm (aka Luhn) | |
for ($sum = 0, $idx = strlen($cc) - 1, $wt = 1; $idx >= 0; | |
$wt = ($wt % 2) + 1, --$idx) { | |
$sum += (($d = intval($cc[$idx]) * $wt) > 9) ? $d - 9 : $d; | |
} | |
return (($sum % 10) == 0); | |
} | |
/** | |
* Validates CNH (Carteira Nacional de Habilitação) | |
* | |
* CNH is the Brazilian driving license. | |
* | |
* @param string $cnh CNH number to validate | |
* @return bool TRUE if the number is a valid CNH, FALSE otherwise | |
* @access public | |
* @since 20100404 | |
*/ | |
public static function CNH($cnh) | |
{ | |
// Canonicalize input | |
$cnh = sprintf('%011s', preg_replace('{\D}', '', $cnh)); | |
// Validate length and invalid numbers | |
if ((strlen($cnh) != 11) || (intval($cnh) == 0)) { | |
return false; | |
} | |
// Validate check digits using a modulus 11 algorithm | |
for ($c = $s1 = $s2 = 0, $p = 9; $c < 9; $c++, $p--) { | |
$s1 += intval($cnh[$c]) * $p; | |
$s2 += intval($cnh[$c]) * (10 - $p); | |
} | |
if ($cnh[9] != (($dv1 = $s1 % 11) > 9) ? 0 : $dv1) { | |
return false; | |
} | |
if ($cnh[10] != (((($dv2 = ($s2 % 11) - (($dv1 > 9) ? 2 : 0)) < 0) | |
? $dv2 + 11 : $dv2) > 9) ? 0 : $dv2) { | |
return false; | |
} | |
return true; | |
} | |
/** | |
* Validates CNPJ (Cadastro Nacional da Pessoa Jurídica) | |
* | |
* CNPJ is the Brazilian corporate taxpayer identification number. | |
* | |
* @param string $cnpj CNPJ number to validate | |
* @return bool TRUE if the number is a valid CNPJ, FALSE otherwise | |
* @access public | |
* @since 20050619 | |
*/ | |
public static function CNPJ($cnpj) | |
{ | |
// Canonicalize input | |
$cnpj = sprintf('%014s', preg_replace('{\D}', '', $cnpj)); | |
// Validate length and CNPJ order | |
if ((strlen($cnpj) != 14) | |
|| (intval(substr($cnpj, -4)) == 0)) { | |
return false; | |
} | |
// Validate check digits using a modulus 11 algorithm | |
for ($t = 11; $t < 13;) { | |
for ($d = 0, $p = 2, $c = $t; $c >= 0; $c--, ($p < 9) ? $p++ | |
: $p = 2) { | |
$d += $cnpj[$c] * $p; | |
} | |
if ($cnpj[++$t] != ($d = ((10 * $d) % 11) % 10)) { | |
return false; | |
} | |
} | |
return true; | |
} | |
/** | |
* Validates CPF (Cadastro de Pessoas Físicas) | |
* | |
* CPF is the Brazilian individual taxpayer identification number. | |
* | |
* @param string $cpf CPF number to validate | |
* @return bool TRUE if the number is a valid CPF, FALSE otherwise | |
* @access public | |
* @since 20050617 | |
*/ | |
public static function CPF($cpf) | |
{ | |
// Canonicalize input | |
$cpf = sprintf('%011s', preg_replace('{\D}', '', $cpf)); | |
// Validate length and invalid numbers | |
if ((strlen($cpf) != 11) | |
|| ($cpf == '00000000000') | |
|| ($cpf == '99999999999')) { | |
return false; | |
} | |
// Validate check digits using a modulus 11 algorithm | |
for ($t = 8; $t < 10;) { | |
for ($d = 0, $p = 2, $c = $t; $c >= 0; $c--, $p++) { | |
$d += $cpf[$c] * $p; | |
} | |
if ($cpf[++$t] != ($d = ((10 * $d) % 11) % 10)) { | |
return false; | |
} | |
} | |
return true; | |
} | |
/** | |
* Validates DDD (Discagem Direta a Distância) | |
* | |
* DDD is the Brazilian phone area code (NPA). | |
* | |
* @param string $ddd 2-digit DDD code | |
* @return bool TRUE if the code is a valid DDD, FALSE otherwise | |
* @access public | |
* @since 20080719 | |
*/ | |
public static function DDD($ddd) | |
{ | |
return preg_match('{^([14689][1-9]|2[14]|[23][278]|[357][13-5]|7[79])$}', | |
$ddd) != false; | |
} | |
/** | |
* Validates NIS (PIS/PASEP/NIT) | |
* | |
* PIS/PASEP/NIT is the Brazilian social integration program. | |
* | |
* @param string $nis NIS number to validate | |
* @return bool TRUE if the number is a valid NIS, FALSE otherwise | |
* @access public | |
* @since 20050620 | |
*/ | |
public static function NIS($nis) | |
{ | |
// Canonicalize input | |
$nis = sprintf('%011s', preg_replace('{\D}', '', $nis)); | |
// Validate length and invalid numbers | |
if ((strlen($nis) != 11) | |
|| (intval($nis) == 0)) { | |
return false; | |
} | |
// Validate check digit using a modulus 11 algorithm | |
for ($d = 0, $p = 2, $c = 9; $c >= 0; $c--, ($p < 9) ? $p++ : $p = 2) { | |
$d += $nis[$c] * $p; | |
} | |
return ($nis[10] == (((10 * $d) % 11) % 10)); | |
} | |
/** | |
* Validates TE (Título Eleitoral) | |
* | |
* Título Eleitoral is the Brazilian voter registration card. | |
* | |
* @param string $te TE number to validate | |
* @return bool TRUE if the number is a valid TE, FALSE otherwise | |
* @access public | |
* @since 20060315 | |
*/ | |
public static function TE($te) | |
{ | |
// Canonicalize input and parse UF | |
$te = sprintf('%012s', preg_replace('{\D}', '', $te)); | |
$uf = intval(substr($te, 8, 2)); | |
// Validate length and invalid UFs | |
if ((strlen($te) != 12) | |
|| ($uf < 1) | |
|| ($uf > 28)) { | |
return false; | |
} | |
// Validate check digits using a slightly modified modulus 11 algorithm | |
foreach (array(7, 8 => 10) as $s => $t) { | |
for ($d = 0, $p = 2, $c = $t; $c >= $s; $c--, $p++) { | |
$d += $te[$c] * $p; | |
} | |
if ($te[($s) ? 11 : 10] != ((($d %= 11) < 2) ? (($uf < 3) ? 1 - $d | |
: 0) | |
: 11 - $d)) { | |
return false; | |
} | |
} | |
return true; | |
} | |
/** | |
* Validates UF (Unidade Federativa) | |
* | |
* UF is the Brazilian federal unit. | |
* | |
* @param string $uf 2-letter UF code | |
* @return bool TRUE if the code is a valid UF, FALSE otherwise | |
* @access public | |
* @since 20050620 | |
*/ | |
public static function UF($uf) | |
{ | |
return preg_match('{^A[CLMP]|BA|CE|DF|ES|[GT]O|M[AGST]|P[ABEIR]|R[JNORS]' | |
. '|S[CEP]$}', $uf) != false; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// Cartão de crédito | |
print (Validate_BR::CC('5111 1111 1111 1118', Validate_BR::CARD_MASTERCARD)) | |
? 'Cartão de crédito MasterCard válido' | |
: 'Cartão de crédito MasterCard inválido'; | |
print (Validate_BR::CC('4111 1111 1111 1111', Validate_BR::CARD_VISA)) | |
? 'Cartão de crédito Visa válido' | |
: 'Cartão de crédito Visa inválido'; | |
print (Validate_BR::CC('4111 1111 1111 1111')) ? 'Cartão de crédito válido' | |
: 'Cartão de crédito inválido'; | |
// CNH | |
print (Validate_BR::CNH('00000000000') ? 'CNH válido' | |
: 'CNH inválido'; | |
// CNPJ | |
print (Validate_BR::CNPJ('00.000.000/0001-91')) ? 'CNPJ válido' | |
: 'CNPJ inválido'; | |
// CPF | |
print (Validate_BR::CPF('012.345.678-90')) ? 'CPF válido' | |
: 'CPF inválido'; | |
// DDD | |
print (Validate_BR::DDD(19)) ? 'DDD válido' | |
: 'DDD inválido'; | |
// NIS | |
print (Validate_BR::NIS('170.33259.50-4')) ? 'NIS válido' | |
: 'NIS inválido'; | |
// Título Eleitoral | |
print (Validate_BR::TE('0000 0000 0000')) ? 'Título Eleitoral válido' | |
: 'Título Eleitoral inválido'; | |
// UF | |
print (Validate_BR::UF('SP')) ? 'UF válida' | |
: 'UF inválida'; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment