(phixonline)--> with javascript_semantics sequence d = {tagset(9,0)}, inv = tagset(9,0), p = {tagset(9,0)} for i=1 to 4 do d = append(d,extract(d[$],{2,3,4,5,1,7,8,9,10,6})) end for for i=5 to 8 do d = append(d,reverse(d[-4])) end for d = append(d,reverse(d[1])) inv[2..5] = reverse(inv[2..5]) for i=1 to 7 do p = append(p,extract(p[$],{2,6,8,7,3,9,4,1,10,5})) end for -- alternatively, if you prefer: --constant d = {{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}}, -- inv = {0,4,3,2,1,5,6,7,8,9}, -- p = {{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}} function verhoeff(string n, bool validate=false, show_workings=false) string {s,t} = iff(validate?{n,"Validation"}:{n&'0',"Check digit"}) if show_workings then printf(1,"%s calculations for `%s`:\n", {t, n}) printf(1," i ni p(i,ni) c\n") printf(1,"------------------\n") end if integer c = 0 for i=1 to length(s) do integer ni = s[-i]-'0', pi = p[remainder(i-1,8)+1][ni+1] c = d[c+1][pi+1] if show_workings then printf(1,"%2d %d %d %d\n", {i-1, ni, pi, c}) end if end for integer ch = inv[c+1]+'0' string r = iff(validate?iff(c=0?"":"in")&"correct" :"`"&ch&"`") printf(1,"The %s for `%s` is %s\n\n",{lower(t),n,r}) return ch end function constant tests = {"236", "12345", "123456789012"} for i=1 to length(tests) do bool show_workings = (i<=2) integer ch = verhoeff(tests[i],false,show_workings) assert(verhoeff(tests[i]&ch,true,show_workings)=='0') assert(verhoeff(tests[i]&'9',true,show_workings)!='0') end for