Validate International Securities Identification Number: Difference between revisions

Line 1,102:
AU0000VXGZA3 is valid
FR0000988040 is valid
</pre>
 
=={{header|Phix}}==
Note this (slightly better) version of Luhn() has the reverse() inside it, whereas the original did not.
<lang Phix>function Luhn(string st)
integer s=0, d
st = reverse(st)
for i=1 to length(st) do
d = st[i]-'0'
s += iff(mod(i,2)?d,d*2-(d>4)*9)
end for
return remainder(s,10)=0
end function
function valid_ISIN(string st)
-- returns 1 if valid, else 0/2/3/4.
-- (feel free to return 0 instead of 2/3/4)
if length(st)!=12 then return 2 end if
for i=length(st) to 1 by -1 do
integer ch = st[i]
if ch>='A' then
if ch>'Z' then return 3 end if
st[i..i] = sprintf("%d",ch-55)
elsif i<=2 then
return 4
elsif ch<'0' or ch>'9' then
return 3
end if
end for
return Luhn(st)
end function
 
sequence tests = {"US0378331005", -- valid
"US0373831005", -- not valid The transposition typo is caught by the checksum constraint.
"U50378331005", -- not valid The substitution typo is caught by the format constraint.
"US03378331005", -- not valid The duplication typo is caught by the format constraint.
"AU0000XVGZA3", -- valid
"AU0000VXGZA3", -- valid Unfortunately, not all transposition typos are caught by the checksum constraint.
"FR0000988040"} -- valid
 
constant reasons = {"wrong checksum","valid","wrong length","bad char","wrong country"}
 
for i=1 to length(tests) do
string ti = tests[i]
printf(1,"%s : %s\n",{ti,reasons[valid_ISIN(ti)+1]})
end for</lang>
{{out}}
<pre>
US0378331005 : valid
US0373831005 : wrong checksum
U50378331005 : wrong country
US03378331005 : wrong length
AU0000XVGZA3 : valid
AU0000VXGZA3 : valid
FR0000988040 : valid
</pre>
 
7,806

edits