<?xml version="1.0" encoding="UTF-8"?>
<code>
  <code>package net.alessandropetrozzelli;

class InvalidISINCharacterException
    extends Exception {
  InvalidISINCharacterException() {
    super();
  }

  InvalidISINCharacterException(String s) {
    super(s);
  }
}

public class Isin {
  static final int numberTableOffset = '0';
  static final int numberTableEndOffset = '9';
  static final int charTableOffset = 'A';
  static final int charTableEndOffset = 'Z';

  private static int getIntValueForISINChar(final char c) throws
      InvalidISINCharacterException {
    int value = 0;

    if ( (c &gt;= numberTableOffset) &amp;&amp; (c &lt;= numberTableEndOffset)) {
      value = c - numberTableOffset;
    }
    else if ( (c &gt;= charTableOffset) &amp;&amp; (c &lt;= charTableEndOffset)) {
      value = 10 + (c - charTableOffset);
    }
    else {
      throw new InvalidISINCharacterException("Unsupported character: " + c);
    }

    return value;
  }

  private static int getSumOfDigits(final int number) {
    int sumOfDigits=0;
    if (number&lt;=9) {
      sumOfDigits = number;
    } else {
      String s = String.valueOf(number);
      try {
        for (int i = 0; i &lt; s.length(); i++) {
          sumOfDigits += getIntValueForISINChar(s.charAt(i));
        }
      }
      catch (InvalidISINCharacterException ex) {
        System.out.println(ex);
        return -1;
      }
    }
    return sumOfDigits;
  }

  public static int getCheckDigit(final String isin) {
    int checkDigit = 0;

    if ( (isin == null) || (isin.length() != 11)) {
      return -1;
    }
    String incompleteISINcode = isin.toUpperCase();
    StringBuffer buffer = new StringBuffer();

    // convert every single character into number as specified
    try {
      for (int i = 0; i &lt; incompleteISINcode.length(); i++) {
        buffer.append(getIntValueForISINChar(isin.charAt(i)));
      }
    }
    catch (InvalidISINCharacterException ex) {
      System.out.println(ex);
      return -1;
    }

    // sum all digits (multiplying odd digits by 2)
    try {
      for (int i = buffer.length() - 1; i &gt;= 0; i--) {
        if ( (buffer.length() - i) % 2 == 1) {
          checkDigit += getSumOfDigits(getIntValueForISINChar(buffer.charAt(i)) * 2);
        }
        else {
          checkDigit += getIntValueForISINChar(buffer.charAt(i));
        }
      }
    }
    catch (InvalidISINCharacterException ex) {
      // this should never happen
      System.out.println(ex);
      return -1;
    }

    // end result
    checkDigit = (10 - (checkDigit % 10)) % 10;
    return checkDigit;
  }
</code>
  <comment>based on http://en.wikipedia.org/wiki/International_Securities_Identifying_Number</comment>
  <created-at type="datetime">2007-11-07T13:38:08+00:00</created-at>
  <id type="integer">142</id>
  <language>Java</language>
  <permalink>isin-check-digit</permalink>
  <refactors-count type="integer">3</refactors-count>
  <title>ISIN check digit</title>
  <trackback-url>http://blogs.ugidotnet.org/a_petrozzelli/archive/2007/11/07/89507.aspx</trackback-url>
  <updated-at type="datetime">2007-11-12T23:42:15+00:00</updated-at>
  <user-id type="integer">341</user-id>
  <refactors type="array">
    <refactor>
      <code>private static int getIntValueForISINChar(final char c) throws
      InvalidISINCharacterException {

    switch( Character.getType() )
    {
      case DECIMAL_DIGIT_NUMBER : 
        return c - '0';

      case UPPERCASE_LETTER :
        return 10 + (c - 'A');

      default :
        throw new InvalidISINCharacterException("Unsupported character: " + c);
    }

    return 0;
  }</code>
      <code-id type="integer">142</code-id>
      <comment>Just a refactoring for getIntValueForISINChar for now :)</comment>
      <created-at type="datetime">2007-11-08T14:30:05+00:00</created-at>
      <id type="integer">796</id>
      <language>Java</language>
      <rating type="integer">5</rating>
      <ratings-count type="integer">2</ratings-count>
      <title>On ISIN check digit</title>
      <user-id type="integer" nil="true"></user-id>
      <user-name>Vime</user-name>
      <user-website>http://digilander.libero.it/vime78</user-website>
    </refactor>
    <refactor>
      <code></code>
      <code-id type="integer">142</code-id>
      <comment>sorry, Character.getType(c)</comment>
      <created-at type="datetime">2007-11-08T14:54:47+00:00</created-at>
      <id type="integer">797</id>
      <language>Java</language>
      <rating type="integer">5</rating>
      <ratings-count type="integer">1</ratings-count>
      <title>On ISIN check digit</title>
      <user-id type="integer" nil="true"></user-id>
      <user-name>Vime</user-name>
      <user-website></user-website>
    </refactor>
    <refactor>
      <code>package net.alessandropetrozzelli;

public class Isin {

	public static int getCheckDigit(String src) {
		int s = 0;
		int a = (src.length() == 12) ? 1 : 2;
		for (int i = src.length() - 1; i &gt;= 0; i--) {
			int c = src.charAt(i);
			if (c &gt; '9') {
				// Character
				c -= ('A' - 10);
				s += (3 - a) * (c / 10) + a * c + (a - 1) * (c % 10) / 5;
			} else {
				// Number
				c -= '0';
				s += a * c + (a - 1) * (c / 5);
				a = 3 - a;
			}
		}
		s %= 10;
		return (10 - s % 10) % 10;
	}
	
}</code>
      <code-id type="integer">142</code-id>
      <comment>Found on german wikipedia :-p
http://de.wikipedia.org/wiki/International_Securities_Identification_Number

Should check if char &gt; 'Z' ...</comment>
      <created-at type="datetime">2007-11-12T23:42:14+00:00</created-at>
      <id type="integer">839</id>
      <language>Java</language>
      <rating type="integer">1</rating>
      <ratings-count type="integer">1</ratings-count>
      <title>On ISIN check digit</title>
      <user-id type="integer">360</user-id>
      <user-name>olivier.fayau.myopenid.com</user-name>
      <user-website nil="true"></user-website>
    </refactor>
  </refactors>
</code>
