公司应用要求,扫图书码之后去搜索图书信息,结果无论使用Zbar还是ZXing,都会出来很多稀奇古怪的数字出来,因此需要手工过滤一下无效ISBN号。于是就有了下文:

开车,同学们!请抓好扶手,我们先来了解一下ISBN号是什么:

国际标准书号(International Standard Book Number),简称ISBN,是专门为识别图书等文献而设计的国际编号。ISO于1972年颁布了ISBN国际标准,并在西柏林普鲁士图书馆设立了实施该标准的管理机构—国际ISBN中心。现在,采用ISBN编码系统的出版物有:图书、小册子、缩微出版物、盲文印刷品等。2007年1月1日前,ISBN由10位数字组成,分四个部分:组号(国家、地区、语言的代号),出版者号,书序号和检验码。2007年1月1日起,实行新版ISBN,新版ISBN由13位数字组成,分为5段,即在原来的10位数字前加上3位EAN(欧洲商品编号[1]  )图书产品代码“978”。在联机书目中ISBN可以作为一个检索字段,从而为用户增加了一种检索途径。

第一组号码是国家代码(State Identifier),最短的是一位数字,最长的达五位数字,大体上兼顾zsdwx、国别和地区。把全世界自愿申请参加国际标准书号体系的国家和地区,划分成若干地区,各有固定的编码:美国所出版的书国家代码为0,1代表英语,使用这两个代码的国家有:澳大利亚、加拿大、爱尔兰、新西兰、波多黎各、南非、英国、美国、津巴布韦等;2代表法语,法国、卢森堡以及比利时、加拿大和瑞士的法语区使用该代码;3代表德语,德国、奥地利和瑞士德语区使用该代码;4是日本出版物的代码;5是俄语系国家出版物的代码;7为中国大陆出版物使用的代码等等。国家领域最长可能为5位数字(如不丹为99936),但相对剩下能使用、分配的位数就较为狭隘。组号分为五个档次,长度为1-5位数字。

第二组号码段 第二组号码是出版社代码(Publisher Identifier),由其隶属的国家或地区ISBN中心分配,允许取值范围为2-5位数字。出版社的规模越大,出书越多,其号码就越短。 第三组号码段 第三组号码是书序码(Title Identifier)由出版社自己给出,而且每个出版社的书序号是定长的(数字9,减去组号、出版社代码所占的位数,就是书序码的位数)。最短的一位,最长的六位。出版社的规模越大,出书越多,书序码越长(如人民文学出版社的出版社代码为02,书序码即为6位,译林出版社代码5447,书序码即为4位)。 第四组号码段 第四组号码是校验码,其数值由前九位数字依次以9~1加权之和并以11为模计算得到。 四组数字之间应该用连字符( – )连接(如2-02-033598-0)。但是,有些图书馆集成系统不能自动分配连字符,图书馆编目人员也对ISBN的分段方式不甚了解,所以人们经常在书目记录中省略 连字符。 —->以上摘自「百度百科」
敲黑板,划重点了!:  示范数据:
9 7 8- 7- 8 1 0 9 0- 0 2 1- ?(?标示 校验位)
代码位置:

13 12 11 10 9 8 7 6 5 4 3 2 1 

除位数1外;所有偶数位的数字代码求和

取末位数为a。将a乘以3 取末位数为b。
 
所有奇数位的数字代码求和取末位数为c。

将b和c相加求和 取末位数为d(因模数为10,所以余数即末位数d)。

用10减去d即为校验位数值。
7+7+1+9+0+1 = 25 取末位数为a=5 5*3 = 15 取末位数为b=5 
9+8+8+0+0+2 = 27 取末位数为c=7 5+7 = 12 
取末位数为d=2 (余数)10-2= 8 差数为校验位: 8 

有效的ISBN 是ISBN 978-7-81090-021-8  上面是我们公司老同事给我的算法,本人凭借自己优秀的数学功底(括弧笑~),稍稍进行了简化,比如  (x%10)*3%10 等效于 x*3%10 (x%10+y%10)%10 等效 (x+y)%10 等等~ 于是自己心动,立马敲代码,得出如下结果 /** * @author franer * @param str_ISBN ISBN numbers * @return true if ISBN is legal,false otherwise * */private static boolean checkISBN(String str_ISBN) {//不满足978开头的13位数字这返回falseif (!Pattern.matches(“978[0-9]{10}”, str_ISBN)) {return false;}int sumOdd = 0;//奇数位总和int sumEvn = 0;//偶数位总和for (int i = 0; i < str_ISBN.length()-1; i++) {if (i%2==0==false) {sumOdd += str_ISBN.charAt(i)-48;//奇数位} else{sumEvn += str_ISBN.charAt(i)-48;//偶数位}}//奇数位总和自乘3sumOdd *= 3;int num13 = 10 – (sumOdd + sumEvn)%10;num13 %= 10;if ((num13+48) == str_ISBN.charAt(str_ISBN.length()-1)) {return true;} else {return false;}}