php 中的 ISBN-10 校验和计算是否正确?
is this ISBN-10 Checksum calculation in php correct?
我找到了一个 PHP 脚本 github ISBN-Calc Routine 来执行 ISBN-10 校验和计算:
<?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;
}
但是 f.e 对于我的 ISBN-10: 0470173424
我得到了 Checksum: 0
这个 github 脚本。
根据 ISBN online checker,校验和应为 4,与 ISBN 中的一样。请问这里有人能给我提供正确的 PHP 程序吗?
谢谢
GitHub 中有一个库:https://github.com/Fale/isbn
有一个函数叫做"Check":
初始化:
$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
您可以从给定的 link 下载库。
也许这有点帮助。
周末愉快!
该函数用于计算 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
If you want to check if the ISBN-10 is correct
验证 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') );
来源:
会显示
1 for true
演示
之前标记的答案接近但不完整。
具体这部分:
$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
我找到了一个 PHP 脚本 github ISBN-Calc Routine 来执行 ISBN-10 校验和计算:
<?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;
}
但是 f.e 对于我的 ISBN-10: 0470173424
我得到了 Checksum: 0
这个 github 脚本。
根据 ISBN online checker,校验和应为 4,与 ISBN 中的一样。请问这里有人能给我提供正确的 PHP 程序吗?
谢谢
GitHub 中有一个库:https://github.com/Fale/isbn
有一个函数叫做"Check":
初始化:
$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
您可以从给定的 link 下载库。
也许这有点帮助。
周末愉快!
该函数用于计算 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
If you want to check if the ISBN-10 is correct
验证 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') );
来源:
会显示
1 for true
演示
之前标记的答案接近但不完整。
具体这部分:
$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