php中的ISBN-10校验和计算正确吗?

时间:2018-07-20 08:14:39

标签: php isbn

我已经找到了执行ISBN-10校验和计算的PHP脚本github ISBN-Calc Routine

<?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;
}

但是我的ISBN-10: 0470173424可以通过这个github脚本得到Checksum: 0

根据ISBN online checker,校验和应为4,与ISBN中的一样。请问有人可以给我提供正确的PHP例程吗?

谢谢

4 个答案:

答案 0 :(得分:2)

该函数用于计算ISBN-13校验位,而不是ISBN-10-这就是为什么它会在第12个字符后中断循环。

ISBN-10的算法不同,要求将数字的前9位数字乘以10到2。该和与下一个11的倍数之间的差是校验位。对于您的示例,这将是:

(10 * 0)+ (9 * 4)+ (8 * 7)+ (7 * 0)+ (6 * 1)+ (5 * 7)+ (4 * 3)+ (3 * 4)+ (2 * 2)= 161

11的下一个倍数是165,因此校验位应为4(如您所说)。如果校验位为10,则使用X。我们可以这样在PHP中建模:

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);

    return ($check === 10) ? 'X' : $check;
}

echo isbn10('047017342');
  

4

您可以在这里看到此方法:https://eval.in/1039654

答案 1 :(得分:1)

先前标记的答案接近但不完整。

特别是这部分:

$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

该代码无法处理11-0 = 11的情况。我试图在下面进行澄清。

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;
}

较早的答案失败的示例ISBN是0134093410

答案 2 :(得分:-1)

有一个来自 GitHub 的库:https://github.com/Fale/isbn

有一个名为“检查” 的功能:

初始化:

$isbn = new Isbn\Isbn();

检查值:(示例)

$isbn->check->is10('888183718'); // Will return false
$isbn->check->is13('9788889527191'); // Will return true
$isbn->check->is13('978888952719'); // Will return false

您可以从给定的链接下载库。

也许有帮助。

周末愉快!

答案 3 :(得分:-1)

  

如果您要检查ISBN-10是否正确

验证ISBN-10

<?php
function isValidIsbn10($isbn) {
    $check = 0;
    for ($i = 0; $i < 10; $i++) {
        if ('x' === strtolower($isbn[$i])) {
            $check += 10 * (10 - $i);
        } elseif (is_numeric($isbn[$i])) {
            $check += (int)$isbn[$i] * (10 - $i);
        } else {
            return false;
        }
    }
    return (0 === ($check % 11)) ? 1 : false;
}

var_dump( isValidIsbn10('0470173424') );

来源:https://stackoverflow.com/a/14096142/5201919

将显示

  

1为真

演示

https://eval.in/1053913