Eclectica Daybreak over Colburne Passage near Sidney, BC, Canada filler
shim shim shim shim
shim Home shim Software shim Avocations shim Services  
shim shim shim shim
Software
shim
shim
Documentation
 SSL Certificates
 OpenBSD RAID
 Self-Check Digits
 Bare Metal Reload
shim
Linux
 popbsmtpd
      Reference
      Installation
      Changelog
      FAQ
      Mailing Lists
      Download
shim
 Postfix
shim
 EnGarde
shim
iSeries
 CPYTOIFSF
 FTP Backup
shim
Windows
shim
shim

Modulus 11 Self-Check Digits

Some numbers are more important to get right during data entry than others.

In transaction processing applications, transposing or mis-typing digits in account numbers can result in applying debits or credits to the wrong person's account.

To reduce the possibility of such mistakes, account numbers can be crafted in such a way that simple errors are detected. This is done by calculating a single-digit value based on the account number, and then appending that digit to the base number to arrive at a final account number. When this account number is entered, the check digit value is stripped off and recalculated. If the supplied value does not match the recalculated value, the account number is rejected.

One common scheme for generating self-check digits, described here, is called Modulus 11 Self-Check. There are various versions of this, which differ in the weightings used; this document describes the one used by IBM on the iSeries (formerly AS/400, System/38) and in the 5250 series of terminal devices.

Each digit in the base number is assigned a multiplication factor. The factors are assigned from right to left, starting at two and counting up. For numbers longer than six digits, the factors restart at two after seven is reached. The product of each digit and its factor is calculated, and the products summed, as follows:


Base number :  1    6    7    7    0    3    6    2    5
Factor  . . :  4    3    2    7    6    5    4    3    2
             ---  ---  ---  ---  ---  ---  ---  ---  ---
               4 + 18 + 14 + 49 +  0 + 15 + 24 +  6 + 10 = 140

The sum of the products is divided by the prime number 11. The remainder is inspected, and:

  • if the remainder is zero, the check digit is also zero.
  • if the remainder is one, the check digit is ambiguous, and the base number should not be used as an account number.
  • for all others, the remainder is subtracted from 11. The result is the check digit.

To continue the example, 140 divided by 11 is 12, with a remainder of 8. 11 minus 8 is 3, so 3 is the modulus 11 check digit for 167703625.


Divide sum of products by 11 : 140 / 11 =  12   remainder   8
Confirm  . . . . . . . . . . :  12 * 11 = 132   140 - 132 = 8
Subtract remainder from 11 . :  11 -  8 =   3

The self-checking account number becomes 1677036253.

Examples of the validation procedure:


Acct #  Base   ?  Sum of Products                   Remainder Ck Digit OK
------  -----  -  -------------------------------- ---------- -------- ---
010006  01000  6  0x6 + 1x5 + 0x4 + 0x3 + 0x2 =  5   5/11 r=5 11-5 = 6 Yes
010022  01002  2  0x6 + 1x5 + 0x4 + 0x3 + 2x2 =  9   9/11 r=9 11-9 = 2 Yes
010057  01005  7  0x6 + 1x5 + 0x4 + 0x3 + 5x2 = 15  15/11 r=4 11-4 = 7 Yes
010066  01006  6  0x6 + 1x5 + 0x4 + 0x3 + 6x2 = 17  17/11 r=6 11-6 = 5 NO
010091  01009  1  0x6 + 1x5 + 0x4 + 0x3 + 9x2 = 23  23/11 r=1 --n/a--- NO

The simple modulus 11 self-check digit calculator below demonstrates the results obtained by the above algorithm:

Check Digit Calculator

Starting number (max 16 digits) :  
Number to generate (max 128) :

The PHP code that implements this calculator:


/* Append modulus 11 check digit to supplied string of digits. */
function GenMOD11( $base_val )
{
   $result = "";
   $weight = array( 2, 3, 4, 5, 6, 7,
                    2, 3, 4, 5, 6, 7,
                    2, 3, 4, 5, 6, 7,
                    2, 3, 4, 5, 6, 7 );

   /* For convenience, reverse the string and work left to right. */
   $reversed_base_val = strrev( $base_val );
   for ( $i = 0, $sum = 0; $i < strlen( $reversed_base_val ); $i++ )
   {
      /* Calculate product and accumulate. */
      $sum += substr( $reversed_base_val, $i, 1 ) * $weight[ $i ];
   }

   /* Determine check digit, and concatenate to base value. */
   $remainder = $sum % 11;
   switch ( $remainder )
   {
   case 0:
      $result = $base_val . 0;
      break;
   case 1:
      $result = "n/a";
      break;
   default:
      $check_digit = 11 - $remainder;
      $result = $base_val . $check_digit;
      break;
   }

   return $result;
}


shim