• Validität von ISBN kontrollieren

    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.
  • Neue Blog-Einträge

    Adventure-PHP-Framework 1.12 erschienen

    Ich bin bisher nicht dazu gekommen - und wollte eigentlich die beiden links nennen: :arrow: http://www.golem.de/1008/77097.html :arrow:...

    20.08.2010 16:09

    Britische Regierung hält am IE6 fest

    Man könnte auch sagen "Tot erhoffte leben länger" :arrow: http://www.golem.de/1008/77035.html Leider sind halt in vielen Unternehmen speziell an den IE angepasste Programme im Einsatz, die es...

    20.08.2010 16:12

    Hosting-Dienst GitHub erreicht Millionen-Marke

    Während ich persönlich noch immer gerne SVN einsetze, ist git gerade voll im Trend. GitHub hatte die Tage zu vermelden, dass es mehr als eine Million Softwareprojekte "unter seinem Dach" hat....

    20.08.2010 16:15

    Screenshot unter Windows vom aktiven Fenster erstellen

    Der Trend, nicht nur einen Bildschirm bei der Arbeit am PC zu verwenden ist imho vorhanden. Wer - wie ich - gerne zwischendurch einen screenshot macht, der dürfte sich ggf. manches Mal geärgert...

    20.08.2010 16:20

    ListView-Spalten Automatisch ausrichten

    Listviews begegnen uns eigentlich jeden Tag aufs neue bei der täglichen Arbeit. Genauso oft nervt es, wenn man z.b. im Explorer Spalten verschieben muss, um einen Dateinamen einer Datei vollständig...

    24.08.2010 13:10
  • Neue Beiträge

    Sekundentakt

    Hi,

    ich weiß nicht genau, wie Deine Subselects aussehen. Aber falls die sich so ähnlich formulieren lassen:

    Code:
    SELECT something
    

    CONCAT_WS mit LEFT JOIN

    Sekundentakt 01.09.2010 15:30 Gehe zum letzten Beitrag
    DasMööp

    *ohje ... Antwort: Subselect *rolleye, damit fällt dann der JOIN weg.

    CONCAT_WS mit LEFT JOIN

    DasMööp 31.08.2010 13:29 Gehe zum letzten Beitrag
    DasMööp

    Hallo,

    bei einer Abfrage von zwei Tabellen ist in einer in zwei Spalten je die ID der einen hinterlegt und diese brauche ich in der CONCAT.

    CONCAT_WS mit LEFT JOIN

    DasMööp 31.08.2010 12:17 Gehe zum letzten Beitrag
    floppy

    Hallo DEVWinC, Hallo Spezialisten,

    ich stehe zur Zeit auf dem gleichen Problem, bei mir gibts beim BartPE (XP) nur einen BlueScreen nach

    [Booten] ISO-Images mit Bootloader starten & BartPE

    floppy 31.08.2010 10:48 Gehe zum letzten Beitrag

Impressum · Tutorials · Nutzungsbedingungen · thematisch sortierte Linklisten · Spendenaufruf · Team · Partnerprojekte

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 45 46 47 48