guenni
Goto Top

Tabellen IDs validieren und generieren mit dem MODULO10-Verfahren

Nahezu jede Datenbank bietet eine Funktion, die beim Anlegen eines Datensatzes
einen numerischen Schlüssel generiert, der automatisch inkrementiert wird.

Für einige Fälle mag dies ausreichend sein, aber es ergeben sich auch Nachteile, wenn
man sich dieser Funktion bedienen und Artikelnummern, Kontonummern etc. einfach
nur hochzählen und ohne validieren auf Gültigkeit verwenden würde.

Durch Tippfehler werden falsche Artikel ausgewählt oder Gelder werden auf falsche
Konten überwiesen, was beides wieder Aufwand und Kosten nach sich zieht, um Fehler
zu korrigieren.

Statt dessen kann man sich verschiedener Verfahren bedienen, neue ID's zu generieren
und mit einer Prüfziffer zu versehen, bzw. eine ID zu validieren.
Eines davon ist das MODULO10-Verfahren – Gewichtung 2,1,2,1,2,1,2,1,2.

ID validieren

Gegeben sei z.B. eine 10stellige ID: 0059735878, wobei die führenden Nullen entfallen können.
Die letzte Ziffer, die erwartete Prüfziffer, wird abgeschnitten.
Die Ziffern der verbleibenden ID, 005973587, werden nun von rechts nach links
abwechselnd mit 2,1,2,1,2 (Gewichtung) usw. multipliziert.
Ergebnis: 0 0 10 9 14 3 10 8 14
Die Quersummen der Produkte werden addiert: 0 + 0 + 1 + 9 + 5 + 3 + 1 + 8 + 5 = 32
Dann wird der Rest der Division durch 10 gebildet = 2
Das Ergebnis wird von 10 abgezogen = 8
Das Ergebnis modulo 10 ist die erwartete Prüfziffer.
Die letzte Modulo-Operation ist für den Fall, dass das Ergebnis der Subtraktion 10 ist. Dann
wird aus der 10 eine Null.

Neue ID's generieren

Genauso lassen sich neue ID's generieren. Angenommen, die oben verwendete ID sei die
zuletzt generierte. Die Prüfziffer wird abgeschnitten, der Rest wird um einen beliebigen Wert,
z.B. 1, erhöht: 5973587 + 1 = 5973588. Es kann auch jeder andere Wert aufaddiert werden.
Jetzt wird die Prüfziffer berechnet. Zuerst die Ziffern von rechts nach links wechselweise
mit 2,1,2,1 (Gewichtung) usw. multiplizieren, ergibt: 10 9 14 3 10 8 16
Dann Addition der Quersummen: 1 + 9 + 5 + 3 + 1 + 8 + 7 = 34
Rest der Division durch 10 = 4
Das Ergebnis von 10 abziehen = 6
Ergebnis modulo 10 ist die Prüfziffer, die nun an die neue Artikelnummer angehangen wird.
Die letzte Modulo-Operation ist für den Fall, dass das Ergebnis der Subtraktion 10 ist. Dann
wird aus der 10 eine Null.

Zum Testen ein PHP-Script:

Zum Testen werden mit dem Script einige ID's generiert. Anschließend kann man die ID's
mit Tippfehler in ein Textfeld eingeben und prüfen. Das habe ich jetzt mehrere Tage probiert
und nicht einmal habe ich per Zufall einen Tippfehler "eingebaut", der eine gültige Prüfziffer
produziert. Alles in allem also eine ziemlich sichere Methode, ID's zu generieren bzw.
zu validieren.

Gruß
Günni

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
<html>
<head>
<title>Untitled</title>
</head>
<script type="text/javascript">  
<!--
/*
* Vor dem Laden wird durch eine Funktion eine neue Nummer generiert, die in einem Textfeld angezeigt wird.
* Damit diese nicht verändert werden kann, wird das Textfeld beim Laden der Seite "gesperrt". 
*/
function lock_field(){
 document.frmFormular.art_nr.disabled=true;
}
/*
* Da gesperrte Textfelder nicht gesendet werden, muß die Sperrung wieder aufgehoben werden. In der Formulardeklaration
* wird deshalb folg. Funktion beim Senden aufgerufen.
*/
function unlock_field(){
 document.frmFormular.art_nr.disabled=false;
}
// -->
</script>
<body onload="lock_field()">  
<?
//*********************************************
// Datenbankverbindung aufbauen
//*********************************************
include('net-comm/inc/session.inc.php'); 
/*
Die folg. Funktion gibt 1 zurück, wenn der Parameter 2 ist,
bzw. gibt 2 zurück, wenn der Parameter 1 ist
*/
function swap($arg){
 if($arg==2) return 1;
 if($arg==1) return 2;
}
/*
Die folg. Funktion gibt die Quersumme eines Arguments zurück.
Da nur zweistellige Zahlen übergeben werden, reicht es, zu prüfen,
ob das Argument größer 9 ist.
*/
function quer_sum($arg){
 if($arg>9){
  $r=$arg-10;
	$r+=1;
	return $r;
 }else{
 			 return $arg;
 			 }
}

/*
Die folg. Funktion generiert eine neue Artikelnummer
*/
function neue_art_nr(){
 /*
 Zuerst wird die letzte(größte) Artikelnummer abgefragt
 Der Datentyp der Artikelnummer ist varchar(10)
 */
 $query="select max(artnr) as Art_Nr from tabelle1";  
 $result=mysql_query($query);
 $row=mysql_fetch_array($result,MYSQL_ASSOC);
 /*
 Die letzte Stelle der Artikelnummer ist die Prüfziffer.
 Da die Artikelnummer als Zeichenkette vorliegt, kann die
 Prüfziffer einfach mittels einer Funktion abgeschnitten werden.
 */
 $row['Art_Nr']=substr($row['Art_Nr'],0,-1);  
 /*
 Um nun eine neue Artikelnummer generieren zu können, wird 
 der String in einen INT-Wert konvertiert und in einer Variablen abgelegt.
 */
 $int_row=intval($row['Art_Nr']);  
 /*
 Artikelnummer wird um einen beliebigen Wert inkrementiert.
 */
 $int_row+=3;
 /*
 Um auf einzelne Stellen der Artikelnummer zu weiteren Berechnungen
 zugreifen zu können, wird die Artikelnummer wieder in einen String
 konvertiert
 */
 $str_row=strval($int_row);
 /*
 Die einzelnen Stellen der Artikelnummer werden von rechts nach links
 abwechselnd mit 2,1,2,1,2,1 usw. multipliziert.
 Dazu wird ein Multiplikator $m mit 2 initialisiert, und innerhalb der
 for-Schleife durch die Funktion swap(s.o.) abwechselnd auf 1 oder 2 gesetzt.
 Die Produkte werden als Zeichenkette in einer Variablen gespeichert.
 */
 $m=2;
 $str_row2="";  
 for($i=strlen($str_row)-1;$i>=0;$i--){
  $str_row2.=strval($str_row[$i]*$m);
	$m=swap($m);
 }
 /*
 Aus den Produkten der Multipikationen werden die Quersummen gebildet.
 Diese Summen werden in der Variablen $sum_pro aufaddiert.
 */
 $sum_pro=0;
 for($i=0;$i<strlen($str_row2);$i++){
  $sum_pro+=quer_sum($str_row2[$i]);
 }
 /*
 Die Variable $sum_pro bekommt das Ergebnis $sum_pro modulo 10 zugewiesen.
 */
 $sum_pro=$sum_pro%10;
 /*
 Die Variable $sum_pro bekommt das Ergebnis 10-$sum_pro zugewiesen
 */
 $sum_pro=10-$sum_pro;
 /*
Für den Fall, dass das Ergebnis der Subtraktion 10 ist, bekommt die
Variable Ergebnis modulo 10 zugeweisen. Dann ist die Prüfziffer 0. 
*/
 $sum_pro=$sum_pro%10;
 /*
 Das Ergebnis, die Prüfziffer der neuen Artikelnummer, wird an die neue 
 Artikelnummer angehangen.
 */
 $str_row.=$sum_pro;
 /*
 Rückgabe der neuen Artikelnummer.
 */
 return $str_row;
}
/*
Die folg. Funktion errechnet aus einer Artikelnummer die zu erwartende
Prüfziffer. Die Artikelnummer wird ohne Prüfziffer übergeben.
Die Funktion verwendet die gleichen Algorithmen, wie oben.
*/
function pruefziffer($art_nr){
 $m=2;
 $str_row2="";  
 for($i=strlen($art_nr)-1;$i>=0;$i--){
  $str_row2.=strval($art_nr[$i]*$m);
	$m=swap($m);
 }
 $sum_pro=0;
 for($i=0;$i<strlen($str_row2);$i++){
  $sum_pro+=quer_sum($str_row2[$i]);
 }
 $sum_pro=$sum_pro%10;
 $sum_pro=10-$sum_pro;
 $sum_pro=$sum_pro%10;
 return $sum_pro;
}
/*
Der nachfolg. Code trägt die neue Artikelnummer in die Datenbank ein,
nachdem das Formular gesendet wurde.
*/
if(isset($_POST['cmd'])){  
 $cmd=$_POST['cmd'];  
 if($cmd=="Anlegen"){  
  $art_nr=$_POST['art_nr'];  
  $query="insert into tabelle1(artnr) values('$art_nr')";  
	mysql_query($query);
	?>
	<script type="text/javascript">  
<!--
window.location.href='a_modulo10.php';  
// -->
</script>
	<?
 }
/*
Der nachfolg. Code berechnet die Gültigkeit einer Artikelnummer.
Die Nummer wird ohne die Prüfziffer an eine Funktion übergeben.
*/
 if($cmd=="Suchen"){  
  $suche_art_nr=$_POST['suche_art_nr'];  
	if(strlen(trim($suche_art_nr))==0){
	 echo "Bitte eine Nummer eingeben";  
	 echo "<a href='#' onclick='history.back()'> Zurück </a>";  
	 exit;
	}
	$pruefziffer=substr($suche_art_nr,-1);
	$art_nr_ohne_pz=substr($suche_art_nr,0,-1);
	echo "Gesuchte Artikelnummer: ".$suche_art_nr."<br>";  
	echo "Prüfziffer: ".$pruefziffer."<br>";  
	if(!($pruefziffer==pruefziffer($art_nr_ohne_pz))){
	 echo "Die Prüfziffer $pruefziffer ist falsch!<br>";  
	 echo "Erwartete Prüfziffer: ".pruefziffer($art_nr_ohne_pz).".<br>";  
	 echo "Eine Datenbankabfrage wird nicht durchgeführt.<br><br>";  
	}else{
				echo "Die Prüfziffer $pruefziffer ist richtig!<br>";  
				echo "Eine Datenbankabfrage wird durchgeführt.<br><br>";  
				}
 }
}
/*
Das nachfolgende Formular enthält ein Textfeld mit einer gültigen Artikelnummer und 
eine Schaltfläche "Anlegen".  
Nach dem Senden wird die angezeigte Artikelnummer in die DB eingetragen, und die nächste,
gültige Artikelnummer wird angezeigt.
Im leeren Textfeld kann eine Nummer eingegeben und geprüft werden.
*/
?>
<form action="a_modulo10.php" method="post" name="frmFormular" onsubmit="unlock_field()">  
<input type="text" value="<? echo neue_art_nr(); ?>" name="art_nr" />  
<input type="submit" name="cmd" value="Anlegen"/><br>  
<input type="text" name="suche_art_nr" />  
<input type="submit" name="cmd" value="Suchen"/><br>  
</form>
</body>
</html>

Content-Key: 104771

Url: https://administrator.de/contentid/104771

Ausgedruckt am: 29.03.2024 um 11:03 Uhr