// checksum5.cpp
//
#include "stdafx.h"
#include <iostream>
#include <string>
#include <assert.h>
#include "convert.h"
// Multiplicative Table
unsigned int
M[10][10] = { {0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
{1, 2, 3, 4, 0, 6, 7, 8, 9, 5},
{2, 3, 4, 0, 1, 7, 8, 9, 5, 6},
{3, 4, 0, 1, 2, 8, 9, 5, 6, 7},
{4, 0, 1, 2, 3, 9, 5, 6, 7, 8},
{5, 9, 8, 7, 6, 0, 4, 3, 2 ,1},
{6, 5, 9, 8, 7, 1, 0, 4, 3, 2},
{7, 6, 5, 9, 8, 2, 1, 0, 4, 3},
{8, 7, 6, 5, 9, 3, 2, 1, 0, 4},
{9, 8, 7, 6, 5, 4, 3, 2, 1, 0} };
// Position Table
// Note: Repeats after 8 Rows...
unsigned int
P[8][10] = { {0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
{1, 5, 7, 6, 2, 8, 3, 0, 9, 4},
{5, 8, 0, 3, 7, 9, 6, 1, 4, 2},
{8, 9, 1, 6, 0, 4, 3, 5, 2, 7},
{9, 4, 5, 3, 1, 2, 6, 8, 7, 0},
{4, 2, 8, 6, 5, 7, 3, 9, 0, 1},
{2, 7, 9, 3, 8, 0, 6, 4, 1, 5},
{7, 0, 4, 6, 9, 1, 3, 2, 5, 8} };
// Inverse Table
unsigned int
Inv[] = {0, 4, 3, 2, 1, 5, 6, 7, 8, 9};
int main(int argc, char* argv[])
{
// Check digit should be 7
// Bressoud and Wagon appear to be wrong
// in Computational Number Theory, p. 162
// CNT claims c = 4, Inv( c ) = 1???
// _tstring number = _T("1793");
// Check digit should be 0
// See http://www.answers.com/topic/verhoeff-algorithm
// _tstring number = _T("1428570");
// Check digit should be 8
// See http://www.esb.ie/esbnetworks/mrso/mprn.jsp
_tstring number = _T("1000372996");
_tcout << _T("number: ") << number << endl;
// It's too bad we had to toss out the
// const_reverse_iterator to get this to compile...
// Also, M$ will only give you the ASCII number to the
// TCHAR if: _tcout << *it;
int i = 0, c = 0;
for( _tstring::reverse_iterator it = number.rbegin();
it != number.rend(); it++, i++)
{
// Consume non digits
while( it != number.rend() && false == isdigit( *it ) ) { it++; }
if( it == number.rend() ) { break; }
// c = M[ c ][ P[ i % 8 ][ CharToNumber( *it ) ]];
unsigned int n = CharToNumber( *it );
unsigned int p = P[ i % 8 ][ n ];
c = M[ c ][ p ];
}
c = Inv[ c ];
_tcout << _T("check digit is: ") << c << endl;
return 0;
}