Skip to content

Instantly share code, notes, and snippets.

@mwgamera
Created July 8, 2011 22:55
Show Gist options
  • Save mwgamera/1073024 to your computer and use it in GitHub Desktop.
Save mwgamera/1073024 to your computer and use it in GitHub Desktop.
Implementation of Verhoeff scheme adapted to aplhanumeric data
/* Group operation in D18 (precomputed) */
static int d18_op[36][36] = {
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35},
{ 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17, 0,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,18},
{ 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17, 0, 1,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,18,19},
{ 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17, 0, 1, 2,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,18,19,20},
{ 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17, 0, 1, 2, 3,22,23,24,25,26,27,28,29,30,31,32,33,34,35,18,19,20,21},
{ 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17, 0, 1, 2, 3, 4,23,24,25,26,27,28,29,30,31,32,33,34,35,18,19,20,21,22},
{ 6, 7, 8, 9,10,11,12,13,14,15,16,17, 0, 1, 2, 3, 4, 5,24,25,26,27,28,29,30,31,32,33,34,35,18,19,20,21,22,23},
{ 7, 8, 9,10,11,12,13,14,15,16,17, 0, 1, 2, 3, 4, 5, 6,25,26,27,28,29,30,31,32,33,34,35,18,19,20,21,22,23,24},
{ 8, 9,10,11,12,13,14,15,16,17, 0, 1, 2, 3, 4, 5, 6, 7,26,27,28,29,30,31,32,33,34,35,18,19,20,21,22,23,24,25},
{ 9,10,11,12,13,14,15,16,17, 0, 1, 2, 3, 4, 5, 6, 7, 8,27,28,29,30,31,32,33,34,35,18,19,20,21,22,23,24,25,26},
{10,11,12,13,14,15,16,17, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,28,29,30,31,32,33,34,35,18,19,20,21,22,23,24,25,26,27},
{11,12,13,14,15,16,17, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,29,30,31,32,33,34,35,18,19,20,21,22,23,24,25,26,27,28},
{12,13,14,15,16,17, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,30,31,32,33,34,35,18,19,20,21,22,23,24,25,26,27,28,29},
{13,14,15,16,17, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,31,32,33,34,35,18,19,20,21,22,23,24,25,26,27,28,29,30},
{14,15,16,17, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,32,33,34,35,18,19,20,21,22,23,24,25,26,27,28,29,30,31},
{15,16,17, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,33,34,35,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32},
{16,17, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,34,35,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33},
{17, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,35,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34},
{18,35,34,33,32,31,30,29,28,27,26,25,24,23,22,21,20,19, 0,17,16,15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1},
{19,18,35,34,33,32,31,30,29,28,27,26,25,24,23,22,21,20, 1, 0,17,16,15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2},
{20,19,18,35,34,33,32,31,30,29,28,27,26,25,24,23,22,21, 2, 1, 0,17,16,15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3},
{21,20,19,18,35,34,33,32,31,30,29,28,27,26,25,24,23,22, 3, 2, 1, 0,17,16,15,14,13,12,11,10, 9, 8, 7, 6, 5, 4},
{22,21,20,19,18,35,34,33,32,31,30,29,28,27,26,25,24,23, 4, 3, 2, 1, 0,17,16,15,14,13,12,11,10, 9, 8, 7, 6, 5},
{23,22,21,20,19,18,35,34,33,32,31,30,29,28,27,26,25,24, 5, 4, 3, 2, 1, 0,17,16,15,14,13,12,11,10, 9, 8, 7, 6},
{24,23,22,21,20,19,18,35,34,33,32,31,30,29,28,27,26,25, 6, 5, 4, 3, 2, 1, 0,17,16,15,14,13,12,11,10, 9, 8, 7},
{25,24,23,22,21,20,19,18,35,34,33,32,31,30,29,28,27,26, 7, 6, 5, 4, 3, 2, 1, 0,17,16,15,14,13,12,11,10, 9, 8},
{26,25,24,23,22,21,20,19,18,35,34,33,32,31,30,29,28,27, 8, 7, 6, 5, 4, 3, 2, 1, 0,17,16,15,14,13,12,11,10, 9},
{27,26,25,24,23,22,21,20,19,18,35,34,33,32,31,30,29,28, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0,17,16,15,14,13,12,11,10},
{28,27,26,25,24,23,22,21,20,19,18,35,34,33,32,31,30,29,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0,17,16,15,14,13,12,11},
{29,28,27,26,25,24,23,22,21,20,19,18,35,34,33,32,31,30,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0,17,16,15,14,13,12},
{30,29,28,27,26,25,24,23,22,21,20,19,18,35,34,33,32,31,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0,17,16,15,14,13},
{31,30,29,28,27,26,25,24,23,22,21,20,19,18,35,34,33,32,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0,17,16,15,14},
{32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,35,34,33,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0,17,16,15},
{33,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,35,34,15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0,17,16},
{34,33,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,35,16,15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0,17},
{35,34,33,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}
};
/* Inverse element in D18 */
static int d18_inv[36] = {
0,17,16,15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1,
18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35
};
/* Permutation */
static int P[] = {
29,0,32,11,35,20,7,27,2,4,19,28,30,1,5,12,3,9,16,
22,6,33,8,24,26,21,14,10,34,31,15,25,17,13,23,18
};
/* Apply n-th composition of the permutation */
static int perm(int x, int n) {
n %= 600;
while (n--)
x = P[x];
return x;
}
/* Translate from alphanumeric ASCII to 0-36 integers */
static int ascii2int(char x) {
return (x & 0xF0) == 0x30 ? x - '0' : x - 'A' + 10;
}
/* Translate from integers to alphanumeric ASCII characters */
static char ascii[] = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
};
static char int2ascii(int x) {
return ascii[x];
}
/* Compute checksum, correct if zero */
int ver36_check(char *data, int len) {
int i = 0, c = 0;
while (len--)
c = d18_op[c][perm(ascii2int(data[len]),i++)];
return c;
}
/* Replace last character with correct check digit */
int ver36_insert(char *data, int len) {
int i, c = 0;
for (i = 1; i < len; i++)
c = d18_op[c][perm(ascii2int(data[len-i-1]), i)];
c = d18_inv[c];
data[len-1] = int2ascii(c);
return c;
}
#include <stdio.h>
#include <ctype.h>
#include <string.h>
static int filteralnum(char *str) {
int i = 0;
char *p = str;
while (*p) {
if (isalnum(*p))
str[i++] = toupper(*p);
p++;
}
str[i] = '\0';
return i;
}
int main(int argc, char **argv) {
for (--argc, ++argv; argc--; argv++) {
int len = filteralnum(*argv);
if (ver36_check(*argv, len)) {
printf("%s WRONG ", *argv);
ver36_insert(*argv, len);
printf("CORRECT IS %s\n", *argv);
}
else
printf("%s OK\n", *argv);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment