Checksum an ISBN
From CodeCodex
[edit] Implementations
import std.stdio, std.string;
/// Checks if the passed string is a valid ISBN number.
bool isISBN(string isbn) {
if (isbn.length != 10 ||
isbn[0 .. 9].countchars("^0-9") ||
inPattern(isbn[9], "^0-9xX"))
return false;
int sum;
foreach(i, c; isbn[0 .. $-1])
sum += (10 - i) * (c - '0');
int checksum = (11 - (sum % 11)) % 11;
if (isbn[9] == 'X' || isbn[9] == 'x')
return checksum == 10;
else
return checksum == (isbn[9] - '0');
}
unittest {
string ok = "031234161X 0525949488 076360013X 0671027360 0803612079
0307263118 0684856093 0767916565 0071392319 1400032806 0765305240";
foreach(code; ok.split())
assert(isISBN(code));
string bad = "0312341613 052594948X 0763600138 0671027364 080361207X 0307263110
0684856092 0767916567 0071392318 1400032801 0765305241 031234161
076530Y241 068485609Y";
foreach(code; bad.split())
assert(!isISBN(code));
writefln("Unittest of isISBN() passed.");
}
/**
* An ISBN Utility
* @author Julius Schorzman
* (C) 2006 -- Provided under GPL
*/
public class ISBNUtil {
/**
* Checks if the passed string is a valid ISBN number.
* @param isbn The ISBN String
* @return true if it is a valid isbn; false in all other cases.
*/
public static boolean isISBN(String isbn) {
try {
if (isbn.length() != 10) {
return false;
}
int weight = 10;
int rollingSum = 0;
for ( int i = 0 ; i < 9 ; i++ ) {
int isbnDigit = Character.digit(isbn.charAt(i), 10);
rollingSum += isbnDigit * weight--;
}
int mod = rollingSum % 11;
mod = 11 - mod;
if ( mod == 11 ) mod = 0;
char checkSum = isbn.charAt(9);
if (Character.toLowerCase(checkSum) == 'x') {
if ( mod == 10 ) return true;
} else {
if (Character.digit(checkSum, 10) == mod) return true;
}
return false;
} catch (Exception e) {
return false;
}
}
public static void main(String[] args) {
System.out.println("true: "+ISBNUtil.isISBN("031234161X"));
System.out.println("true: "+ISBNUtil.isISBN("0525949488"));
System.out.println("true: "+ISBNUtil.isISBN("076360013X"));
System.out.println("true: "+ISBNUtil.isISBN("0671027360"));
System.out.println("true: "+ISBNUtil.isISBN("0803612079"));
System.out.println("true: "+ISBNUtil.isISBN("0307263118"));
System.out.println("true: "+ISBNUtil.isISBN("0684856093"));
System.out.println("true: "+ISBNUtil.isISBN("0767916565"));
System.out.println("true: "+ISBNUtil.isISBN("0071392319"));
System.out.println("true: "+ISBNUtil.isISBN("1400032806"));
System.out.println("true: "+ISBNUtil.isISBN("0765305240"));
System.out.println("false: "+ISBNUtil.isISBN("0312341613"));
System.out.println("false: "+ISBNUtil.isISBN("052594948X"));
System.out.println("false: "+ISBNUtil.isISBN("0763600138"));
System.out.println("false: "+ISBNUtil.isISBN("0671027364"));
System.out.println("false: "+ISBNUtil.isISBN("080361207X"));
System.out.println("false: "+ISBNUtil.isISBN("0307263110"));
System.out.println("false: "+ISBNUtil.isISBN("0684856092"));
System.out.println("false: "+ISBNUtil.isISBN("0767916567"));
System.out.println("false: "+ISBNUtil.isISBN("0071392318"));
System.out.println("false: "+ISBNUtil.isISBN("1400032801"));
System.out.println("false: "+ISBNUtil.isISBN("0765305241"));
}
}
[edit] Python
def isISBN(isbn):
"""Checks if the passed string is a valid ISBN number."""
if len(isbn) != 10 or not isbn[:9].isdigit():
return False
if not (isbn[9].isdigit() or isbn[9].lower() == "x"):
return False
tot = sum((10 - i) * int(c) for i, c in enumerate(isbn[:-1]))
checksum = (11 - tot % 11) % 11
if isbn[9] == 'X' or isbn[9] == 'x':
return checksum == 10
else:
return checksum == int(isbn[9])
ok = """031234161X 0525949488 076360013X 0671027360 0803612079
0307263118 0684856093 0767916565 0071392319 1400032806 0765305240"""
for code in ok.split():
assert isISBN(code)
bad = """0312341613 052594948X 0763600138 0671027364 080361207X 0307263110
0684856092 0767916567 0071392318 1400032801 0765305241 031234161
076530Y241 068485609Y"""
for code in bad.split():
assert not isISBN(code)
print "Tests of isISBN()passed."