Impressum · Kontakt · Hilfe
Besucher online · Mitglieder



Portal > Foren > Ankündigungen, News und Feedback > Tutorials > [php] Validität von ISBN kontrollieren

Layoutprobleme? - Styleswitcher!

Antwort
 
Themen-Optionen
Alt 16.01.2008, 12:05 Nach oben    #1
Jann Hendrik
Jann Hendrik Bekaan
 
Benutzerbild von Jann Hendrik
 
Registriert seit: 02.12.2004
Ort: Wildeshausen
Beiträge: 1.539
Standard [php] Validität von ISBN kontrollieren

Validierung von ISBN
In diesem Tutorial geht es um die Validierung von ISBN.

Vorwort:
Die ISBN (International Standard Book Number) ist eine 10, bzw. seit dem Jahr 2007 eine 13-stellige Zahlenfolge, die ein Buch in eindeutiger Form kennzeichnet.
Die letzte Zahl ist dabei eine Prüfziffer.
Aufgrund der Knappheit von verfügbaren ISBN wurde der Zahlenraum verdoppelt und in das EAN-System überführt.
Näheres dazu und zur Geschichte sowie dem Aufbau einer ISBN kann man in dem entsprechenden Wikipedia-Artikel nachlesen.

Die Funktionsweise:
Es soll im Verlauf dieses Tutorials ein Funktion erstellt werden, die den boolschen Wert true oder false zurückgibt; in Abhängigkeit davon, ob die übergebene ISBN valid ist - oder nicht.


Die Schnittstelle zum testen der Funktion sieht so aus:
PHP-Code:
<?php
  error_reporting
(E_ALL);

  
$ISBN '3442464552';
  echo 
'<br>'.$ISBN.' -> '.((bISBN($ISBN) === true)?'':'nicht ').'valid';
?>
Diese Zeilen bewirken nur eine Ausgabe mit der Info, ob die angegeben ISBN valid ist, oder nicht.

Doch nun zur eigentlichen Funktion, die die Prüfung vornimmt:
PHP-Code:
<?php
  
function bISBN($ISBN false)
  {
    if(
$ISBN == 'valid'// hier fehlt noch der passende Teil
    
{
      return 
true;
    }
    else
    {
      return 
false;
    }
  }
?>
Das Prinzip soweit sollte klar sein, oder?

die Funktion:
Zuerst müssen alle Striche und Leerzeichen entfernt werden, denn häufig werden diese mit angegeben. Sie enthalten aber keinerlei vewertbaren Informationen.


PHP-Code:
 <?php
  
function bISBN($ISBN false)
  {
    
// alle leerzeichen entfernen
    
$ISBN str_replace(" """$ISBN);

    
// alle - entfernen
    
$ISBN str_replace("-"""$ISBN);

    if(
$ISBN == 'valid'// hier fehlt noch der passende Teil
    
{
      return 
true;
    }
    else
    {
      return 
false;
    }
  }
?>
Der Schritt des Zeichen-entfernens lässt sich auch noch zusammenfassen:
PHP-Code:
 <?php
  
function bISBN($ISBN false)
  {
    
// störende Zeichen (Punkt und Strich) entfernen
    
$ISBN str_replace(array(' ''-'), '' $ISBN);

    if(
$ISBN == 'valid'// hier fehlt noch der passende Teil
    
{
      return 
true;
    }
    else
    {
      return 
false;
    }
  }
?>
Dann muss eine Fallunterscheidung eingebaut werden, denn eine ISBN kann 10stellig, oder (seit Anfang 2007) auch 13stellig sein. Davon hängt aber das verwendete Verfahren zur Berechnung der Prüfziffer ab.

PHP-Code:
 <?php
  
function bISBN($ISBN false)
  {
    
$ISBN str_replace(array(' ''-'), '' $ISBN);

    if(
strlen($ISBN) == 10)
    {
      if(
$ISBN == 'valid'// hier fehlt noch der passende Teil
      
{
        return 
true;
      }
      else
      {
        return 
false;
      }
    }
    elseif(
strlen($ISBN)  == 13)
    {
      if(
$ISBN == 'valid'// hier fehlt noch der passende Teil
      
{
        return 
true;
      }
      else
      {
        return 
false;
      }
    }
    else
    {
      return 
false;
    }
  }
?>
Im Gegensatz zur ISBN-10, bei der auch noch ein X als Prüfziffer vorkommen kann (X wie die römische Zahl für 10), ist die ISBN-13 rein numerisch. Das kann daher als weiteres Prüfargument genommen werden!
Des weiteren sind der ISBN-13 3 weitere Zahlen vorgestellt, welche eine Warengruppe deklarieren. Das ist entweder die 978 oder die 979. Auch das kann als weiteres Prüfargument benutzt werden!
PHP-Code:
 <?php
  
function bISBN($ISBN false)
  {
    
$ISBN str_replace(array(' ''-'), '' $ISBN);

    if(
strlen($ISBN) == 10)
    {
      if(
$ISBN == 'valid'// hier fehlt noch der passende Teil
      
{
        return 
true;
      }
      else
      {
        return 
false;
      }
    }
    elseif(
strlen($ISBN) == 13 && is_numeric($ISBN) && (substr($ISBN03) == 978 || substr($ISBN03) == 979))
    {
      if(
$ISBN == 'valid'// hier fehlt noch der passende Teil
      
{
        return 
true;
      }
      else
      {
        return 
false;
      }
    }
    else
    {
      return 
false;
    }
  }
?>

Die Formel für die Berechnung der Prüfziffer bei ISBN-10 sieht so aus:
Code:
(1*$z1 + 2*$z2 + 3*$z3 + 4*$z4 + 5*$z5 +  6*$z6  + 7*$z7 + 8*$z8 + 9*$z9) modulo 11;
wobei z1 bis z9 die einzelnen Stellen (von links nach rechts) in der ISBN sind.
Wenn die berechnete Zahl mit der letzten Ziffer übereinstimmt, handelt es sich um eine valide ISBN. Hierbei sei noch der Sonderfall erwähnt, dass die Prüfziffer eine 10 sein kann und anstelle dessen dann ein X verwendet wird.

Im PHP-Code sieht das dann so aus:
PHP-Code:
 <?php
      
// als erstes wird die Ziffernfolge in einzelne Zahlen zerlegt:
      
$z1  substr($ISBN01);
      
$z2  substr($ISBN11);
      
$z3  substr($ISBN21);
      
$z4  substr($ISBN31);
      
$z5  substr($ISBN41);
      
$z6  substr($ISBN51);
      
$z7  substr($ISBN61);
      
$z8  substr($ISBN71);
      
$z9  substr($ISBN81);
      
$z10 substr($ISBN91);

      
//dann wird der Sonderfall des X berücksichtigt
      
if(strtoupper($z10) === 'X')
      {
        
$z10 10;
      }

      
// nun wird die Prüfziffer berechnet
      
$pruefziffer = (1*$z1 2*$z2 3*$z3 4*$z4 5*$z5 +  6*$z6  7*$z7 8*$z8 9*$z9)%11;

      
// wenn nun die berechnete Prüfziffer mit der übergebenen Prüfziffer identisch ist, dann handelt es sich um eine valide ISBN
      
if($z10 == $pruefziffer)
      {
        return 
true;
      }
      else
      {
        return 
false// andernfalls gibt die Prüffunktion ein false zurück
      
}
?>
Der Überprüfungsschritt am Ende lässt sich auch noch verkürzen (oben nur für das Verständnis lang ausgeschrieben). Die kurze Form sieht so aus:
PHP-Code:
return $z10 === $pruefziffer
Was passiert hier? Ganz einfach. Wenn die beiden Variablen, als $z13 und $pruefziffer sowohl den gleichen Wert als auch den gleichen Typ haben, dann wird return ein true zurückgeben, andernfalls ein false. Also genau das, was das if-else-Konstrukt auch tut.


Ähnlich geschieht die Überprüfung nun auch bei der ISBN-13, wobei der Sonderfall mit dem X wegfällt und darüber hinaus die Berechnungsformel ein wenig anders aussieht.
PHP-Code:
 <?php
      
// als erstes wird die Ziffernfolge in einzelne Zahlen zerlegt:
      
$z1  substr($ISBN01);
      
$z2  substr($ISBN11);
      
$z3  substr($ISBN21);
      
$z4  substr($ISBN31);
      
$z5  substr($ISBN41);
      
$z6  substr($ISBN51);
      
$z7  substr($ISBN61);
      
$z8  substr($ISBN71);
      
$z9  substr($ISBN81);
      
$z10 substr($ISBN91);
      
$z11 substr($ISBN101);
      
$z12 substr($ISBN111);
      
$z13 substr($ISBN121);

      
// nun wird die Prüfziffer berechnet
      
$pruefziffer = (10-(($z1+$z3+$z5+$z7+$z9+$z11+3*(+$z2+$z4+$z6+$z8+$z10+$z12))%10))%10;

      
// wenn nun die berechnete Prüfziffer mit der übergebenen Prüfziffer identisch ist, dann handelt es sich um eine valide ISBN
      
return $z13 === $pruefziffer;
 
?>
Wenn nun beides in die Funktion eingebaut wird, sieht diese wie folgt aus:

PHP-Code:
 <?php
  
function bISBN($ISBN false)
  {
    
$ISBN str_replace(array(' ''-'), '' $ISBN);

    
// Laenge prüfen
    
if(strlen($ISBN) == 10)
    {
      
// als erstes wird die Ziffernfolge in einzelne Zahlen zerlegt:
      
$z1  substr($ISBN01);
      
$z2  substr($ISBN11);
      
$z3  substr($ISBN21);
      
$z4  substr($ISBN31);
      
$z5  substr($ISBN41);
      
$z6  substr($ISBN51);
      
$z7  substr($ISBN61);
      
$z8  substr($ISBN71);
      
$z9  substr($ISBN81);
      
$z10 substr($ISBN91);

      
//dann wird der Sonderfall des X berücksichtigt
      
if(strtoupper($z10) === 'X')
      {
        
$z10 10;
      }

      
// nun wird die Prüfziffer berechnet
      
$pruefziffer = (1*$z1 2*$z2 3*$z3 4*$z4 5*$z5 +  6*$z6  7*$z7 8*$z8 9*$z9)%11;

      
// wenn nun die berechnete Prüfziffer mit der übergebenen Prüfziffer identisch ist, dann handelt es sich um eine valide ISBN
      
return $z10 === $pruefziffer;
    }
    elseif(
strlen($ISBN) == 13 && is_numeric($ISBN) && (substr($ISBN03) == 978 || substr($ISBN03) == 979))
    {
      
// als erstes wird die Ziffernfolge in einzelne Zahlen zerlegt:
      
$z1  substr($ISBN01);
      
$z2  substr($ISBN11);
      
$z3  substr($ISBN21);
      
$z4  substr($ISBN31);
      
$z5  substr($ISBN41);
      
$z6  substr($ISBN51);
      
$z7  substr($ISBN61);
      
$z8  substr($ISBN71);
      
$z9  substr($ISBN81);
      
$z10 substr($ISBN91);
      
$z11 substr($ISBN101);
      
$z12 substr($ISBN111);
      
$z13 substr($ISBN121);

      
// nun wird die Prüfziffer berechnet
      
$pruefziffer = (10-(($z1+$z3+$z5+$z7+$z9+$z11+3*(+$z2+$z4+$z6+$z8+$z10+$z12))%10))%10;

      
// wenn nun die berechnete Prüfziffer mit der übergebenen Prüfziffer identisch ist, dann handelt es sich um eine valide ISBN
      
return $z13 === $pruefziffer;
    }
    else
    {
      return 
false;
    }
  }
 
?>


Nun noch ein paar ISBN um die Funktionalität zu testen

PHP-Code:
 <?php
  error_reporting
(E_ALL);


  
$ISBN '3442464552';
  echo 
'<br>'.$ISBN.' -> '.((bISBN($ISBN) === true)?'':'nicht ').'valid';

  
$ISBN '3442464555';
  echo 
'<br>'.$ISBN.' -> '.((bISBN($ISBN) === true)?'':'nicht ').'valid';

  
$ISBN '3-442-46455-2';
  echo 
'<br>'.$ISBN.' -> '.((bISBN($ISBN) === true)?'':'nicht ').'valid';

  
$ISBN '978-3-7657-2780-1';
  echo 
'<br>'.$ISBN.' -> '.((bISBN($ISBN) === true)?'':'nicht ').'valid';

  
$ISBN '9783765727801';
  echo 
'<br>'.$ISBN.' -> '.((bISBN($ISBN) === true)?'':'nicht ').'valid';

  
$ISBN '9793765727801';
  echo 
'<br>'.$ISBN.' -> '.((bISBN($ISBN) === true)?'':'nicht ').'valid';

  
$ISBN '9793765727800';
  echo 
'<br>'.$ISBN.' -> '.((bISBN($ISBN) === true)?'':'nicht ').'valid';
 
?>
Wer nun eine ISBN-10 in eine ISBN-13 umwandeln möchte, hat hier alles an Wissen dazu zusammengetragen.
Einfach eine 978 davorstellen und die alte Prüfziffer durch eine neue ersetzen. Fertig.


Solltet Ihr Fragen zu dem Tutorial haben, so schreibt bitte einen Beitrag im PHP-Forum mit einem Verweis auf dieses Tutorial.
Danke.

Ich hoffe, dass ich Euch hier etwas weiterhelfen konnte.

Grüße Jann Hendrik


Nachtrag:
Trotz sorgfältiger Prüfung schleichen sich immer kleinere Fehler ein. Darüber hinaus gibt es auch Programmabschnitte, die man verbessern kann. Ein thread, in welchem derartige Vorschläge zu diesem Tutorial gesammelt werden ist hier verlinkt.

edit:
Ich habe einige der Kritikpunkte verbessert. Andere werden noch geprüft und dann ggf. noch eingearbeitet.

Geändert von Jann Hendrik (18.01.2008 um 09:04 Uhr).
Jann Hendrik ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Antwort

« [PHP] thumbnails erstellen - kleine Funktion | [Server] LAMPP mit ftp, openSSL, msmtp, webalizer und phpmyadmin in einer chroot »

Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)
 
Themen-Optionen

Forumregeln
Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge anzufügen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

vB Code ist An.
Smileys sind An.
[IMG] Code ist An.
HTML-Code ist Aus.
Trackbacks are An
Pingbacks are An
Refbacks are Aus


Alle Zeitangaben in WEZ +2. Es ist jetzt 07:20 Uhr.

Nach oben
Wir nutzen das Zend Framework, vBulletin (vBulletin v3.6.7, Copyright ©2000-2008, Jelsoft Enterprises Ltd.
SEO by vBSEO 3.0.0) und vBSEO.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44