PHP校验ISBN码的函数

日期: 标签:php
如需帮忙改代码,或者WordPress二次开发、PHP网站建设等需求,可联系我购买付费服务:  点此联系我

    最近在编写一个图书管理程序的时候,需要校验图书ISBN码正确性,查了一些资料,了解了图书ISBN码的构成,详细资料可以参考:国际标准书号 - 维基百科,下面还是简述一下什么是ISBN码:

国际标准书号(International Standard Book Number,ISBN;拟发音is-ben),是国际通用的图书或独立的出版物(除定期出版的期刊)代码。出版社可以通过国际标准书号清晰的辨认所有非期刊书籍。一个国际标准书号只有一个或一份相应的出版物与之对应。新版本如果在原来旧版的基础上没有内容上太大的变动,在出版时也不会得到新的国际标准书号码。当平装本改为精装本出版时,原来相应的国际标准书号号码也应当收回。

    平常我们能够见到的ISBN码有10位和13位两种,其中10位的ISBN自2007年1月起已经停止使用,目前新出版的图书ISBN码都是13位。考虑到一个严谨的图书管理程序要考虑到多方面的问题,因为10位ISBN码的图书还是有巨大的存世量的,所以要校验图书ISBN码的正确性,就必须同时考虑10位和13位的情况。从维基百科可以了解到ISBN码最后一位是校验码,其实要想校验ISBN码的正确,就是通过计算ISBN的校验码,看是否与最后一位吻合。这里所说的校验也只是校验ISBN在构成上是否合法,而不会校验是否为已发行图书的ISBN。下面是维基百科提供的ISBN码校验算法:

校验码的计算方法(10码)

  1. 假设某国际标准书号号码前9位是:7-309-04547
  2. 计算加权和S:S = 7×10+3×9+0×8+9×7+0×6+4×5+5×4+4×3+7×2 = 226
  3. 计算S÷11的余数M:M = 226 mod 11 = 6
  4. 计算11 - M 的差N:N = 11 − 6 = 5
    • 如果N = 10,校验码是字母"X"
    • 如果N = 11,校验码是数字"0"
    • 如果N为其他数字,校验码是数字N

    所以,本书的校验码是5;如果用户提供的ISBN码是7-309-04547-6,那么校验失败

校验码的计算方法(13码)

  1. 假设某国际标准书号号码前12位是:978-986-181-728
  2. 计算加权和S:S = (9x1)+(7x3)+(8x1)+(9x3)+(8x1)+(6x3)+(1x1)+(8x3)+(1x1)+(7x3)+(2x1)+(8x3) = 164
  3. 计算S÷10的余数M:M = 164 mod 10 = 4
  4. 计算10 - M 的差N:N = 10 − 4 = 6
    • 如果N = 10,校验码是数字"0"
    • 如果N为其他数字,校验码是数字N

    所以,本书的校验码是6。完整的国际标准书号号码为 ISBN 978-986-181-728-6

    好了,背景知识介绍到这,下面我写的ISBN码校验函数(php版),需要的话可以直接使用:

/**
 * 名称: PHP校验ISBN码的函数
 * 作者:露兜
 * 博客:https://www.ludou.org/
 * 最后修改:2010年09月26日
 */

function isbn_sum($isbn, $len)
{
/* 
 * 该函数用于计算ISBN加权和 
 * 参数说明:
 *   $isbn : isbn码
 *   $len  : isbn码长度
 */
	$sum = 0;
	
	if ($len == 10)
	{
		for ($i = 0; $i < $len-1; $i++)
		{
			$sum = $sum + (int)$isbn[$i] * ($len - $i);
		}
	}
	elseif ($len == 13)
	{
		for ($i = 0; $i < $len-1; $i++)
		{
			if ($i % 2 == 0)
				$sum = $sum + (int)$isbn[$i];
			else
				$sum = $sum + (int)$isbn[$i] * 3;
		}
	}
	return $sum;
}

function isbn_compute($isbn, $len)
{
/* 
* 该函数用于计算ISBN末位校验码
* 参数说明:
*   $isbn : isbn码
*   $len  : isbn码长度
*/

	if ($len == 10)
	{
		$digit = 11 - isbn_sum($isbn, $len) % 11;

		if ($digit == 10)
			$rc = 'X';
		else if ($digit == 11)
			$rc = '0';
		else
			$rc = (string)$digit;
	}
	else if($len == 13)
	{
		$digit = 10 - isbn_sum($isbn, $len) % 10;

		if ($digit == 10)
			$rc = '0';
		else
			$rc = (string)$digit;
	}

	return $rc;
}

function is_isbn($isbn)
{
/* 
 * 该函数用于判断是否为ISBN号 
 * 参数说明:
 *    $isbn : isbn码
 */
	$len = strlen($isbn);

	if ($len!=10 && $len!=13)
		return 0;

	$rc = isbn_compute($isbn, $len);

	if ($isbn[$len-1] != $rc)	/* ISBN尾数与计算出来的校验码不符 */
		return 0;
	else
		return 1;
}

    函数写好后,就可以直接调用了,下面是调用示例:

<?php echo is_isbn('9787507421781') ? '校验通过' : '校验失败'; ?>

    另外我写了一个在线校验ISBN的工具,使用该工具可以在线校验ISBN码的合法性,可以点击以下链接使用:ISBN码在线校验工具

-- 完 --

本文采用 「CC BY-NC-SA 4.0」创作共享协议,转载请标注以下信息:
原文出处:露兜即刻 https://www.ludou.org/php-check-isbn.html
露兜
kaapass@outlook.com  QQ 825533758

业余编程爱好者。

12 条留言

点此留言
  1. 安徽吉诺 安徽吉诺

    这样的技术要经常分享撒

  2. 400电话 400电话

    要不段的学习 进步 努力 加油

  3. 翎羽志 翎羽志

    不懂

  4. 李道然 李道然

    不懂PHP

  5. 书香阁 书香阁

    php文盲哦 呵呵。。

  6. WordPress啦 WordPress啦

    这些东东还真是过复杂的啊,学习了

  7. 好东西分享 好东西分享

    留着,这个东西以后可能会用的上!

  8. Firm Firm

    额,这个是啥,上课的时候还真的没学到过

  9. Ludou

    @Firm 并不是所有东西都能从课堂上学到的

  10. 个人简介 个人简介

    确实是不错~~~~~~

  11. WordPress啦 WordPress啦

    这个函数没有使用过,了解了。。

  12. hui hui

    2008年的NOIP,全国计算机学会出的一道题,教会了选手们神马是ISBN- -这道题正好就是要验证ISBN的- –

发表留言