PHP : Convertir un ISBN-10 en EAN-13 (et vice-versa)

Quand on est développeur web et libraire (et un peu nerd sur les bords), on peut se retrouver à faire ce genre de choses : convertir des codes ISBN en code EAN et réciproquement via PHP. Comme je n’ai rien trouvé d’équivalent ailleurs, j’ai du créer ma propre petite fonction. Et comme j’ai pensé qu’elle pouvait à d’autres, je vous en livre le code ci-dessous. Ainsi que quelques interrogations.

(Voir aussi PHP : Convertir un code EAN-13 (sans tirets) en ISBN-13 (avec tirets))

Aujourd’hui, les codes ISBN (qui apparaissent au dos des livres) et les codes EAN (code-barre) sont les mêmes, à la différence des petits tirets des codes ISBN. Pour passer d’un ISBN-13 à un EAN-13, il suffit donc de retirer les tirets en question. Mais pour les livres parus avant janvier 2007, les codes ISBN ne comportaient que 10 chiffres (ISBN-10) dont une clé de contrôle (dernièr caractère) différente de la clé des EAN. Dans les métiers du livre, on a parfois besoin de convertir un ISBN-10 en EAN-13, et il ne suffit malheureusement de virer trois chiffres pour passer de l’un à l’autre : il faut recalculer la clé de contrôle. C’est ce que fait la fonction ci-dessous :

function isbn2ean($x)
{
  $x = str_replace("-","",$x);
  $x = str_replace(" ","",$x);
  if(strlen($x) < 10) $x = $x."X";
  if(strlen($x) == 10) // ISBN10
  {
    $x = substr($x,0,-1);
    $x = "978".$x;
    $code = $x;
    $x = str_split($x);
    $i = 0;
    while($i2 <= 11)
    {
      if($i2%2 == 0) $p = "1";
      else $p = "3";
      $r += $x[$i] * $p;
      if($x[$i] != "-") $i2++;
      $i++;
    }
    $q = floor($r/10);
    $x = 10 - ($r - $q * 10);
    if($x == "10") $x = "0";
    $x = $code.$x;
  }
  return $x;
}

Utilisation :

$ean = isbn2ean("2-913039-18-9"); // retourne 9782913039148

J’ai aussi une fonction qui permet de faire l’inverse, à savoir convertir un EAN en ISBN. Mais cette conversion pose deux problème : d’abord, pas moyen de savoir si l’ISBN correspondant à notre EAN est un code à 10 ou à 13 chiffres sans connaître la date de parution de l’ouvrage (et même, il y a eu quelques cafouillages début 2007). L’autre souci est que le code ISBN se décompose en 4 fragments : A-B-C-D où A est un code correspondant à la langue (2 pour les pays francophones), D est la clé de contrôle, B un code correspondant à l’éditeur et C le numéro du livre chez l’éditeur. Si A et D sont toujours longs d’un caractère, impossible de savoir (à ma connaissance) où se trouve le tiret qui sépare B et C à partir de l’EAN. Cette fonction renvoie donc un ISBN-10 sans tiret.

function ean2isbn($x)
{
  $x = str_replace("-","",$x);
  $x = str_replace(" ","",$x);
  if(strlen($x) == 13)
  {
    $x = substr($x,-10,9);
    $k = str_split($x);
    $m = 10;
    foreach($k as $K)
    {
      $K = $K*$m;
      $t += $K;
      $m--;
    }
    $k = 11 - ($t % 11);
    if(strlen($k) > 1) $k = "X";
    $x = $x.$k;
  }
  return $x;
}

Utilisation

$isbn = ean2isbn("9782913039148"); // retourne 2913039146

Vous pouvez essayer ces deux fonctions ici : http://ext.nokto.net/convert.php

J’étais tombé une fois sur un site (impossible de le retrouver, évidemment) qui proposait un formulaire convertissant un EAN-13 en ISBN avec tirets, mais sans code source. Perso, je ne vois pas comment faire ça sans avoir à disposition une base de données croisant ISBN et EAN. Mais si quelqu’un a une idée, je suis preneur…

5 réflexions au sujet de « PHP : Convertir un ISBN-10 en EAN-13 (et vice-versa) »

  1. Wow, merci ! Ca a bien l’air d’être exactement ce que je cherche. En fait j’étais tombé sur quelque chose comme ça mais je n’avais pas compris que c’était la solution que je cherchais. Par contre, si ça peut m’aider à calculer le bloc éditeur, reste le problème de savoir si l’ISBN était à 10 ou 13 chiffres… enfin c’est déjà ça ! Je reviens vers vous avec une nouvelle fonction dès que j’ai le temps de regarder ça en détail.

  2. Content d’avoir été utile. Ce n’est que justice après avoir eu l’occasion de dégoter plein de beaux livres sur Librys.

    Je n’ai rien trouvé non plus pour différencier ISBN 10 et 13 mais est-ce bien utile ? Tant que l’EAN commence par 978 les deux sont équivalents non ? Sur amazon on peut rechercher indifféremment avec l’un ou l’autre, que les livres datent d’avant ou d’après 2007. Autant rendre hommage à de vieux livres de SF en les convertissant en ISBN 13 dans une BDD.

  3. Bonjour, merci pour ce script que je comptais utiliser mais je n’obtiens pas l’ISBN 10 souhaité à partir d’un EAN 13.
    J’ai utilisé un convertisseur en ligne : http://www.isbn.org/converterpub.as… qui lui me donne le bon ISBN 10 (sans prendre en compte les tirets)

    Ex à partir de l’EAN 13 suivant : 978-2812600333
    votre script => 281260033X
    autre script (cf lien donné) => 2-8126-0033-0
    ce que je souhaitais => 2812600330

    Auriez vous des idées sur cette différence ? Merci d’avance

  4. Bonjour,
    Pour le script, vous parlez du code source de Tellico ? Quand on entre un ISBN dans ce logiciel, il s’occupe tout seul de calculer le dernier chiffre. Et avec 281260033 il trouve bien 0.

    J’ai regardé le code, pour passer d’un ISBN 13 à un ISBN 10 le programme enlève les tirets, enlève 978 et recalcule le dernier chiffre avec l’algo présent dans la fonction checkSum10 du fichier http://websvn.kde.org/trunk/extrage
    Il met pour finir le résultat en forme.

    Avez-vous bien implémenté la fonction en php ? Celle de Tellico est tirée de celle-ci, en javascript et plus lisible à mon sens :

    if (indexisbn.indexOf("978") == 0) {     isbn = isbn.substr(3,9);     var xsum = 0;     var add = 0;     var i = 0;     for (i = 0; i < 9; i++) {         add = isbn.substr(i,1);         xsum += (10 - i) * add;    }    xsum %= 11;    xsum = 11 - xsum;    if (xsum == 10) { xsum = "X"; }    if (xsum == 11) { xsum = "0"; }    isbn += xsum; }

    Cf la page suivante : http://www.eblong.com/zarf/bookscan

    Je l’ai testée avec votre ISBN (ok j’ai triché, j’ai juste fait tourné la boucle sur 281260033), là encore « 0 » est trouvé. Si le mauvais comportement persiste, je peux jeter un œil neuf à votre code si vous le souhaitez.

  5. Merci beaucoup pour votre réponse et votre aide, j’ai donc adapté votre script et cela fonctionne bien :

    function ean2isbn($x)
    {

     $x = str_replace("-","",$x);  $x = str_replace(" ","",$x);  if(strlen($x) == 13)  {    $x = substr($x,-10,9);    $k = str_split($x);    $m = 10;    foreach($k as $K)    {      $K = $K*$m;      $t += $K;      $m--;    }    $k = 11 - ($t % 11);    if ($k == 10) { $k = "X"; }    if ($k == 11) { $k = "0"; }    $x = $x.$k;  }  return $x;

    }

    Bonne continuation :)

Laisser un commentaire