Makistos
10/28/2013 - 7:35 AM

This code will check both ISBN-10 and ISBN-13 codes for validity. String length, characters and check digit are checked. Java regexp cla

This code will check both ISBN-10 and ISBN-13 codes for validity. String length, characters and check digit are checked.

Java regexp class is used, so this is an example on how to use it, too. #isbn #regexp #java

import java.util.regex.*;

/**
 * @brief This class is used to verify that input is a valid ISBN (International
 * Standard Book Number). 
 *
 * @note Invalid ISBN-13 codes have been published in books! Do not assume
 * that just because this returns false for an existing ISBN, there is a bug.
 * Verify with e.g. Amazon that the ISBN is correct first.
 *
 * @author mep
 */
class ISBNChecker {

    /**
     *
     * A valid ISBN 12 digits from 0-9 and the last digit which can be 0-9 or X
     * (which represents ten in the modulo result).
     *
     * @param isbn
     * @return Boolean
     */
    private Boolean checkDigits(String isbn) {

        Pattern pattern = Pattern.compile("^(978|979){0,1}[0-9]{9}[0-9xX]{1}$");
        Matcher matcher = pattern.matcher(isbn);

        return matcher.matches();
    }

    /**
     * @brief This method validates that the check digit in the ISBN (the last
     * digit) matches.
     * 
     * @param isbn The ISBN to check.
     * @return Boolean
     */
    private Boolean validCheckDigit(String isbn) {
        int sum = 0;
        int len = isbn.length();
        Boolean retVal = false;
        int remainder;
        String digit = isbn.substring(len - 1);

        if (len == 10) {
            // ISBN-10 checking
            for (int k = 1; k < len; k++) {
                sum += k * Character.getNumericValue(isbn.charAt(k-1));
            }

            remainder = sum % 11;

            if ((remainder) == 0) {
                if (digit.compareTo("0") == 0) {

                    retVal = true;
                }
            } else if (remainder == 10) {
                if (digit.compareToIgnoreCase("x") == 0) {
                    retVal = true;
                }
            } else {
                if (Integer.parseInt(digit) == remainder) {
                    retVal = true;
                }
            }
            
        } else if (len == 13) {
            // ISBN-13 checking
            int sub;
            for (int k = 1; k <= len; k++) {
                if (k % 2 == 1) {
                    sum += Character.getNumericValue(isbn.charAt(k-1));
                } else {
                    sum += 3 * Character.getNumericValue(isbn.charAt(k-1));
                }
                remainder = sum % 10;
                sub = 10 - remainder;
                remainder = sub % 10;
                if (remainder == 10) {
                    remainder = 0;
                }
                if (Integer.parseInt(digit) == remainder) {
                    retVal = true;
                }
            }
        }
        return retVal;
    }

    /**
     * @brief Checks that the input given is a valid ISBN.
     * 
     * @param str ISBN to check.
     *
     * @return Boolean.
     */
     Boolean check(String str) {
        String isbn;

        /* Remove dashes from the isbn. They do have a meaning but checking
        their validity would be a ridiculous task.*/
        isbn = str.replace("-", "");

        /* Verify that the number part of the ISBN is all numbers and the
         * last digit is either 0-9 or X.
         */
        if (checkDigits(isbn) == false) {
	    return false;
        }
        /* Verify that the check digit is correct */
        if (validCheckDigit(isbn) == false) {
            return false;
        }
    }
}