/** * Convert a character at a specified position to an integer value. * * @param character The character to convert * @param leftPos The position of the character in the code, counting from left to right * @param rightPos The position of the character in the code, counting from right to left * @return The integer value of the character * @throws CheckDigitException if character is not alphanumeric */ @Override protected int toInt(char character, int leftPos, int rightPos) throws CheckDigitException { int charValue = Character.getNumericValue(character); // the final character is only allowed to reach 9 final int charMax = rightPos == 1 ? 9 : 35; // CHECKSTYLE IGNORE MagicNumber if (charValue < 0 || charValue > charMax) { throw new CheckDigitException("Invalid Character[" + leftPos + "," + rightPos + "] = '" + charValue + "' out of range 0 to " + charMax); } return charValue; }
/** * Convert an ISBN-10 code to an ISBN-13 code. * <p> * This method requires a valid ISBN-10 with NO formatting * characters. * * @param isbn10 The ISBN-10 code to convert * @return A converted ISBN-13 code or <code>null</code> * if the ISBN-10 code is not valid */ public String convertToISBN13(String isbn10) { if (isbn10 == null) { return null; } String input = isbn10.trim(); if (input.length() != ISBN_10_LEN) { throw new IllegalArgumentException("Invalid length " + input.length() + " for '" + input + "'"); } // Calculate the new ISBN-13 code (drop the original checkdigit) String isbn13 = "978" + input.substring(0, ISBN_10_LEN - 1); try { String checkDigit = isbn13Validator.getCheckDigit().calculate(isbn13); isbn13 += checkDigit; return isbn13; } catch (CheckDigitException e) { throw new IllegalArgumentException("Check digit error for '" + input + "' - " + e.getMessage()); } }
/** * Convert an integer value to a check digit. * <p> * <b>Note:</b> this implementation only handles single-digit numeric values * For non-numeric characters, override this method to provide * integer-->character conversion. * * @param charValue The integer value of the character * @return The converted character * @throws CheckDigitException if integer character value * doesn't represent a numeric character */ protected String toCheckDigit(int charValue) throws CheckDigitException { if (charValue >= 0 && charValue <= 9) { // CHECKSTYLE IGNORE MagicNumber return Integer.toString(charValue); } throw new CheckDigitException("Invalid Check Digit Value =" + + charValue); }
return ean13; } catch (CheckDigitException e) { // Should not happen throw new IllegalArgumentException("Check digit error for '" + ean13 + "' - " + e.getMessage());
/** * Convert a character at a specified position to an integer value. * * @param character The character to convert * @param leftPos The position of the character in the code, counting from left to right * @param rightPos The positionof the character in the code, counting from right to left * @return The integer value of the character * @throws CheckDigitException if character is not alphanumeric */ @Override protected int toInt(char character, int leftPos, int rightPos) throws CheckDigitException { int charValue = Character.getNumericValue(character); // the check digit is only allowed to reach 9 final int charMax = rightPos == 1 ? 9 : MAX_ALPHANUMERIC_VALUE; // CHECKSTYLE IGNORE MagicNumber if (charValue < 0 || charValue > charMax) { throw new CheckDigitException("Invalid Character[" + leftPos + "," + rightPos + "] = '" + charValue + "' out of range 0 to " + charMax); } return charValue; }
assertTrue("Invalid Character[" +i +"]=" + e.getMessage(), e.getMessage().startsWith("Invalid "));
/** * Convert a character at a specified position to an integer value. * <p> * <b>Note:</b> this implementation only handlers values that * Character.getNumericValue(char) returns a non-negative number. * * @param character The character to convert * @param leftPos The position of the character in the code, counting from * left to right (for identifying the position in the string) * @param rightPos The position of the character in the code, counting from * right to left (not used here) * @return The integer value of the character * @throws CheckDigitException if Character.getNumericValue(char) returns a * negative number */ @Override protected int toInt(char character, int leftPos, int rightPos) throws CheckDigitException { int num = Character.getNumericValue(character); if (num < 0) { throw new CheckDigitException("Invalid Character[" + leftPos + "] = '" + character + "'"); } return num; }
/** * Convert an ISBN-10 code to an ISBN-13 code. * <p> * This method requires a valid ISBN-10 with NO formatting * characters. * * @param isbn10 The ISBN-10 code to convert * @return A converted ISBN-13 code or <code>null</code> * if the ISBN-10 code is not valid */ public String convertToISBN13(String isbn10) { if (isbn10 == null) { return null; } String input = isbn10.trim(); if (input.length() != ISBN_10_LEN) { throw new IllegalArgumentException("Invalid length " + input.length() + " for '" + input + "'"); } // Calculate the new ISBN-13 code (drop the original checkdigit) String isbn13 = "978" + input.substring(0, ISBN_10_LEN - 1); try { String checkDigit = isbn13Validator.getCheckDigit().calculate(isbn13); isbn13 += checkDigit; return isbn13; } catch (CheckDigitException e) { throw new IllegalArgumentException("Check digit error for '" + input + "' - " + e.getMessage()); } }
/** * Convert a character at a specified position to an integer value. * <p> * <b>Note:</b> this implementation only handlers numeric values * For non-numeric characters, override this method to provide * character-->integer conversion. * * @param character The character to convert * @param leftPos The position of the character in the code, counting from left to right (for identifiying the position in the string) * @param rightPos The position of the character in the code, counting from right to left (not used here) * @return The integer value of the character * @throws CheckDigitException if character is non-numeric */ protected int toInt(char character, int leftPos, int rightPos) throws CheckDigitException { if (Character.isDigit(character)) { return Character.getNumericValue(character); } throw new CheckDigitException("Invalid Character[" + leftPos + "] = '" + character + "'"); }
return ean13; } catch (CheckDigitException e) { // Should not happen throw new IllegalArgumentException("Check digit error for '" + ean13 + "' - " + e.getMessage());
/** * Calculate the modulus for a code. * * @param code The code to calculate the modulus for. * @return The modulus value * @throws CheckDigitException if an error occurs calculating the modulus * for the specified code */ private int calculateModulus(String code) throws CheckDigitException { String reformattedCode = code.substring(4) + code.substring(0, 4); // CHECKSTYLE IGNORE MagicNumber long total = 0; for (int i = 0; i < reformattedCode.length(); i++) { int charValue = Character.getNumericValue(reformattedCode.charAt(i)); if (charValue < 0 || charValue > MAX_ALPHANUMERIC_VALUE) { throw new CheckDigitException("Invalid Character[" + i + "] = '" + charValue + "'"); } total = (charValue > 9 ? total * 100 : total * 10) + charValue; // CHECKSTYLE IGNORE MagicNumber if (total > MAX) { total = total % MODULUS; } } return (int)(total % MODULUS); }
/** * Calculate the checksum. * * @param code The code to calculate the checksum for. * @param includesCheckDigit Whether the code includes the Check Digit or not. * @return The checksum value * @throws CheckDigitException if the code contains an invalid character (i.e. not numeric) */ private int calculateChecksum(String code, boolean includesCheckDigit) throws CheckDigitException { int checksum = 0; for (int i = 0; i < code.length(); i++) { int idx = code.length() - (i + 1); int num = Character.getNumericValue(code.charAt(idx)); if (num < 0 || num > 9) { // CHECKSTYLE IGNORE MagicNumber throw new CheckDigitException("Invalid Character[" + i + "] = '" + ((int)code.charAt(idx)) + "'"); } int pos = includesCheckDigit ? i : i + 1; checksum = D_TABLE[checksum][P_TABLE[pos % 8][num]]; // CHECKSTYLE IGNORE MagicNumber } return checksum; }
/** * Calculate a Verhoeff <i>Check Digit</i> for a code. * * @param code The code to calculate the Check Digit for * @return The calculated Check Digit * @throws CheckDigitException if an error occurs calculating * the check digit for the specified code */ @Override public String calculate(String code) throws CheckDigitException { if (code == null || code.length() == 0) { throw new CheckDigitException("Code is missing"); } int checksum = calculateChecksum(code, false); return Integer.toString(INV_TABLE[checksum]); }
/** * Calculate the modulus for an SEDOL code. * * @param code The code to calculate the modulus for. * @param includesCheckDigit Whether the code includes the Check Digit or not. * @return The modulus value * @throws CheckDigitException if an error occurs calculating the modulus * for the specified code */ @Override protected int calculateModulus(String code, boolean includesCheckDigit) throws CheckDigitException { if (code.length() > POSITION_WEIGHT.length) { throw new CheckDigitException("Invalid Code Length = " + code.length()); } return super.calculateModulus(code, includesCheckDigit); }
/** * Calculate the modulus for an ISIN code. * * @param code The code to calculate the modulus for. * @param includesCheckDigit Whether the code includes the Check Digit or not. * @return The modulus value * @throws CheckDigitException if an error occurs calculating the modulus * for the specified code */ @Override protected int calculateModulus(String code, boolean includesCheckDigit) throws CheckDigitException { StringBuilder transformed = new StringBuilder(code.length() * 2); if (includesCheckDigit) { char checkDigit = code.charAt(code.length()-1); // fetch the last character if (!Character.isDigit(checkDigit)){ throw new CheckDigitException("Invalid checkdigit["+ checkDigit+ "] in " + code); } } for (int i = 0; i < code.length(); i++) { int charValue = Character.getNumericValue(code.charAt(i)); if (charValue < 0 || charValue > MAX_ALPHANUMERIC_VALUE) { throw new CheckDigitException("Invalid Character[" + (i + 1) + "] = '" + charValue + "'"); } // this converts alphanumerics to two digits // so there is no need to overload toInt() transformed.append(charValue); } return super.calculateModulus(transformed.toString(), includesCheckDigit); }
/** * Calculate the <i>Check Digit</i> for an IBAN code. * <p> * <b>Note:</b> The check digit is the third and fourth * characters and is set to the value "<code>00</code>". * * @param code The code to calculate the Check Digit for * @return The calculated Check Digit as 2 numeric decimal characters, e.g. "42" * @throws CheckDigitException if an error occurs calculating * the check digit for the specified code */ @Override public String calculate(String code) throws CheckDigitException { if (code == null || code.length() < MIN_CODE_LEN) { throw new CheckDigitException("Invalid Code length=" + (code == null ? 0 : code.length())); } code = code.substring(0, 2) + "00" + code.substring(4); // CHECKSTYLE IGNORE MagicNumber int modulusResult = calculateModulus(code); int charValue = (98 - modulusResult); // CHECKSTYLE IGNORE MagicNumber String checkDigit = Integer.toString(charValue); return (charValue > 9 ? checkDigit : "0" + checkDigit); // CHECKSTYLE IGNORE MagicNumber }
/** * Calculate an ISBN-10 or ISBN-13 check digit, depending * on the length of the code. * <p> * If the length of the code is 9, it is treated as an ISBN-10 * code or if the length of the code is 12, it is treated as an ISBN-13 * code. * * @param code The ISBN code to validate (should have a length of * 9 or 12) * @return The ISBN-10 check digit if the length is 9 or an ISBN-13 * check digit if the length is 12. * @throws CheckDigitException if the code is missing, or an invalid * length (i.e. not 9 or 12) or if there is an error calculating the * check digit. */ @Override public String calculate(String code) throws CheckDigitException { if (code == null || code.length() == 0) { throw new CheckDigitException("ISBN Code is missing"); } else if (code.length() == 9) { // CHECKSTYLE IGNORE MagicNumber return ISBN10_CHECK_DIGIT.calculate(code); } else if (code.length() == 12) { // CHECKSTYLE IGNORE MagicNumber return ISBN13_CHECK_DIGIT.calculate(code); } else { throw new CheckDigitException("Invalid ISBN Length = " + code.length()); } }
/** * Calculate the modulus for a code. * * @param code The code to calculate the modulus for. * @param includesCheckDigit Whether the code includes the Check Digit or not. * @return The modulus value * @throws CheckDigitException if an error occurs calculating the modulus * for the specified code */ protected int calculateModulus(String code, boolean includesCheckDigit) throws CheckDigitException { int total = 0; for (int i = 0; i < code.length(); i++) { int lth = code.length() + (includesCheckDigit ? 0 : 1); int leftPos = i + 1; int rightPos = lth - i; int charValue = toInt(code.charAt(i), leftPos, rightPos); total += weightedValue(charValue, leftPos, rightPos); } if (total == 0) { throw new CheckDigitException("Invalid code, sum is zero"); } return total % modulus; }
/** * Calculate a modulus <i>Check Digit</i> for a code which does not yet have one. * * @param code The code for which to calculate the Check Digit; * the check digit should not be included * @return The calculated Check Digit * @throws CheckDigitException if an error occurs calculating the check digit */ @Override public String calculate(String code) throws CheckDigitException { if (code == null || code.length() == 0) { throw new CheckDigitException("Code is missing"); } int modulusResult = calculateModulus(code, false); int charValue = (modulus - modulusResult) % modulus; return toCheckDigit(charValue); }
/** * Convert an integer value to a check digit. * <p> * <b>Note:</b> this implementation only handles single-digit numeric values * For non-numeric characters, override this method to provide * integer-->character conversion. * * @param charValue The integer value of the character * @return The converted character * @throws CheckDigitException if integer character value * doesn't represent a numeric character */ protected String toCheckDigit(int charValue) throws CheckDigitException { if (charValue >= 0 && charValue <= 9) { // CHECKSTYLE IGNORE MagicNumber return Integer.toString(charValue); } throw new CheckDigitException("Invalid Check Digit Value =" + + charValue); }