The Laws of Cryptography:
The IBM Scheme

by Neal R. Wagner

Copyright © 2001 by Neal R. Wagner. All rights reserved.

NOTE: This site is obsolete. See book draft (in PDF):

Here is the "IBM" scheme used for credit card numbers.


// ErrorDetection.java: base class for single-digit error detection
public class ErrorDetection {

   public static void printArray(int[] a) {
      for (int i = 0; i < a.length; i++) {
      	 if (a[i] == 10)
      	    System.out.print("X ");
      	 else
      	    System.out.print(a[i]);
      	 if (i%5 == 0) System.out.print(" ");
      }
      System.out.println();
   }
   
   public static void printUnchecked(int[] a) {
   	  System.out.print("? ");
      for (int i = 1; i < a.length; i++) {
      	 System.out.print(a[i]);
      	 if (i%5 == 0) System.out.print(" ");
      }
      System.out.println();
   }
}

// IbmErrorDetection.java: Implement the "IBM" decimal error detection method public class IbmErrorDetection extends ErrorDetection{ private static int sharp(int d) { return (2*d)/10 + (2*d)%10; } public static int insertCheck(int[] a) { int check = 0; for (int i = 1; i < a.length; i++) if (i%2 == 0) check = (check + a[i])%10; else check = (check + sharp(a[i]))%10; if (check == 0) a[0] = 0; else a[0] = -check + 10; return a[0]; } public static boolean doCheck(int[] a) { int check = 0; for (int i = 0; i < a.length; i++) if (i%2 == 0) check = (check + a[i])%10; else check = (check + sharp(a[i]))%10; if (check != 0) return false; else return true; } // main function public static void main (String[] args) { int[] a = new int[15]; boolean checkFlag = false; for (int i = 1; i < a.length; i++) a[i] = (int)(Math.random() * 10.0); printUnchecked(a); IbmErrorDetection.insertCheck(a); printArray(a); System.out.println(IbmErrorDetection.doCheck(a)); a[4] = (a[4] + 1)%10; IbmErrorDetection.printArray(a); System.out.println(IbmErrorDetection.doCheck(a)); // test all adjacent transpositions System.out.println("\nTest all adjacent transpositions ..."); for (int p1 = 0; p1 < 10; p1++) for (int p2 = 0; p2 < 10; p2++) { if (p1 != p2) { a[8] = p1; a[9] = p2; IbmErrorDetection.insertCheck(a); // interchange a[8] ^= a[9]; a[9] ^= a[8]; a[8] ^= a[9]; if (IbmErrorDetection.doCheck(a)) { System.out.println("Warning: Interchange of " + p1 + " and " + p2 + " not detected"); checkFlag = true; } } } if (checkFlag) System.out.println("At least one transposition undetected"); else System.out.println("All transpositions detected"); } // end of main }

Here is the output, showing a simple test, and a test of all adjacent interchanges. Here interchange errors not caught are 09 and 90.
? 31623 91033 1003
7 31623 91033 1003
true
7 31633 91033 1003
false

Test all adjacent transpositions ...
Warning: Interchange of 0 and 9 not detected
Warning: Interchange of 9 and 0 not detected
At least one transposition undetected