Bitcoin/address validation: Difference between revisions

m
→‎{{header|Phix}}: added syntax colouring the hard way
(Added Wren)
m (→‎{{header|Phix}}: added syntax colouring the hard way)
Line 1,636:
 
=={{header|Phix}}==
<!--<lang Phix>(notonline)-->
<lang Phix>-- demo\rosetta\bitcoin_address_validation.exw
<span style="color: #000080;font-style:italic;">-- demo\rosetta\bitcoin_address_validation.exw</span>
include builtins\sha256.e
<span style="color: #008080;">include</span> <span style="color: #000000;">builtins</span><span style="color: #0000FF;">\</span><span style="color: #000000;">sha256</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
 
constant b58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
<span style="color: #008080;">constant</span> <span style="color: #000000;">b58</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"</span>
string charmap = ""
<span style="color: #004080;">string</span> <span style="color: #000000;">charmap</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</span>
 
function valid(string s, bool expected)
<span style="color: #008080;">function</span> <span style="color: #000000;">valid</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">bool</span> <span style="color: #000000;">expected</span><span style="color: #0000FF;">)</span>
bool res := (expected==false)
<span style="color: #004080;">bool</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">:=</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">expected</span><span style="color: #0000FF;">==</span><span style="color: #004600;">false</span><span style="color: #0000FF;">)</span>
if charmap="" then
<span style="color: #008080;">if</span> <span style="color: #000000;">charmap</span><span style="color: #0000FF;">=</span><span style="color: #008000;">""</span> <span style="color: #008080;">then</span>
charmap = repeat('\0',256)
<span style="color: #000000;">charmap</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'\0'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">256</span><span style="color: #0000FF;">)</span>
for i=1 to length(b58) do
<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;">b58</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
charmap[b58[i]] = i
<span style="color: #000000;">charmap</span><span style="color: #0000FF;">[</span><span style="color: #000000;">b58</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: #000000;">i</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
-- not at all sure about this:
<span style="color: #000080;font-style:italic;">-- not at all sure about this:
-- if length(s)!=34 then
-- if length(s)!=34 then
-- return {res,"bad length"}
-- return {res,"bad length"}
-- end if
-- end if</span>
if not find(s[1],"13") then
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">],</span><span style="color: #008000;">"13"</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
return {res,"first character is not 1 or 3"}
<span style="color: #008080;">return</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">res</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"first character is not 1 or 3"</span><span style="color: #0000FF;">}</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
string out = repeat('\0',25)
<span style="color: #004080;">string</span> <span style="color: #000000;">out</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'\0'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">25</span><span style="color: #0000FF;">)</span>
for i=1 to length(s) do
<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;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
integer c = charmap[s[i]]
<span style="color: #004080;">integer</span> <span style="color: #000000;">c</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">charmap</span><span style="color: #0000FF;">[</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]]</span>
if c=0 then
<span style="color: #008080;">if</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
return {res,"bad char"}
<span style="color: #008080;">return</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">res</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"bad char"</span><span style="color: #0000FF;">}</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
c -= 1
<span style="color: #000000;">c</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">1</span>
for j=25 to 1 by -1 do
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">25</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>
c += 58 * out[j];
<span style="color: #000000;">c</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">58</span> <span style="color: #0000FF;">*</span> <span style="color: #000000;">out</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">];</span>
out[j] = and_bits(c,#FF)
<span style="color: #000000;">out</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">and_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">,</span><span style="color: #000000;">#FF</span><span style="color: #0000FF;">)</span>
c = floor(c/#100)
<span style="color: #000000;">c</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">/</span><span style="color: #000000;">#100</span><span style="color: #0000FF;">)</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
if c!=0 then
<span style="color: #008080;">if</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
return {res,"address too long"}
<span style="color: #008080;">return</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">res</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"address too long"</span><span style="color: #0000FF;">}</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
if out[1]!='\0' then
<span style="color: #008080;">if</span> <span style="color: #000000;">out</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]!=</span><span style="color: #008000;">'\0'</span> <span style="color: #008080;">then</span>
return {res,"not version 0"}
<span style="color: #008080;">return</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">res</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"not version 0"</span><span style="color: #0000FF;">}</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
if out[22..$]!=sha256(sha256(out[1..21]))[1..4] then
<span style="color: #008080;">if</span> <span style="color: #000000;">out</span><span style="color: #0000FF;">[</span><span style="color: #000000;">22</span><span style="color: #0000FF;">..$]!=</span><span style="color: #000000;">sha256</span><span style="color: #0000FF;">(</span><span style="color: #000000;">sha256</span><span style="color: #0000FF;">(</span><span style="color: #000000;">out</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..</span><span style="color: #000000;">21</span><span style="color: #0000FF;">]))[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..</span><span style="color: #000000;">4</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">then</span>
return {res,"bad digest"}
<span style="color: #008080;">return</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">res</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"bad digest"</span><span style="color: #0000FF;">}</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
res := (expected==true)
<span style="color: #000000;">res</span> <span style="color: #0000FF;">:=</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">expected</span><span style="color: #0000FF;">==</span><span style="color: #004600;">true</span><span style="color: #0000FF;">)</span>
return {res,"OK"}
<span style="color: #008080;">return</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">res</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"OK"</span><span style="color: #0000FF;">}</span>
end function
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
constant tests = {{"1Q1pE5vPGEEMqRcVRMbtBK842Y6Pzo6nK9",true}, -- OK
<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;">"1Q1pE5vPGEEMqRcVRMbtBK842Y6Pzo6nK9"</span><span style="color: #0000FF;">,</span><span style="color: #004600;">true</span><span style="color: #0000FF;">},</span> <span style="color: #000080;font-style:italic;">-- OK</span>
{"1Q1pE5vPGEEMqRcVRMbtBK842Y6Pzo6nJ9",false}, -- bad digest
<span style="color: #0000FF;">{</span><span style="color: #008000;">"1Q1pE5vPGEEMqRcVRMbtBK842Y6Pzo6nJ9"</span><span style="color: #0000FF;">,</span><span style="color: #004600;">false</span><span style="color: #0000FF;">},</span> <span style="color: #000080;font-style:italic;">-- bad digest</span>
{"1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i",true}, -- OK
<span style="color: #0000FF;">{</span><span style="color: #008000;">"1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i"</span><span style="color: #0000FF;">,</span><span style="color: #004600;">true</span><span style="color: #0000FF;">},</span> <span style="color: #000080;font-style:italic;">-- OK</span>
{"1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62j",false}, -- bad disgest
<span style="color: #0000FF;">{</span><span style="color: #008000;">"1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62j"</span><span style="color: #0000FF;">,</span><span style="color: #004600;">false</span><span style="color: #0000FF;">},</span> <span style="color: #000080;font-style:italic;">-- bad disgest</span>
{"1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62X",false}, -- bad digest (checksum changed, original data.)
<span style="color: #0000FF;">{</span><span style="color: #008000;">"1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62X"</span><span style="color: #0000FF;">,</span><span style="color: #004600;">false</span><span style="color: #0000FF;">},</span> <span style="color: #000080;font-style:italic;">-- bad digest (checksum changed, original data.)</span>
{"1ANNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i",false}, -- bad digest (data changed, original checksum.)
<span style="color: #0000FF;">{</span><span style="color: #008000;">"1ANNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i"</span><span style="color: #0000FF;">,</span><span style="color: #004600;">false</span><span style="color: #0000FF;">},</span> <span style="color: #000080;font-style:italic;">-- bad digest (data changed, original checksum.)</span>
{"1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62iz",false}, -- not version 0
<span style="color: #0000FF;">{</span><span style="color: #008000;">"1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62iz"</span><span style="color: #0000FF;">,</span><span style="color: #004600;">false</span><span style="color: #0000FF;">},</span> <span style="color: #000080;font-style:italic;">-- not version 0</span>
{"1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62izz",false}, -- address too long
<span style="color: #0000FF;">{</span><span style="color: #008000;">"1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62izz"</span><span style="color: #0000FF;">,</span><span style="color: #004600;">false</span><span style="color: #0000FF;">},</span> <span style="color: #000080;font-style:italic;">-- address too long</span>
{"1BGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i",false}, -- bad digest
<span style="color: #0000FF;">{</span><span style="color: #008000;">"1BGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i"</span><span style="color: #0000FF;">,</span><span style="color: #004600;">false</span><span style="color: #0000FF;">},</span> <span style="color: #000080;font-style:italic;">-- bad digest</span>
{"1A Na15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i",false}, -- bad char
<span style="color: #0000FF;">{</span><span style="color: #008000;">"1A Na15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i"</span><span style="color: #0000FF;">,</span><span style="color: #004600;">false</span><span style="color: #0000FF;">},</span> <span style="color: #000080;font-style:italic;">-- bad char</span>
{"1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62I",false}, -- bad char
<span style="color: #0000FF;">{</span><span style="color: #008000;">"1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62I"</span><span style="color: #0000FF;">,</span><span style="color: #004600;">false</span><span style="color: #0000FF;">},</span> <span style="color: #000080;font-style:italic;">-- bad char</span>
{"1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62!",false}, -- bad char
<span style="color: #0000FF;">{</span><span style="color: #008000;">"1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62!"</span><span style="color: #0000FF;">,</span><span style="color: #004600;">false</span><span style="color: #0000FF;">},</span> <span style="color: #000080;font-style:italic;">-- bad char</span>
{"1AGNa15ZQXAZUgFiqJ3i7Z2DPU2J6hW62i",false}, -- bad digest
<span style="color: #0000FF;">{</span><span style="color: #008000;">"1AGNa15ZQXAZUgFiqJ3i7Z2DPU2J6hW62i"</span><span style="color: #0000FF;">,</span><span style="color: #004600;">false</span><span style="color: #0000FF;">},</span> <span style="color: #000080;font-style:italic;">-- bad digest</span>
{"1111111111111111111114oLvT2", true}, -- OK
<span style="color: #0000FF;">{</span><span style="color: #008000;">"1111111111111111111114oLvT2"</span><span style="color: #0000FF;">,</span> <span style="color: #004600;">true</span><span style="color: #0000FF;">},</span> <span style="color: #000080;font-style:italic;">-- OK</span>
{"17NdbrSGoUotzeGCcMMCqnFkEvLymoou9j",true}, -- OK
<span style="color: #0000FF;">{</span><span style="color: #008000;">"17NdbrSGoUotzeGCcMMCqnFkEvLymoou9j"</span><span style="color: #0000FF;">,</span><span style="color: #004600;">true</span><span style="color: #0000FF;">},</span> <span style="color: #000080;font-style:italic;">-- OK</span>
{"1badbadbadbadbadbadbadbadbadbadbad",false}, -- not version 0
<span style="color: #0000FF;">{</span><span style="color: #008000;">"1badbadbadbadbadbadbadbadbadbadbad"</span><span style="color: #0000FF;">,</span><span style="color: #004600;">false</span><span style="color: #0000FF;">},</span> <span style="color: #000080;font-style:italic;">-- not version 0</span>
{"BZbvjr",false}, -- first character is not 1 or 3 (checksum is fine, address too short)
<span style="color: #0000FF;">{</span><span style="i55jcolor: #008000;">"BZbvjr"</span><span style="color: #0000FF;">,</span><span style="color: #004600;">false</span><span style="color: #0000FF;">},</span> <span style="color: #000080;font-style:italic;">-- first character is not 1 or 3 (checksum is fine, address too short)</span>
<span style="color: #0000FF;">{</span><span style="color: #008000;">"i55j"</span><span style="color: #0000FF;">,</span><span style="color: #004600;">false</span><span style="color: #0000FF;">},</span> <span style="color: #000080;font-style:italic;">-- first character is not 1 or 3 (checksum is fine, address too short)</span>
{"16UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM", true}, -- OK (from public_point_to_address)
<span style="color: #0000FF;">{</span><span style="color: #008000;">"16UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM"</span><span style="color: #0000FF;">,</span> <span style="color: #004600;">true</span><span style="color: #0000FF;">},</span> <span style="color: #000080;font-style:italic;">-- OK (from public_point_to_address)</span>
$}
<span style="color: #0000FF;">$}</span>
 
for i=1 to length(tests) do
<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>
{string ti, bool expected} = tests[i]
<span style="color: #0000FF;">{</span><span style="color: #004080;">string</span> <span style="color: #000000;">ti</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">bool</span> <span style="color: #000000;">expected</span><span style="color: #0000FF;">}</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>
{bool res, string coin_err} = valid(ti,expected)
<span style="color: #0000FF;">{</span><span style="color: #004080;">bool</span> <span style="color: #000000;">res</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">string</span> <span style="color: #000000;">coin_err</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">valid</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ti</span><span style="color: #0000FF;">,</span><span style="color: #000000;">expected</span><span style="color: #0000FF;">)</span>
if not res then
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #000000;">res</span> <span style="color: #008080;">then</span>
printf(1,"%s: %s\n", {ti, coin_err})
<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: #0000FF;">{</span><span style="color: #000000;">ti</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">coin_err</span><span style="color: #0000FF;">})</span>
{} = wait_key()
<span style="color: #0000FF;">{}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">wait_key</span><span style="color: #0000FF;">()</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end for</lang>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</lang>-->
(No output since all tests pass)
 
7,805

edits