今天看了蝈蝈俊.net的公司同事李玉卿提供的图书条形码跟ISBN号互相转换算法。一文,折腾一阵之后,贴出源代码:
using System;
using System.Text.RegularExpressions;namespace BarCode
{
/// <summary>
/// Summary description for BarCode2ISBN.
/// </summary>
public class BarCode2ISBN
{
public BarCode2ISBN()
{
//
// TODO: Add constructor logic here
//
}
#region ISBN_BarCode
//条码 转 ISBN:
//条码示例:9787508027104 前三位978(中国)
// 1. 除去前三位及最后一位(4),剩下7 5 0 8 0 2 7 1 0(A)
// 2. 高位 -> 低位(分别乘以10,9,8..3,2),即7*10,5*9,0*8...1*3,0*2。
// 3. 求和:70 45 0 56 0 10 28 3 0 = 212;
// 4. 和除以11: 212 % 11 余3
// 5. 余数3取11的补数:11 - 3 = 8;(8即为校验位)
// 注:当余数为0时,校验位为 0,余数为1时,补数为10,此时用符号X代替。
// 6. 结果ISBN的书号为:A值加检验位8,即得:7 5 0 8 0 2 7 1 0 8
public string BarCodeToISBN(string barCode)
{
if(barCode.Length != 13) return string.Empty;
if(!Regex.IsMatch(barCode, @"/d{13}")) return string.Empty;
string coreCode = barCode.Substring(3, 9);
int sum = 0;
for(int i = 10; i >= 2; i--)
{
sum += i * Convert.ToInt32(coreCode.Substring(10 - i,1));
}
string checkCode = null;
if(sum % 11 == 0)
{
checkCode = "0";
}
else if(sum % 11 == 1)
{
checkCode = "X";
}
else
{
checkCode = (11 - (sum % 11)).ToString();
}
return coreCode + checkCode;
}
//ISBN 转 条码:
//示范数据:7-5080-2710-8
// 1. 去掉末尾校验码8,前面统一加上978(中国),为:978750802710
// 2. 从代码位置序号2开始,所有偶数位的数字代码求和为a, 7 + 7 + 0 + 0 + 7 + 0 = 21
// 3. 将a乘以3为a, 21 * 3 = 63
// 4. 从代码位置序号1开始,所有奇数位的数字代码求和为b,9 + 8 + 5 + 8 + 2 + 1 = 33
// 5. 将a和b相加为c, 63 + 33 = 96
// 6. 取c的个位数d。 个位:6
// 7. 用10减去d即为校验位数值,将它置于最后一位。10 - 6 = 4
// 8. 条形码为:9 7 8 7 5 0 8 0 2 7 1 0 4
public string ISBNToBarCode(string isbnCode)
{
isbnCode = isbnCode.Replace("-", string.Empty);
if(isbnCode.Length != 10) return string.Empty;
if(!Regex.IsMatch(isbnCode, @"/d{10}")) return string.Empty;
string coreCode = isbnCode.Substring(0, 9);
string chinaIsbnCode = "978";
string tmpCode = chinaIsbnCode + coreCode;
int sumOddNumber = 0;//奇数和
int sumEvenNumber = 0;//偶数和
for(int i = 0; i < 11; i++)
{
if( (i + 1) % 2 == 1)
{
sumOddNumber += Convert.ToInt32(tmpCode.Substring(i, 1));
}
else
{
sumEvenNumber += Convert.ToInt32(tmpCode.Substring(i, 1));
}
} int sum = sumOddNumber + sumEvenNumber * 3;
string checkCode = null;
if(sum % 10 == 0)
{
checkCode = "0";
}
else
{
checkCode = (10 - (sum % 10)).ToString();
} return tmpCode + checkCode;
}
#endregion
}
}
贴两张图吧:
运行时的样子:
保存结果:
暂时不太清楚转换为ISBN书号时,其中“-”的规则。
哪位大侠知道,望告知。谢谢!
后来一位网友提供了ISBN书号“-”的规则代码,不过是Java写的,也贴在这里吧:
package com.libwan.utils;
public class ToISBN {
public static String toisbn(String isbn){
if(isbn.indexOf("-")!=-1||isbn.length()!=13)return isbn; //如果包含-或不是13位,则返回
String newstr=isbn.substring(3, isbn.length()-1);
int sum=0;
for(int i=0,j=10;i<newstr.length();i++,j--){
int a=Integer.parseInt(newstr.substring(i,i+1));
sum=sum+a*j;
}
int b=11-sum%11; //得到校验位
String c=toisbn2(newstr+b);
//System.out.println(c);
return c;
}
public static String toisbn2(String srcISBN){
String retISBN = srcISBN;
if(srcISBN.charAt(1) != '-')
{
switch(srcISBN.charAt(1))
{
case '0':
retISBN = srcISBN.charAt(0)
+ "-"
+ srcISBN.charAt(1)
+ srcISBN.charAt(2)
+ "-"
+ srcISBN.charAt(3)
+ srcISBN.charAt(4)
+ srcISBN.charAt(5)
+ srcISBN.charAt(6)
+ srcISBN.charAt(7)
+ srcISBN.charAt(8)
+ "-"
+ srcISBN.charAt(9);
break;
case '1':
case '2':
case '3':
retISBN = srcISBN.charAt(0)
+ "-"
+ srcISBN.charAt(1)
+ srcISBN.charAt(2)
+ srcISBN.charAt(3)
+ "-"
+ srcISBN.charAt(4)
+ srcISBN.charAt(5)
+ srcISBN.charAt(6)
+ srcISBN.charAt(7)
+ srcISBN.charAt(8)
+ "-"
+ srcISBN.charAt(9);
break;
case '5':
retISBN = srcISBN.charAt(0)
+ "-"
+ srcISBN.charAt(1)
+ srcISBN.charAt(2)
+ srcISBN.charAt(3)
+ srcISBN.charAt(4)
+ "-"
+ srcISBN.charAt(5)
+ srcISBN.charAt(6)
+ srcISBN.charAt(7)
+ srcISBN.charAt(8)
+ "-"
+ srcISBN.charAt(9);
break;
case '4':
case '8':
retISBN = srcISBN.charAt(0)
+ "-"
+ srcISBN.charAt(1)
+ srcISBN.charAt(2)
+ srcISBN.charAt(3)
+ srcISBN.charAt(4)
+ srcISBN.charAt(5)
+ "-"
+ srcISBN.charAt(6)
+ srcISBN.charAt(7)
+ srcISBN.charAt(8)
+ "-"
+ srcISBN.charAt(9);
break;
case '7'://add Wang .CD or DVD more
retISBN = srcISBN.charAt(0)
+ "-"
+ srcISBN.charAt(1)
+ srcISBN.charAt(2)
+ srcISBN.charAt(3)
+ srcISBN.charAt(4)
+ "-"
+ srcISBN.charAt(5)
+ srcISBN.charAt(6)
+ srcISBN.charAt(7)
+ srcISBN.charAt(8)
+ "-"
+ srcISBN.charAt(9);
break;
default:
retISBN = srcISBN;
break;
}
}
return retISBN;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println(toisbn("9787030154224"));
}}
(我已记不清是哪位网友提供的了,所以无法给出其BLOG链接。在此,谨向这位热心网友致谢!)
谁有空将它转成C#版本吧,如果可能,发一份转换后的版本给我。[Email: a3news(at)hotmail.com ]
相关参考文章:
Interlib支持ISBN扩升至13位 http://www.interlib.com.cn/tcsoft/plugin/office/news/2006/12/30/1167455500935.html
转贴两个链接:
13位ISBN的校验位计算方法 将13位图书条码转换为ISBN-10(2007年以前图书)的方法
为方便,就直接贴出内容来吧:
13位ISBN的校验位计算方法(模数10 余数 0-9 差数 1-10 校验位:0-9)
[作者:lnpusky]
13位ISBN校验位改变了10位ISBN的计算方法,采用奇数偶数位算法,模数也改为10,所以新的ISBN中将不出现X校验码。13位ISBN的最后一位数字为校验位,数值范围由0至9,其计算方法如下 :
(1) 用1分别乘书号的前12位中的奇数位, 用3乘以偶数位:(位数从左到右为13位到2位)
(2) 将各乘积相加,求出总和 ;
(3) 将总和除以10,得出余数;
(4) 将10减去余数后即为校验位。如相减后的数值为10,校验位则为0。
/** <summary>
/// ISBN-10位转换成ISBN-13位方法
/// </summary>
/// <param name="Isbn10">ISBN-10编号</param>
/// <returns>ISBN-13编号</returns>
public static string GetIsbn13(string Isbn10)
{
if (Isbn10.Length == 10)
{
string Location13 = "9";
string Location12 = "7";
string Location11 = "8";
string Location10 = Isbn10.Substring(0,1);
string Location09 = Isbn10.Substring(1, 1);
string Location08 = Isbn10.Substring(2, 1);
string Location07 = Isbn10.Substring(3, 1);
string Location06 = Isbn10.Substring(4, 1);
string Location05 = Isbn10.Substring(5, 1);
string Location04 = Isbn10.Substring(6, 1);
string Location03 = Isbn10.Substring(7, 1);
string Location02 = Isbn10.Substring(8, 1); int IsbnSUM = Convert.ToInt16(Location13) + Convert.ToInt16(Location11) + Convert.ToInt16(Location09) + Convert.ToInt16(Location07) + Convert.ToInt16(Location05) + Convert.ToInt16(Location03) + (Convert.ToInt16(Location12) + Convert.ToInt16(Location10) + Convert.ToInt16(Location08) + Convert.ToInt16(Location06) + Convert.ToInt16(Location04) + Convert.ToInt16(Location02)) * 3;
string Location01 =Convert.ToString((10 - IsbnSUM % 10)%10);
string Isbn13 = Location13 + Location12 + Location11 + Location10 + Location09 + Location08 + Location07 + Location06 + Location05 + Location04 + Location03 + Location02 + Location01;
return Isbn13;
}
else
{
return null;
}
}
将13位图书条码转换为ISBN-10(2007年以前图书)的方法[作者:lnpusky]
/** <summary>
/// 2007年前图书13条码转换成ISBN-10位方法
/// </summary>
/// <param name="Isbn13">13位条形码</param>
/// <returns>10位isbn编号</returns>
public static string GetISBN10(string Isbn13)
{
if ( Isbn13.Length == 13 )
{
string Location4 = Isbn13.Substring(3 , 1);
string Location5 = Isbn13.Substring(4 , 1);
string Location6 = Isbn13.Substring(5 , 1);
string Location7 = Isbn13.Substring(6 , 1);
string Location8 = Isbn13.Substring(7 , 1);
string Location9 = Isbn13.Substring(8 , 1);
string Location10 = Isbn13.Substring(9, 1);
string Location11 = Isbn13.Substring(10, 1);
string Location12 = Isbn13.Substring(11 , 1);
string location13 = Isbn13.Substring(11 , 1);
int loc12 = Convert.ToInt16(Location12);
int loc11 = Convert.ToInt16(Location11);
int loc10 = Convert.ToInt16(Location10);
int loc9 = Convert.ToInt16(Location9);
int loc8 = Convert.ToInt16(Location8);
int loc7 = Convert.ToInt16(Location7);
int loc6 = Convert.ToInt16(Location6);
int loc5 = Convert.ToInt16(Location5);
int loc4 = Convert.ToInt16(Location4);
int isbnSum =10 -( loc4 * 10 + loc5 * 9 + loc6 * 8 + loc7 * 7 + loc8 * 6 + loc9 * 5 + loc10 * 4 + loc11 * 3 + loc12 * 2)%11;
if ( isbnSum == 0 )
{
location13 = "0";
}
else
{
if ( isbnSum == 1 )
{
location13 = "X";
}
else
{
isbnSum = 11 - isbnSum;
location13 = isbnSum.ToString();
}
}
return Location4 + Location5 + Location6 + Location7 + Location8 + Location9 + Location10 + Location11 + Location12 + location13;
}
}
顺向lnpusky致谢!