[sci.math] The 12121 check digit algorithm

ken@aiai.ed.ac.uk (Ken Johnson) (12/28/89)

A few months ago there was a conversation about check digit algorithms
in these groups, and I mentioned the `12121' algorithm.  I've recently
had cause to implement the damn thing in `C', having last done it in
Cobol in about 1972 when the Examine command was the latest thing! So
here are the relevant procedures.  I expect that for most applications
you should change `int' to `long' throughout. 


------------ cut here 8< ---------------------------------------------------

/*
 * The 12121 check digit algorithm. This version Ken Johnson, AIAI,
 * Edinburgh University, 1989. You may freely use, modify or copy
 * this code, declaim it in public houses or paint it on walls.
 * But if you sell it at a profit, I want a share please.
 * 
 * Supply_check_digit returns a number which is the supplied argument
 * shifted left a place, with the check digit inserted on the left hand
 * end. (Decimal, not binary, e.g. 192 --> 1922)
 * 
 * checks returns 1 or 0 depending on whether the input number ends in
 * the correct digit or not. In any `real' system you should also check
 * the sign and the number of digits, by adding a test at the
 * beginning that says `if (number < 1000 || number > 9999) {return(0)}'
 * 
 * check_digit_for computes and returns the check digit for a given number,
 * the number having first been stripped of any check digit.
 * How it works: Assume the number has the digits abcde. Then add together
 * a+c+e+2*b+2*d. To that total add 1 if b>=5 and another 1 if d>=5. The
 * check digit is that total modulo 10.
 * 
 *  $$ Good Luck $$
 */

int supply_check_digit(number)
int number;
{
	int check_digit_for( );

	return((number * 10) + check_digit_for(number));
}

checks(number)
int number;
{
	int check_digit_for( );

	return ((number % 10) == check_digit_for(number/10) ? 1 : 0);
}

static int check_digit_for(number)
int number;
{
	int check = 0;

	while (number > 0)
	{
		check += (number % 10);
		number /= 10;

		if (number % 10 >= 5)
		{
			++check;
		}

		check += 2 * (number % 5);
		number /= 10;
	}
	return(check % 10);
}
-- 
Ken Johnson, AI Applications Institute, 80 South Bridge, Edinburgh EH1 1HN
E-mail ken@aiai.ed.ac.uk, phone 031-225 4464 extension 212
`I have read your article, Mr Johnson, and I am no wiser now than when I
started'.  -- `Possibly not, sir, but far better informed.'