Bitcoin/address validation: Difference between revisions

Content deleted Content added
Update Seed7 example
Update Seed7 example to define the function validBitcoinAddress
Line 1,982: Line 1,982:
include "encoding.s7i";
include "encoding.s7i";


const proc: assertBitcoin (in string: stri, in string: expected) is func
const func boolean: validBitcoinAddress (in string: address) is func
result
var boolean: isValid is FALSE;
local
local
var string: decoded is "";
var string: decoded is "";
var string: state is "okay";
begin
begin
if not succeeds(decoded := fromBase58(stri)) then
if succeeds(decoded := fromBase58(address)) and
length(decoded) = 25 and decoded[1] = '\0;' and
state := "bad char";
elsif length(decoded) <> 25 then
sha256(sha256(decoded[.. 21]))[.. 4] = decoded[22 ..] then
state := "wrong length";
isValid := TRUE;
elsif decoded[1] <> '\0;' then
state := "not version 0";
elsif sha256(sha256(decoded[.. 21]))[.. 4] <> decoded[22 ..] then
state := "bad digest";
end if;
end if;
end func;
writeln((stri <& ": ") rpad 37 <& state);

if state <> expected then
const proc: checkValidationFunction (in string: address, in boolean: expected) is func
writeln(" *** Expected " <& literal(expected) <& " for " <& stri <& ", but got " <& literal(state) <& ".");
local
var boolean: isValid is FALSE;
begin
isValid := validBitcoinAddress(address);
writeln((address <& ": ") rpad 37 <& isValid);
if isValid <> expected then
writeln(" *** Expected " <& expected <& " for " <& address <& ", but got " <& isValid <& ".");
end if;
end if;
end func;
end func;
Line 2,004: Line 2,008:
const proc: main is func
const proc: main is func
begin
begin
assertBitcoin("1Q1pE5vPGEEMqRcVRMbtBK842Y6Pzo6nK9", "okay");
checkValidationFunction("1Q1pE5vPGEEMqRcVRMbtBK842Y6Pzo6nK9", TRUE); # okay
assertBitcoin("1Q1pE5vPGEEMqRcVRMbtBK842Y6Pzo6nJ9", "bad digest");
checkValidationFunction("1Q1pE5vPGEEMqRcVRMbtBK842Y6Pzo6nJ9", FALSE); # bad digest
assertBitcoin("1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i", "okay");
checkValidationFunction("1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i", TRUE); # okay
assertBitcoin("1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62j", "bad digest");
checkValidationFunction("1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62j", FALSE); # bad digest
assertBitcoin("1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62X", "bad digest");
checkValidationFunction("1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62X", FALSE); # bad digest
assertBitcoin("1ANNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i", "bad digest");
checkValidationFunction("1ANNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i", FALSE); # bad digest
assertBitcoin("oMRDCDfyQhEerkaSmwCfSPqf3MLgBwNvs", "not version 0");
checkValidationFunction("oMRDCDfyQhEerkaSmwCfSPqf3MLgBwNvs", FALSE); # not version 0
assertBitcoin("1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62iz", "wrong length");
checkValidationFunction("1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62iz", FALSE); # wrong length
assertBitcoin("1BGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i", "bad digest");
checkValidationFunction("1BGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i", FALSE); # bad digest
assertBitcoin("1A Na15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i", "bad char");
checkValidationFunction("1A Na15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i", FALSE); # bad char
assertBitcoin("1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62I", "bad char");
checkValidationFunction("1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62I", FALSE); # bad char
assertBitcoin("1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62!", "bad char");
checkValidationFunction("1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62!", FALSE); # bad char
assertBitcoin("1AGNa15ZQXAZUgFiqJ3i7Z2DPU2J6hW62i", "bad digest");
checkValidationFunction("1AGNa15ZQXAZUgFiqJ3i7Z2DPU2J6hW62i", FALSE); # bad digest
assertBitcoin("1111111111111111111114oLvT2", "okay");
checkValidationFunction("1111111111111111111114oLvT2", TRUE); # okay
assertBitcoin("17NdbrSGoUotzeGCcMMCqnFkEvLymoou9j", "okay");
checkValidationFunction("17NdbrSGoUotzeGCcMMCqnFkEvLymoou9j", TRUE); # okay
assertBitcoin("1badbadbadbadbadbadbadbadbadbadbad", "wrong length");
checkValidationFunction("1badbadbadbadbadbadbadbadbadbadbad", FALSE); # wrong length
assertBitcoin("BZbvjr", "wrong length");
checkValidationFunction("BZbvjr", FALSE); # wrong length
assertBitcoin("i55j", "wrong length");
checkValidationFunction("i55j", FALSE); # wrong length
assertBitcoin("16UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM", "okay");
checkValidationFunction("16UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM", TRUE); # okay
end func;</lang>
end func;</lang>


{{out}}
{{out}}
<pre>
<pre>
1Q1pE5vPGEEMqRcVRMbtBK842Y6Pzo6nK9: okay
1Q1pE5vPGEEMqRcVRMbtBK842Y6Pzo6nK9: TRUE
1Q1pE5vPGEEMqRcVRMbtBK842Y6Pzo6nJ9: bad digest
1Q1pE5vPGEEMqRcVRMbtBK842Y6Pzo6nJ9: FALSE
1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i: okay
1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i: TRUE
1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62j: bad digest
1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62j: FALSE
1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62X: bad digest
1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62X: FALSE
1ANNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i: bad digest
1ANNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i: FALSE
oMRDCDfyQhEerkaSmwCfSPqf3MLgBwNvs: not version 0
oMRDCDfyQhEerkaSmwCfSPqf3MLgBwNvs: FALSE
1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62iz: wrong length
1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62iz: FALSE
1BGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i: bad digest
1BGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i: FALSE
1A Na15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i: bad char
1A Na15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i: FALSE
1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62I: bad char
1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62I: FALSE
1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62!: bad char
1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62!: FALSE
1AGNa15ZQXAZUgFiqJ3i7Z2DPU2J6hW62i: bad digest
1AGNa15ZQXAZUgFiqJ3i7Z2DPU2J6hW62i: FALSE
1111111111111111111114oLvT2: okay
1111111111111111111114oLvT2: TRUE
17NdbrSGoUotzeGCcMMCqnFkEvLymoou9j: okay
17NdbrSGoUotzeGCcMMCqnFkEvLymoou9j: TRUE
1badbadbadbadbadbadbadbadbadbadbad: wrong length
1badbadbadbadbadbadbadbadbadbadbad: FALSE
BZbvjr: wrong length
BZbvjr: FALSE
i55j: wrong length
i55j: FALSE
16UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM: okay
16UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM: TRUE
</pre>
</pre>