Peter Rehm's Blog

apple,development,life & more

Validierung von Ausweisdaten mit PHP

Ohne Kommentare

Es kursieren unzählige Mythen um die Ausweisnummer. So behaupten einige,
die letzte Ziffer, sei die Zahl, wieviele Leute in Deutschland einem ähnlich
sind :-)
Dem ist nicht so. Hinter der Ausweisnummer steckt ein triviales System.

Der erste Block setzt sich zusammen aus der Ausgabenummer des Ortes, von dem
man den Ausweis bezogen hat, einer zufälligen Nummer, einer Prüfziffer, und
der Staatsangehörigkeit.

Beispiel:

CODE:
0000000005D


Die letzte Zahl vor dem D ist die Prüfziffer (5), und das D ist die Staatsangehörigkeit,
also Deutsch.

Der zweite Block beinhaltet das Geburtsdatum des Ausweisinhabers, in der
Form YYMMDD und eine Prüfziffer

Beispiel:

CODE:
8607209


9 ist in dem Beispiel die Prüfziffer, und der Ausweisinhaber wurde am 20. Juli 1986
geboren.

Der dritte Block ist wie der zweite, beinhaltet allerdings das Gültigkeitsdatum.

Beispiel:
CODE:
8607209


In dem Fall ist die Prüfziffer wieder 9, und der Ausweis ist gültig bis zum 20. Juli 1986.

Der letzte Block ist eine Prüfziffer von den Prüfziffern.

Prüfziffern



Hinter den Prüfziffern verbirgt sich ein einfacher Algorithmus.

CODE:
7 * die erste Zahl + 3 * die zweite Zahl + die dritte Zahl + 7 * die erste Zahl,...


Dies wird solange wiederholt, bis alle Zahlen summiert werden. Das Ergebnis Modulo 10
ist dann die Prüfziffer.

Beispiel:
CODE:
8607209


Berechnung:
CODE:
8*7 + 6*3 + 0 + 7*7 + 2*3 + 0 = 129

129 % 10 = 9

Daher ist die Prüfziffer 9.


Auch die Prüfziffer der Prüfziffern wird nach dem gleichen Algorithmus berechnet.

Code



CODE:
<?php
/**
* class to verify the german passport number
*/
class verify_passport
{

var $full_number;
var $blocks=array();
var $result;
var $is_valid=true;
var $expires;

/**
* Constructor
* @param string $number passportnumber
* @return void
*/
function verify_passport($number)
{
/**
* Remove the < and split into the 4 blocks
* If $number > 26 $number is invalid
*/
if(strlen($number)>26 || strlen($number)<26)
{
$number=str_replace('<','',$number);
if(strlen($number)>26)
{
die('invalid passport length');
}
}

$this->blocks[1]=substr($number,0,11);
$this->blocks[2]=substr($number,11,7);
$this->blocks[3]=substr($number,18,7);
$this->blocks[4]=substr($number,25,1);
foreach($this->blocks as $key => $value)
{
if(!$this->verify_block($key,$value))
{
echo $key;
$this->is_valid=false;
return;
}
}

/**
* Set the expire date
*/
$this->expires=mktime(0,0,0,substr($this->blocks[3],2,2),substr($this->blocks[3],4,2),substr($this->blocks[3],0,2));

}

/**
* Verifies the single Blocks
* @param integer $type block id
* @param string $data block content
* @return boolean
*/
function verify_block($type,$data)
{
switch($type)
{
case 1:
return ($this->calc_checksum(substr($data,0,-2))==$data{9} ? true : false );
break;
case 2:
case 3:
return ($this->calc_checksum(substr($data,0,-1))==$data{6} ? true : false );
break;
case 4:
return ($this->calc_checksum(substr($this->blocks[1],0,-1).substr($this->blocks[2],0).substr($this->blocks[3],0))==$data{0} ? true : false );
break;
}
}

/**
* Calculates the Checksum for the given line
* @param string $data
* @result unit place of the checksum
*/
function calc_checksum($data)
{
$result=0;
$length=strlen($data);
for($i=0;$i<$length;$i++)
{
switch($i%3)
{
case 0:
$result+=$data{$i}*7;
break;
case 1:
$result+=$data{$i}*3;
break;
case 2:
$result+=$data{$i};
break;
}
}
return $result%10;
}

/**
* Checks if all was valid - Also if passport is not expired
* @return boolean
*/
function is_valid()
{
if($this->is_valid)
{
if(time()<=$this->expires)
{
return true;
}
}
return false;
}

/**
* Returns the Age in array or unix timestamp
* @param integer $type 0=array 1=timestamp
* @return array or timestamp
*/
function get_age($type='0')
{

$year=substr($this->blocks[2],0,2);
/*
* Create a 4 digit Year number
*/
if($year>=20)
{
$year=(substr(date("Y"),0,2)-1)*100+$year;
} else {
$year=substr(date("Y"),0,2)*100+$year;
}
$month=substr($this->blocks[2],2,2);
$day=substr($this->blocks[2],4,2);

if($type==0)
{
return array('year'=>$year,
 'month'=>$month,
 'day'=>$day);
} else {
return mktime(0,0,0,$month,$day,$year);
}
}
}
?>


Funktionsweise


Der Constructor teilt die Nummer in die Blocks auf, und überprüft ob die Länge
der Nummer korrekt ist. Ist dies nicht der Fall wird die Class sofort beendet.
Der die() ist zugegeben etwas hart, und sollte im Produktiven Einsatz vielleicht
nicht so verwendet werden :-)

Danach kann ich mir über die Methode is_valid() anzeigen lassen, ob die
Ausweisnummer gültig ist. Die Funktion gibt einen Boolschen Wert zurück.
Neben den Prüfziffern wird auch überprüft, ob das Ablaufdatum noch nicht
erreicht ist.

Man kann sich auch das Geburtsdatum als Unix Timestamp oder als Array ausgeben lassen.
Dies geht mittels get_age($type). ist type 0 wird in Array mit den Keys (year,month,day
zurückgegeben, ansonsten ein Unix Timestam.

Der Einsatz



Das folgende Beispiel soll abschließend die Funktionsweise verdeutlichen.

CODE:
$try=new verify_passport($ppn);
var_dump( date("Ymd",$try->get_age(1)) );
var_dump( $try->is_valid() );


$ppn sollte die Ausweisnummer beinhalten.

Geschrieben von Peter Rehm

05.03.2007 um 18:51:31

Abgelegt in PHP

0 Trackbacks zu Validierung von Ausweisdaten mit PHP

Trackback-URL für diesen Eintrag

  1. Keine Trackbacks

0 Kommentare zu Validierung von Ausweisdaten mit PHP

  1. Noch keine Kommentare

Kommentar schreiben

BBCode-Formatierung erlaubt
Umschließende Sterne heben ein Wort hervor (*wort*), per _wort_ kann ein Wort unterstrichen werden.
Standard-Text Smilies wie :-) und ;-) werden zu Bildern konvertiert.
Die angegebene E-Mail-Adresse wird nicht dargestellt, sondern nur für eventuelle Benachrichtigungen verwendet.

Um maschinelle und automatische Übertragung von Spamkommentaren zu verhindern, bitte die Zeichenfolge im dargestellten Bild in der Eingabemaske eintragen. Nur wenn die Zeichenfolge richtig eingegeben wurde, kann der Kommentar angenommen werden. Bitte beachten Sie, dass Ihr Browser Cookies unterstützen muss, um dieses Verfahren anzuwenden.
CAPTCHA

Kommentare werden erst nach redaktioneller Prüfung freigeschaltet!