Search code examples
phpisbn

is this ISBN-10 Checksum calculation in php correct?


I have found a PHP script github ISBN-Calc Routine to perform the ISBN-10 checksum calculation:

<?php
/**
 * Calculate ISBN checksum
 * 
 * @param string $isbn
 * @return integer
 */
function isbn_checksum($isbn) {
    $sum = 0; $isbn = str_split(preg_replace('/[^\d]/', '', $isbn));
    foreach($isbn as $key => $z) {
        if($key >= 12) break;
        $sum += ($key % 2) ? $z * 3 : $z;
    }
    $checksum = (10 - $sum % 10);
    return ($checksum == 10) ? 0 : $checksum;
}

But f.e for my ISBN-10: 0470173424 I get Checksum: 0with this github script.

Accoring to ISBN online checker the checksum should be 4 as is it in the ISBN. Can anyone here provide me with the correct PHP routine, please?

Thanks


Solution

  • The previously marked answer is close but incomplete.

    Specifically this portion:

    $check = 11 - ($sum % 11); // This can output 1,2,3,4,5,6,7,8,9,10,11 not 0
    return ($check === 10) ? 'X' : $check; // This is incomplete does not address 11
    

    The code does not deal with the situation where 11 - 0 = 11. I have tried to clarify it below.

    function isbn10($isbn)
    {
      $isbn = preg_replace('/[^\d]/', '', $isbn);
      $digits = str_split(substr($isbn, 0, 9));
    
      $sum = 0;
    
      foreach ($digits as $index => $digit)
      {
          $sum += (10 - $index) * $digit;
      }
    
      $check = 11 - ($sum % 11);
    
      // $check may hold either 10 or 11, but not 0
      // 10 becomes X, 11 becomes 0 -- output is 1 character only
      if ($check == 10)
      {
        $check = 'X';
      }
      elseif ($check == 11)
      {
        $check = '0';
      }
    
      return $check;
    }
    

    An example ISBN where the earlier answer fails is 0134093410