Created
July 18, 2011 06:09
-
-
Save mwgamera/1088656 to your computer and use it in GitHub Desktop.
Alphanumeric derivative of Verhoeff check digit in javascript.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var Ver36 = function() { | |
"use strict"; | |
var N = 18, N2 = N*2; | |
var d18_op; // D18 group operation table | |
var d18_inv; // D18 group inverse | |
var perm; // the permutation decomposed into cycles | |
var a2i,i2a; // ASCII translation tables | |
var NA=0xff; // invalid digit marker in ASCII table | |
// initialization code | |
(function() { | |
var A8 = typeof Uint8Array != 'undefined' ? Uint8Array : Array; | |
// prepare Cayley table for D18 group | |
d18_op = new A8(N2*N2); | |
var i, j; | |
for (i = 0; i < N; i++) | |
for (j = 0; j < N; j++) | |
d18_op[N2*i+j] = (i + j) % N; | |
for (i = 0; i < N; i++) | |
for (j = N; j < N2; j++) | |
d18_op[N2*i+j] = N + (i + j) % N; | |
for (i = N; i < N2; i++) | |
for (j = 0; j < N; j++) | |
d18_op[N2*i+j] = N + (i - j) % N; | |
for (i = N; i < N2; i++) | |
for (j = N; j < N2; j++) | |
d18_op[N2*i+j] = (N + i - j) % N; | |
// prepare inverse element table | |
d18_inv = new A8(N2); | |
d18_inv[0] = 0; | |
for (i = 1; i < N; i++) | |
d18_inv[i] = N - i; | |
for (i = N; i < N2; i++) | |
d18_inv[i] = i; | |
// decompose permutation cycles | |
perm = new Array(N2); | |
var p = [ // the permutation | |
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 | |
], b = new A8(N2); // assert p.length == N2 | |
i = 0; | |
while (i < b.length) { | |
var h = [null], c = h, l = 0; | |
while (!b[i]) { | |
var cc = [null, p[i]]; | |
c[0] = cc; c = cc; | |
b[i] = true; | |
i = p[i]; | |
l++; | |
} | |
c[0] = h[0]; | |
for (var j = 0; j < l; j++) { | |
var pp = perm[c[1]] = new A8(l); | |
for (var k = 0; k < l; k++) { | |
pp[k] = c[1]; | |
c = c[0]; | |
} | |
c = c[0]; | |
} | |
for (i = 0; i < b.length && b[i]; i++) {} | |
} | |
// set up translation tables | |
a2i = new A8(256); | |
for (i = 0; i < a2i.length; i++) a2i[i] = NA; | |
for (i = 0x30; i < 0x3a; i++) a2i[i] = i - 0x30; | |
for (i = 0x41; i < 0x5b; i++) a2i[i] = i - 0x41 + 10; | |
for (i = 0x61; i < 0x7b; i++) a2i[i] = i - 0x61 + 10; | |
i2a = new A8(N2); | |
for (i = 0; i < 10; i++) i2a[i] = i + 0x30; | |
for (i = 10; i < N2; i++) i2a[i] = i + 0x41 - 10; | |
})(); | |
// group operation | |
var op = function(i, j) { | |
return d18_op[N2*i+j]; | |
} | |
// compute n-th application of the permutation | |
var nperm = function(i, n) { | |
return perm[i][n % perm[i].length]; | |
} | |
// verify correctness of check digit | |
var verify = function(str) { | |
var i = 0, c = 0, l = str.length; | |
while (l--) { | |
var ch = a2i[str.charCodeAt(l) & 0xff]; | |
if (ch != NA) | |
c = op(c,nperm(ch,i++)); | |
} | |
return c; | |
} | |
// Create new check digit | |
var create = function(str) { | |
var i = 1, c = 0, l = str.length; | |
while (l--) { | |
var ch = a2i[str.charCodeAt(l) & 0xff]; | |
if (ch != NA) | |
c = op(c,nperm(ch,i++)); | |
} | |
return i2a[d18_inv[c]]; | |
} | |
// Append check digit to given string | |
var append = function(str) { | |
return str + String.fromCharCode(create(str)); | |
} | |
// export functions | |
return { | |
'verify': verify, | |
'create': create, | |
'append': append | |
}; | |
}(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var Ver36=function(){"use strict";function n(c){for(var a=1,b=0,f=c.length;f--;){var d=g[c.charCodeAt(f)&255];d!=255&&(d=l[d][a++%l[d].length],b=h[36*b+d])}return k[i[b]]}var h,i,l,g,k;(function(){var c=typeof Uint8Array!="undefined"?Uint8Array:Array;h=new c(1296);var a,b;for(a=0;a<18;a++)for(b=0;b<18;b++)h[36*a+b]=(a+b)%18;for(a=0;a<18;a++)for(b=18;b<36;b++)h[36*a+b]=18+(a+b)%18;for(a=18;a<36;a++)for(b=0;b<18;b++)h[36*a+b]=18+(a-b)%18;for(a=18;a<36;a++)for(b=18;b<36;b++)h[36*a+b]=(18+a-b)%18;i= | |
new c(36);i[0]=0;for(a=1;a<18;a++)i[a]=18-a;for(a=18;a<36;a++)i[a]=a;l=Array(36);var f=[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],d=new c(36);for(a=0;a<d.length;){for(var e=b=[null],m=0;!d[a];){var j=[null,f[a]],e=e[0]=j;d[a]=!0;a=f[a];m++}e[0]=b[0];for(b=0;b<m;b++){a=l[e[1]]=new c(m);for(j=0;j<m;j++)a[j]=e[1],e=e[0];e=e[0]}for(a=0;a<d.length&&d[a];a++);}g=new c(256);for(a=0;a<g.length;a++)g[a]=255;for(a=48;a<58;a++)g[a]=a-48;for(a=65;a< | |
91;a++)g[a]=a-65+10;for(a=97;a<123;a++)g[a]=a-97+10;k=new c(36);for(a=0;a<10;a++)k[a]=a+48;for(a=10;a<36;a++)k[a]=a+65-10})();return{verify:function(c){for(var a=0,b=0,f=c.length;f--;){var d=g[c.charCodeAt(f)&255];d!=255&&(d=l[d][a++%l[d].length],b=h[36*b+d])}return b},create:n,append:function(c){return c+String.fromCharCode(n(c))}}}(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
http://tumblr.mwgamera.name/post/7395866808/alphanumeric-verhoeff-algorithm