Validate International Securities Identification Number: Difference between revisions

Content added Content deleted
m (→‎{{header|Phix}}: syntax coloured)
Line 1,967: Line 1,967:
=={{header|Phix}}==
=={{header|Phix}}==
Note this (slightly better) version of Luhn() has the reverse() inside it, whereas the original did not.
Note this (slightly better) version of Luhn() has the reverse() inside it, whereas the original did not.
<lang Phix>function Luhn(string st)
<!--<lang Phix>(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
integer s=0, d
<span style="color: #008080;">function</span> <span style="color: #000000;">Luhn</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">st</span><span style="color: #0000FF;">)</span>
st = reverse(st)
<span style="color: #004080;">integer</span> <span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">d</span>
for i=1 to length(st) do
<span style="color: #000000;">st</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">reverse</span><span style="color: #0000FF;">(</span><span style="color: #000000;">st</span><span style="color: #0000FF;">)</span>
d = st[i]-'0'
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">st</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
s += iff(mod(i,2)?d,d*2-(d>4)*9)
<span style="color: #000000;">d</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">st</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]-</span><span style="color: #008000;">'0'</span>
end for
<span style="color: #000000;">s</span> <span style="color: #0000FF;">+=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">)?</span><span style="color: #000000;">d</span><span style="color: #0000FF;">,</span><span style="color: #000000;">d</span><span style="color: #0000FF;">*</span><span style="color: #000000;">2</span><span style="color: #0000FF;">-(</span><span style="color: #000000;">d</span><span style="color: #0000FF;">></span><span style="color: #000000;">4</span><span style="color: #0000FF;">)*</span><span style="color: #000000;">9</span><span style="color: #0000FF;">)</span>
return remainder(s,10)=0
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end function
<span style="color: #008080;">return</span> <span style="color: #7060A8;">remainder</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">,</span><span style="color: #000000;">10</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">0</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
function valid_ISIN(string st)
-- returns 1 if valid, else 0/2/3/4.
<span style="color: #008080;">function</span> <span style="color: #000000;">valid_ISIN</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">st</span><span style="color: #0000FF;">)</span>
-- (feel free to return 0 instead of 2/3/4)
<span style="color: #000080;font-style:italic;">-- returns 1 if valid, else 0/2/3/4.
if length(st)!=12 then return 2 end if
-- (feel free to return 0 instead of 2/3/4)</span>
for i=length(st) to 1 by -1 do
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">st</span><span style="color: #0000FF;">)!=</span><span style="color: #000000;">12</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #000000;">2</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
integer ch = st[i]
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">st</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">to</span> <span style="color: #000000;">1</span> <span style="color: #008080;">by</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
if ch>='A' then
<span style="color: #004080;">integer</span> <span style="color: #000000;">ch</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">st</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
if ch>'Z' then return 3 end if
<span style="color: #008080;">if</span> <span style="color: #000000;">ch</span><span style="color: #0000FF;">>=</span><span style="color: #008000;">'A'</span> <span style="color: #008080;">then</span>
st[i..i] = sprintf("%d",ch-55)
<span style="color: #008080;">if</span> <span style="color: #000000;">ch</span><span style="color: #0000FF;">></span><span style="color: #008000;">'Z'</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #000000;">3</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
elsif i<=2 then
<span style="color: #000000;">st</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">..</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"%d"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">-</span><span style="color: #000000;">55</span><span style="color: #0000FF;">)</span>
return 4
<span style="color: #008080;">elsif</span> <span style="color: #000000;">i</span><span style="color: #0000FF;"><=</span><span style="color: #000000;">2</span> <span style="color: #008080;">then</span>
elsif ch<'0' or ch>'9' then
<span style="color: #008080;">return</span> <span style="color: #000000;">4</span>
return 3
<span style="color: #008080;">elsif</span> <span style="color: #000000;">ch</span><span style="color: #0000FF;"><</span><span style="color: #008000;">'0'</span> <span style="color: #008080;">or</span> <span style="color: #000000;">ch</span><span style="color: #0000FF;">></span><span style="color: #008000;">'9'</span> <span style="color: #008080;">then</span>
end if
<span style="color: #008080;">return</span> <span style="color: #000000;">3</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
return Luhn(st)
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end function
<span style="color: #008080;">return</span> <span style="color: #000000;">Luhn</span><span style="color: #0000FF;">(</span><span style="color: #000000;">st</span><span style="color: #0000FF;">)</span>

<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
sequence tests = {"US0378331005", -- valid
"US0373831005", -- not valid The transposition typo is caught by the checksum constraint.
<span style="color: #008080;">constant</span> <span style="color: #000000;">tests</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"US0378331005"</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- valid </span>
"U50378331005", -- not valid The substitution typo is caught by the format constraint.
"US03378331005", -- not valid The duplication typo is caught by the format constraint.
<span style="color: #008000;">"US0373831005"</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- not valid The transposition typo is caught by the checksum constraint.</span>
<span style="color: #008000;">"U50378331005"</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- not valid The substitution typo is caught by the format constraint.</span>
"AU0000XVGZA3", -- valid
"AU0000VXGZA3", -- valid Unfortunately, not all transposition typos are caught by the checksum constraint.
<span style="color: #008000;">"US03378331005"</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- not valid The duplication typo is caught by the format constraint.</span>
<span style="color: #008000;">"AU0000XVGZA3"</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- valid </span>
"FR0000988040"} -- valid
<span style="color: #008000;">"AU0000VXGZA3"</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- valid Unfortunately, not all transposition typos are caught by the checksum constraint.</span>

<span style="color: #008000;">"FR0000988040"</span><span style="color: #0000FF;">},</span> <span style="color: #000080;font-style:italic;">-- valid</span>
constant reasons = {"wrong checksum","valid","wrong length","bad char","wrong country"}

<span style="color: #000000;">reasons</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"wrong checksum"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"valid"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"wrong length"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"bad char"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"wrong country"</span><span style="color: #0000FF;">}</span>
for i=1 to length(tests) do
string ti = tests[i]
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tests</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
printf(1,"%s : %s\n",{ti,reasons[valid_ISIN(ti)+1]})
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%s : %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">tests</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #000000;">reasons</span><span style="color: #0000FF;">[</span><span style="color: #000000;">valid_ISIN</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tests</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]})</span>
end for</lang>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</lang>-->
{{out}}
{{out}}
<pre>
<pre>