public class ISBNUtil {
/**
* 检验字符串是否符合ISBN规范
* @param isbn 输入以“ISBN”开头且可包含若干连接符或空格的字符串
* @return 符合ISBN规范返回true否则返回false
*/
public static boolean verifyISBN(String isbn) {
isbn = isbn.strip();
if (!isbn.startsWith("ISBN")) {
return false;
}
isbn = isbn.replaceAll(" ", "").substring(4).replaceAll("-", "");
if (isbn.length() == 13) {
return verifyISBN13(isbn);
} else if (isbn.length() == 10) {
return verifyISBN10(isbn);
} else {
return false;
}
}
/**
* 10位ISBN号转换为13位ISBN号
* 前加“978”,移除末尾校验位,重新计算校验位
* 计算奇数位的a和加3倍偶数位的和b ==> sum = a + 3 * b
* 计算校验位 c = 10 - sum % 10, c = c == 10 ? 0 : c
* @param isbn 10位的ISBN串
* @return 13位的ISBN串
* @throws Exception 不能转换的Exception
*/
public static String convert10to13(String isbn) throws Exception {
if (!verifyISBN(isbn)) {
throw new Exception("Input is not an ISBN string.");
}
isbn = isbn.strip().replaceAll(" ", "").substring(4).replaceAll("-", "");
if (isbn.length() != 10) {
throw new Exception("Input is not an ISBN-10 string.");
}
isbn = "978" + isbn;
CharSequence chars = isbn.subSequence(0, 12);
int sum = 0;
for (int i = 0; i < chars.length(); i += 2) {
sum += Integer.parseInt(chars, i, i + 1, 10);
}
for (int i = 1; i < chars.length(); i += 2) {
sum += Integer.parseInt(chars, i, i + 1, 10) * 3;
}
int code = 10 - sum % 10;
code = code == 10 ? 0 : code;
return format(chars.toString() + code);
}
/**
* 13位ISBN号转换为10位ISBN号
* 移除前3位及末尾校验位,重新计算校验位
* 设有13位ISBN C1C2C2C4C5C6C7C8C9C10C11C12C13,for(i : 10..2) sum = C4 * i + C5 * i + ... + C12 * i
* 计算校验位 c = 11 - sum % 11,c=0(c==11),c=X(c==10),c=c(else)
* @param isbn 13位的ISBN串
* @return 10位的ISBN串
* @throws Exception 不能转换的Exception
*/
public static String convert13to10(String isbn) throws Exception {
if (!verifyISBN(isbn)) {
throw new Exception("Input is not an ISBN string.");
}
isbn = isbn.strip().replaceAll(" ", "").substring(4).replaceAll("-", "");
if (isbn.length() != 13) {
throw new Exception("Input is not an ISBN-13 string.");
}
CharSequence chars = isbn.subSequence(3, 12);
isbn = chars.toString();
int sum = 0;
for (int i = 0; i < chars.length(); i++) {
sum += Integer.parseInt(chars, i, i + 1, 10) * (10 - i);
}
int code = 11 - sum % 11;
switch (code) {
case 11:
isbn = isbn + "0";
break;
case 10:
isbn = isbn + "X";
break;
default:
isbn = isbn + code;
}
return format(isbn);
}
private static boolean verifyISBN13(String isbn) {
CharSequence chars = isbn.subSequence(0, isbn.length());
int sum = 0;
try {
for (int i = 0; i < chars.length() - 1; i += 2) {
sum += Integer.parseInt(chars, i, i + 1, 10);
}
for (int i = 1; i < chars.length() - 1; i += 2) {
sum += Integer.parseInt(chars, i, i + 1, 10) * 3;
}
} catch (Exception e) {
return false;
}
int code = 10 - sum % 10;
if (code == 10) {
code = 0;
}
return code == Integer.parseInt(chars, 12, 13, 10);
}
private static boolean verifyISBN10(String isbn) {
CharSequence chars = isbn.subSequence(0, isbn.length());
int sum = 0;
try {
for (int i = 0; i < chars.length() - 1; i++) {
sum += Integer.parseInt(chars, i, i + 1, 10) * (10 - i);
}
} catch (Exception e) {
return false;
}
int code = 11 - sum % 11;
if (code == 11) {
code = 0;
}
return code == Integer.parseInt(chars, 9, 10, 10) || (code == 10 && chars.charAt(9) == 'X');
}
/**
* 将纯数字的ISBN串格式化成“ISBN ZZZ-Z-ZZZZ-ZZZZ-Z”或“ISBN Z-ZZZZ-ZZZZ-Z”
* @param isbn 纯数字的ISBN串
* @return 格式化的ISBN串
*/
public static String format(String isbn) {
if (isbn.length() == 10) {
return "ISBN " + isbn.charAt(0) + "-" + isbn.substring(1, 5) + "-" + isbn.substring(5, 9) + "-" + isbn.charAt(9);
} else if (isbn.length() == 13) {
return "ISBN " + isbn.substring(0, 3) + "-" + isbn.charAt(3) + "-" + isbn.substring(4, 8) + "-" + isbn.substring(8, 12) + "-" + isbn.charAt(12);
}
return isbn;
}
}
11-10
3254
![](https://csdnimg.cn/release/blogv2/dist/pc/img/readCountWhite.png)