Checksum an ISBN

From CodeCodex

Contents

[edit] Implementations

[edit] D


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.");
}

[edit] Java


/**
* 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."