CUSIP Source Code: Difference between revisions
No edit summary  | 
				|||
| Line 73: | Line 73: | ||
     assertFalse(LUHN.isValid("?"));  |      assertFalse(LUHN.isValid("?"));  | ||
   }  |    }  | ||
    public void testCreditCards() {  | |||
        assertTrue(Luhn.isValid("3850074292251725"));  | |||
        assertTrue(Luhn.isValid("4242540460361996"));  | |||
        assertTrue(Luhn.isValid("6030624550510273"));  | |||
        assertTrue(Luhn.isValid(CreateNumber(16)));  | |||
        assertTrue(Luhn.isValid(CreateNumber(13)));  | |||
    }  | |||
    private String CreateNumber(int length) {  | |||
        Random random = new Random();  | |||
        int[] digits = new int[length];  | |||
        for (int i = 0; i < length - 1; i++) {  | |||
            digits[i] = random.nextInt(10);  | |||
        }  | |||
        int sum = 0;  | |||
        boolean alt = true;  | |||
        for (int i = length - 2; i >= 0; i--) {  | |||
            if (alt) {  | |||
                int temp = digits[i];  | |||
                temp *= 2;  | |||
                if (temp > 9) {  | |||
                    temp -= 9;  | |||
                }  | |||
                sum += temp;  | |||
            } else {  | |||
                sum += digits[i];  | |||
            }  | |||
            alt = !alt;  | |||
        }  | |||
        int modulo = sum % 10;  | |||
        if (modulo > 0) {  | |||
            digits[length - 1] = 10 - modulo;  | |||
        }  | |||
        String out = "";  | |||
        for(int n : digits) {  | |||
            out += Integer.toString(n);  | |||
        }  | |||
        return out;  | |||
    }  | |||
}  | }  | ||
</pre>  | </pre>  | ||
Revision as of 04:52, 7 February 2007
Source Code
/**
 * This class impliments the 
 * <a href="http://en.wikipedia.org/wiki/Luhn_formula">LUHN formula</a> in order
 * to check if a <a href="http://en.wikipedia.org/wiki/CUSIP">CUSIP</A>
 * is valid.
 * @author eggebr
 */
public class LUHN {
  public static boolean isValid(String ccNum) {
    char number[] = ccNum.toCharArray();
    int len = number.length;
    int sum = 0;
    for (int i = 0; i < len - 1; i++) {
      int num = mapChar(number[i]);
      // Double all the odd digits
      if (i % 2 != 0)
        num *= 2;
      // Combine digits.  i.e., 16 = (1 + 6) = 7
      if (num > 9)
        num = (num % 10) + (num / 10);
      sum += num;
    }
    int checkDigit = mapChar(number[number.length - 1]);
    
    // This is the mathmatical modulus - not the remainder.  i.e., 10 mod 7 = 3
    int mod = (10 - (sum % 10)) % 10;
    if (mod == checkDigit) {
      return true;
    }
    return false;
  }
  /**
   * Standard & Poor's maps A..Z to 10..35 
   * @param c
   * @return numeric value of the letter
   */
  private static int mapChar(char c) {
    if (c >= '0' && c <= '9')
      return c - '0';
    return c - 'A' + 10;
  }
}
Test case
public class LUHNTest extends TestCase {
  public void testCUSIP() {
    assertTrue(LUHN.isValid("31430F200"));
    assertTrue(LUHN.isValid("037833100")); // Apple
    assertTrue(LUHN.isValid("316549401"));
    assertTrue(LUHN.isValid("022615AC2"));
    assertTrue(LUHN.isValid("931142103")); // Walmart
    assertTrue(LUHN.isValid("883199AQ4"));
    assertTrue(LUHN.isValid("14911QGW5"));
    assertTrue(LUHN.isValid("14911QHM6"));
    assertTrue(LUHN.isValid("339072407"));
    assertTrue(LUHN.isValid("3133XBC78"));
    assertTrue(LUHN.isValid("808905AB9"));
    
    assertFalse(LUHN.isValid("2005"));
    assertFalse(LUHN.isValid("?"));
  }
    public void testCreditCards() {
        assertTrue(Luhn.isValid("3850074292251725"));
        assertTrue(Luhn.isValid("4242540460361996"));
        assertTrue(Luhn.isValid("6030624550510273"));
        assertTrue(Luhn.isValid(CreateNumber(16)));
        assertTrue(Luhn.isValid(CreateNumber(13)));
    }
    private String CreateNumber(int length) {
        Random random = new Random();
        int[] digits = new int[length];
        for (int i = 0; i < length - 1; i++) {
            digits[i] = random.nextInt(10);
        }
        int sum = 0;
        boolean alt = true;
        for (int i = length - 2; i >= 0; i--) {
            if (alt) {
                int temp = digits[i];
                temp *= 2;
                if (temp > 9) {
                    temp -= 9;
                }
                sum += temp;
            } else {
                sum += digits[i];
            }
            alt = !alt;
        }
        int modulo = sum % 10;
        if (modulo > 0) {
            digits[length - 1] = 10 - modulo;
        }
        String out = "";
        for(int n : digits) {
            out += Integer.toString(n);
        }
        return out;
    }
}