Last active
September 5, 2021 01:35
-
-
Save Sebbo94BY/f5b5813d9344cbb658f8517fdcbb7412 to your computer and use it in GitHub Desktop.
A simple PHP class to check the validity of an identity card and to get some basic information like the age of the person.
This file contains hidden or 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 | |
/** | |
* PHP class to check the validity of an identity card and to get some basic information like the age of the person. | |
* | |
* @author PHP-einfach.de <https://www.php-einfach.de/diverses/personalausweis-ueberpruefen/> | |
* @author Sebastian Krätzig <[email protected]> | |
*/ | |
class IdentityCard | |
{ | |
/** | |
* Constructor | |
*/ | |
public function __construct() | |
{ | |
// constructor | |
} | |
/** | |
* Checks, if the identity card is a new type | |
* | |
* @param string $identity_card_identifier Unique identity card identifier | |
* @return boolean True, when the identity card is a new type, False when an old type | |
* @throws Exception Returns an exception, when the type could not be identified | |
*/ | |
private function is_new_identity_card_type($identity_card_identifier = null) | |
{ | |
if ($identity_card_identifier == null OR empty(trim($identity_card_identifier))) | |
{ | |
throw new Exception("No unique identity card identifier was provided."); | |
} | |
// @todo Regex could be improved: https://de.wikipedia.org/wiki/Ausweisnummer | |
if (!preg_match('/^[0-9A-Z]{10,11}\s[0-9]{7}\s[0-9A-Z]{7,8}\s[0-9]{1}$/', $identity_card_identifier)) | |
{ | |
throw new Exception("Unknown identity card type."); | |
} | |
$splits = explode(" ", strtoupper($identity_card_identifier)); | |
if (strlen($splits[0]) == 11 && strlen($splits[1]) == 7 && strlen($splits[2]) == 7 && strlen($splits[3]) == 1) | |
{ | |
return false; | |
} | |
return true; | |
} | |
/** | |
* Helper function to validate the identity card checksums | |
* | |
* @param string $id | |
* @param string $checksum | |
* @return boolean True, when the checksum is valid | |
*/ | |
private function validate_checksum($id, $checknumber) | |
{ | |
$p = 7; | |
$sum = 0; | |
for($i=0; $i < strlen($id); $i++) | |
{ | |
$char = $id[$i]; | |
if ($char >= '0' && $char <= '9') | |
{ | |
$int = intval($char); | |
} else { | |
$int = ord($char)-55; | |
} | |
$sum += $int*$p; | |
if ($p==1) | |
{ | |
$p=7; | |
} elseif ($p==3) { | |
$p=1; | |
} elseif ($p==7) { | |
$p=3; | |
} | |
} | |
$last_number = substr(strval($sum), -1); | |
if ($last_number != $checknumber) | |
{ | |
return false; | |
} | |
return true; | |
} | |
/** | |
* Checks, if the identity cards checksum is valid | |
* | |
* @param string $identity_card_identifier Unique identity card identifier | |
* @return boolean True, when the identity card checksum is valid, False when it's invalid | |
* @throws Exception Returns an exception, when the type could not be identified | |
*/ | |
public function identity_card_checksum_is_valid($identity_card_identifier) | |
{ | |
$splits = explode(" ", strtoupper($identity_card_identifier)); | |
$checksums = array(); | |
$checksums[] = array(substr($splits[0],0,9), substr($splits[0],9,1)); | |
$checksums[] = array(substr($splits[1],0,6), substr($splits[1],6,1)); | |
$checksums[] = array(substr($splits[2],0,6), substr($splits[2],6,1)); | |
$checksums[] = array(substr($splits[0],0,10).substr($splits[1],0,7).substr($splits[2],0,7), $splits[3]); | |
foreach($checksums as $checksum) | |
{ | |
if (! $this->validate_checksum($checksum[0], $checksum[1])) | |
{ | |
return false; | |
} | |
} | |
return true; | |
} | |
/** | |
* Checks, if the identity card is expired | |
* | |
* @param string $identity_card_identifier Unique identity card identifier | |
* @return boolean True, when the identity card is expired, False when it's still valid | |
*/ | |
public function identity_card_expired($identity_card_identifier) | |
{ | |
$splits = explode(" ", $identity_card_identifier); | |
$valid_until = mktime(0,0,0, substr($splits[2], 2, 2) , substr($splits[2], 4, 2) , "20".substr($splits[2], 0, 2)); | |
if (time() < $valid_until) | |
{ | |
return false; | |
} | |
return true; | |
} | |
/** | |
* Returns information about the person and identity card based on the unique identity card identifier | |
* | |
* @param string $identity_card_identifier Unique identity card identifier | |
* @return stdClass $data An object with information about the person (eg. birthday, identity card expiry date, country of origin, ...) | |
* @throws Exception Returns an exception, when the type could not be identified | |
*/ | |
public function identity_card_info($identity_card_identifier) | |
{ | |
$splits = explode(" ", $identity_card_identifier); | |
$data = new stdClass(); | |
$data->birthday = new stdClass(); | |
$data->birthday->day = $splits[1][4].$splits[1][5]; | |
$data->birthday->month = $splits[1][2].$splits[1][3]; | |
$data->birthday->year = ($splits[1][0].$splits[1][1] > intval(date('y'))) ? '19'.$splits[1][0].$splits[1][1] : '20'.$splits[1][0].$splits[1][1]; | |
$data->identity_card = new stdClass(); | |
$data->identity_card->expiry = new stdClass(); | |
$data->identity_card->expiry->day = $splits[2][4].$splits[2][5]; | |
$data->identity_card->expiry->month = $splits[2][2].$splits[2][3]; | |
$data->identity_card->expiry->year = '20'.$splits[2][0].$splits[2][1]; | |
try { | |
$is_new_identity_card_type = $this->is_new_identity_card_type($identity_card_identifier); | |
} catch (Exception $exception) { | |
throw new Exception($exception->getMessage()); | |
} | |
if ($is_new_identity_card_type) | |
{ | |
$data->country_of_origin = $splits[2][7]; | |
} else { | |
$data->country_of_origin = $splits[0][10]; | |
} | |
$data->authority_code = substr($splits[0], 0, 4); | |
return $data; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Example usage: