GeorgeSayegh
GeorgeSayegh

Reputation: 19

Calculating the ISBN Number check digit using Java

I'm trying to calculate any ISBN-13 Number's Check Digit, I'm not too worried if the ISBN number is valid or invalid, but what I've been trying to do is get the code to work. There are obviously flaws in my interpretation of the algorithm, suggestions on how to fix it are welcome but the primary problem is receiving user input that is too large for an integer variable but I also want to avoid the decimals of the double value.

I already tried to use the BigDecimal and BigNumber but I simply don't have enough experience to be able to understand them completely. This is the algorithm to find d13 (the Check Digit): 10-(d1 +3d2 +d3 +3d4 +d5 +3d6 +d7 +3d8 +d9 +3d10 +d11 +3d12)%10.

The Code is a mess I know. I've used this website as a reference to what I want to do and I've been using this ISBN number as my practice: 9780132130806.

Again my question is how can I print the final ISBN number without decimals and how can I possibly fix my algorithm? (I'd also really appreciate any tips on a website that helps with teaching JOption as that is the prefered method i use because it looks a bit cleaner to me than using the scanner)


import javax.swing.JOptionPane;
import java.math.BigInteger;

public class ISBN
{
    //George Sayegh Calculate check Digit ISBN

    public static void main(String[] args)
    {
    //Define Variables
    double ISBN12, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12 = 0, D13;
    double A = 100000000000L;
    double B = 10000000000L;
    double C = 1000000000;
    double D = 100000000;
    double E = 10000000;
    double F = 1000000;
    double G = 100000;
    double H = 10000;
    double I = 1000;
    double J = 100;
    double K = 10;
    double L = 1;

    //Get ISBN #
    String ISBN12text = JOptionPane.showInputDialog("Please enter the first 12 digits of your ISBN number");
    ISBN12 = Double.parseDouble(ISBN12text);

    //Calculate D1
    D1 = ((ISBN12 - (ISBN12 % A)) / A); 

    //Calculate D2
    D2 = ((ISBN12 - (ISBN12 % B)) / B);

    //Calculate D3
    D3 = ((ISBN12 - (ISBN12 % C)) / C);

    //Calculate D4
    D4 = ((ISBN12 - (ISBN12 % D)) / D);

    //Calculate D5
    D5 = ((ISBN12 - (ISBN12 % E)) / E);

    //Calculate D6
    D6 = ((ISBN12 - (ISBN12 % F)) / F);

    //Calculate D7
    D7 = ((ISBN12 - (ISBN12 % G)) / G);

    //Calculate D8
    D8 = ((ISBN12 - (ISBN12 % H)) / H);

    //Calculate D9
    D9 = ((ISBN12 - (ISBN12 % I)) / J);

    //Calculate D10
    D10 = ((ISBN12 - (ISBN12 % K)) / K);

    //Calculate D11
    D11 = ((ISBN12 - (ISBN12 % L)) / L);

    //Get D13
    D13 = 10 - (D1 + (3 * D2) + D3 + 3 * D4 + D5 + 3 * D6 + D7 + 3 * D8 + D9 + 3 * 10 + D11 + 3 * D12) % 10; 

    JOptionPane.showMessageDialog(null, D1 +""+ D2 +""+ D3 +""+ D4 +""+ D5 +""+ D6 +""+ D7 +""+ D8 +""+ D9 +""+ D10 +""+ D11 +""+ D12 +""+ 13);
    }
}     

Upvotes: 0

Views: 3134

Answers (2)

EvilTak
EvilTak

Reputation: 7579

Try this extremely simple algorithm (written in Python, but it should be very easy to convert to Java). The comments hopefully explain enough. Should convert to not more than 10 lines (not including blank lines for readability)

# Valid ISBN-12 string from user (12 numbers, doesn't matter what other characters)
isbn12 = '978-0-306-40615' # Input it from the user, hardcoded Wikipedia example for testing
coeff = 1 # Multiple used in calculating sum
sum = 0

for d in isbn12: # Equivalent to for(char d : isbn12.toCharArray())
    # this next block is just a tryParse or an isDigit check
    # if the character is a digit, parse it to an int
    # else continue to next iteration
    try:
        # just reassigning the value because-
        # Hey, this is Python!
        d = int(d)
    except ValueError:
        continue

    # Add to sum after multiplying with coeff
    sum += d * coeff
    # If coeff was 1, change to 3 and vice versa
    # Equivalent to coeff == 1 ? 3 : 1 in Java
    coeff = 3 if coeff == 1 else 1
    
# END FOR LOOP

# Get positive number to be added to make ISBN divisible by 10
# The extra % 10 at the end is for changing 10 to 0 without if
check_digit = (10 - sum % 10) % 10

Upvotes: 2

blazs
blazs

Reputation: 4845

Here's a much simpler implementation based on this Wikipedia example. It lacks sanity checks---such as whether the input string is a valid ISBN13---but should be enough to get you going. I hope it helps.

Note that the input is an ISBN-13 string with the check digit removed (e.g. 978013213080 instead of 9780132130806); the program prints the check digit on the output; you should be able modify it if this is not what you want.

public class CheckISBN13 {
    /* We assume isbnString is a *valid* ISBN-13 with the check digit removed.  */
    public static int[] stringToInt(String isbnString) {
        int[] isbnInt = new int[12];
        int j = 0;
        for (int i = 0; i < isbnString.length(); ++i) {
            if (Character.isDigit(isbnString.charAt(i))) {
                isbnInt[j++] = Character.getNumericValue(isbnString.charAt(i));
            }
        }
        return isbnInt;
    }

    public static int getCheckDigit(int[] isbnInt) {
        int val = 0;
        for (int i = 0; i < isbnInt.length; ++i) {
            int coeff = (i % 2 == 0 ? 1 : 3);
            val += coeff * isbnInt[i];
        }
        return 10 - (val % 10);
    }

    public static void main(String[] args) {
        if (args.length < 1) {
            System.err.println("Usage: java CheckISBN13 978-0-306-40615");
            System.exit(-1);
        }
        String isbnString = args[0];
        int[] isbnInt = stringToInt(isbnString);
        System.out.println("Check digit: " + getCheckDigit(isbnInt));
    }
}

Upvotes: 2

Related Questions