public static int getNumericValue(final int ch) { final int val = getProperties(ch); int retval = -1; switch (val & 0xC00) { case (0x00000000): // not numeric retval = -1; break; case (0x00000400): // simple numeric retval = ch + ((val & 0x3E0) >> 5) & 0x1F; break; case (0x00000800): // "strange" numeric retval = -2; break; case (0x00000C00): // Java supradecimal retval = (ch + ((val & 0x3E0) >> 5) & 0x1F) + 10; break; default: // cannot occur retval = -1; break; } return retval; }
/** * 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 = CharacterGetNumericValue.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; }
/** * 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 */ protected int toInt(char character, int leftPos, int rightPos) throws CheckDigitException { int charValue = CharacterGetNumericValue.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 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 CharacterGetNumericValue.getNumericValue(character); } throw new CheckDigitException("Invalid Character[" + leftPos + "] = '" + character + "'"); }
/** * 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 = CharacterGetNumericValue.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; }
/** * Convert a character at a specified position to an integer value. * <p> * <b>Note:</b> this implementation only handlers values that * CharacterGetNumericValue.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 CharacterGetNumericValue.getNumericValue(char) returns a * negative number */ @Override protected int toInt(char character, int leftPos, int rightPos) throws CheckDigitException { int num = CharacterGetNumericValue.getNumericValue(character); if (num < 0) { throw new CheckDigitException("Invalid Character[" + leftPos + "] = '" + character + "'"); } return num; }
/** * 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 = CharacterGetNumericValue.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 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 = CharacterGetNumericValue.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); }