Bitcoin/address validation: Difference between revisions

m
(Added Wren)
m (→‎{{header|Wren}}: Minor tidy)
 
(6 intermediate revisions by 3 users not shown)
Line 1:
[[Category:Checksums]]
{{alertbox|#ffff70|'''<big>Warning:</big>''' Many of these snippets are [[{{TALKPAGENAME}}#C-based_code_.28and_possibly_others.29_improperly_validates|incomplete]]. It is recommended that you use an established [https://en.bitcoin.it/wiki/Software#Libraries library] for any projects that are likely to see external use}}
{{task}}
[[Category:Checksums]]
{{omit from|Brlcad}}
{{omit from|GUISS}}
 
 
Line 38 ⟶ 36:
<br>You can change a few characters in this string and check that it'll fail the test.
<br><br>
 
=={{header|Ada}}==
<langsyntaxhighlight lang="ada">with Ada.Exceptions, Interfaces;
with Ada.Streams;
use Ada.Exceptions, Interfaces;
Line 168 ⟶ 165:
end;
end Bitcoin_Addr_Validate;
</syntaxhighlight>
</lang>
 
{{out}}
Line 177 ⟶ 174:
1A Na15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i validity: *** Error: Invalid BT address.
</pre>
 
=={{header|C}}==
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <string.h>
#include <openssl/sha.h>
Line 239 ⟶ 235:
 
return 0;
}</langsyntaxhighlight>
Compile with -lcrypto
{{out}}
Line 248 ⟶ 244:
1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62I: bad char
</pre>
 
=={{header|C sharp|C#}}==
This requires [https://www.nuget.org/packages/NUnit/ NUnit package] to compile.
<langsyntaxhighlight lang="csharp">
using System;
using System.Linq;
Line 321 ⟶ 316:
}
}
</syntaxhighlight>
</lang>
 
=={{header|D}}==
This requires the D module from the SHA-256 Task.
{{trans|Go}}
<langsyntaxhighlight lang="d">import std.stdio, std.algorithm, std.array, std.string, sha_256_2;
 
struct A25 {
Line 410 ⟶ 404:
writefln(`"%s": %s`, test, err.empty ? "OK." : err);
}
}</langsyntaxhighlight>
{{out}}
<pre>"1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i": OK.
Line 417 ⟶ 411:
"1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62iz": not Bitcoin version 0.
"1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62izz": too long Bitcoin address.</pre>
 
=={{header|dart}}==
This requires [https://pub.dev/packages/crypto Crypto package] to compile.
{{trans|Java}}
<langsyntaxhighlight lang="dart">import 'package:crypto/crypto.dart';
 
class Bitcoin {
Line 519 ⟶ 512:
return true;
}
}</langsyntaxhighlight>
{{out}}
<pre>"1BNGaR29FmfAqidXmD9HLwsGv9p5WVvvhq" true
"1BNGaR29FmfAqidXmD9HLws" false
</pre>
 
=={{header|Delphi}}==
This requires [http://www.cityinthesky.co.uk/opensource/DCPcrypt/ DCPcrypt library] to compile.
<langsyntaxhighlight lang="delphi">
uses
DCPsha256;
Line 592 ⟶ 584:
raise Exception.Create('Bad digest');
end;
</syntaxhighlight>
</lang>
 
=={{header|Erlang}}==
Using base58 module from http://github.com/titan098/erl-base58.git.
 
<syntaxhighlight lang="erlang">
<lang Erlang>
-module( bitcoin_address ).
 
Line 615 ⟶ 606:
{checksum, Checksum} = {checksum, Four_bytes},
ok.
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 626 ⟶ 617:
in call from bitcoin_address:task/0 (src/bitcoin_address.erl, line 9)
</pre>
 
=={{header|Factor}}==
<langsyntaxhighlight lang="factor">USING: byte-arrays checksums checksums.sha io.binary kernel math
math.parser sequences ;
IN: rosetta-code.bitcoin.validation
Line 644 ⟶ 634:
 
: btc-valid? ( str -- ? ) base58> [ btc-checksum ] [ 4 tail* ] bi = ;
</syntaxhighlight>
</lang>
 
{{out}}
Line 652 ⟶ 642:
"1ANNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i" btc-valid? . ! f, data changed, original checksum.
</pre>
 
=={{header|FreeBASIC}}==
<langsyntaxhighlight lang="freebasic">' version 05-04-2017
' compile with: fbc -s console
 
Line 859 ⟶ 848:
Print : Print "hit any key to end program"
Sleep
End</langsyntaxhighlight>
{{out}}
<pre>Bitcoin address: 1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i is valid
Line 866 ⟶ 855:
Bitcoin address: 0AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i first character is not 1 or 3
Bitcoin address: 1AGNa15ZQXAZUgFlqJ2i7Z2DPU2J6hW62i bitcoin address contains illegal character</pre>
 
=={{header|Go}}==
{{trans|C}}
<langsyntaxhighlight lang="go">package main
 
import (
Line 977 ⟶ 965:
os.Stderr.WriteString(m + "\n")
os.Exit(1)
}</langsyntaxhighlight>
{{out}}
Command line usage examples showing program exit status.
Line 1,002 ⟶ 990:
1
</pre>
 
=={{header|Haskell}}==
<langsyntaxhighlight lang="haskell">import Control.Monad (when)
import Data.List (elemIndex)
import Data.Monoid ((<>))
Line 1,062 ⟶ 1,049:
validate "1ANa55215ZQXAZUgFiqJ2i7Z2DPU2J6hW62i" -- too long
validate "i55j" -- too short
</syntaxhighlight>
</lang>
{{out}}
<pre style="font-size:80%">"1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i" -> Valid
Line 1,071 ⟶ 1,058:
"1ANa55215ZQXAZUgFiqJ2i7Z2DPU2J6hW62i" -> "Address length exceeds 25 bytes"
"i55j" -> "Address length less than 4 bytes"</pre>
 
=={{header|Java}}==
<langsyntaxhighlight lang="java">import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
Line 1,141 ⟶ 1,127:
throw new AssertionError(String.format("Expected %s for %s, but got %s.", expected, address, actual));
}
}</langsyntaxhighlight>
 
=={{header|Julia}}==
{{works with|Julia|0.6}}
{{trans|Python}}
<langsyntaxhighlight lang="julia">using SHA
 
bytes(n::Integer, l::Int) = collect(UInt8, (n >> 8i) & 0xFF for i in l-1:-1:0)
Line 1,183 ⟶ 1,168:
for (addr, corr) in addresses
println("Address: $addr\nExpected: $corr\tChecked: ", checkbcaddress(addr))
end</langsyntaxhighlight>
 
{{out}}
Line 1,212 ⟶ 1,197:
Address: 1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62iz
Expected: false Checked: false</pre>
 
=={{header|Kotlin}}==
{{trans|Java}}
<langsyntaxhighlight lang="scala">import java.security.MessageDigest
 
object Bitcoin {
Line 1,274 ⟶ 1,258:
for (address in addresses)
println("${address.padEnd(36)} -> ${if (Bitcoin.validateAddress(address)) "valid" else "invalid"}")
}</langsyntaxhighlight>
 
{{out}}
Line 1,292 ⟶ 1,276:
1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62I -> invalid
</pre>
 
=={{header|Mathematica}} / {{header|Wolfram Language}}==
<langsyntaxhighlight Mathematicalang="mathematica">chars = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; data =
IntegerDigits[
FromDigits[
Line 1,303 ⟶ 1,286:
Hash[FromCharacterCode[
IntegerDigits[Hash[FromCharacterCode[data[[;; -5]]], "SHA256"],
256, 32]], "SHA256"], 256, 32][[;; 4]]</langsyntaxhighlight>
{{in}}
<pre>1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i
Line 1,310 ⟶ 1,293:
<pre>True
False</pre>
 
=={{header|Nim}}==
Tests on first digit character and on address length have been added to detect wrong addresses such as "BZbvjr".
Line 1,316 ⟶ 1,298:
===Using “libssl”===
 
<langsyntaxhighlight lang="nim">import algorithm
 
const SHA256Len = 32
Line 1,396 ⟶ 1,378:
 
main()
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,414 ⟶ 1,396:
===Using “nimcrypto”===
{{libheader|nimcrypto}}
<langsyntaxhighlight Nimlang="nim">import nimcrypto
import strformat
 
Line 1,492 ⟶ 1,474:
 
for vector in testVectors:
vector.checkValidity()</langsyntaxhighlight>
 
{{out}}
Line 1,507 ⟶ 1,489:
Address “1111111111111111111114oLvT2” is valid.
Address “BZbvjr” is invalid (starting character is not 1 or 3).</pre>
 
=={{header|Oberon-2}}==
{{works with|oo2c}}{{libheader|Crypto}}
<langsyntaxhighlight lang="oberon2">
MODULE BitcoinAddress;
IMPORT
Line 1,591 ⟶ 1,572:
Out.Bool(Valid("1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62I"));Out.Ln
END BitcoinAddress.
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,600 ⟶ 1,581:
FALSE
</pre>
 
=={{header|Perl}}==
<langsyntaxhighlight lang="perl">my @b58 = qw{
1 2 3 4 5 6 7 8 9
A B C D E F G H J K L M N P Q R S T U V W X Y Z
Line 1,633 ⟶ 1,613:
(pack 'C*', @byte[21..24]) eq
substr sha256(sha256 pack 'C*', @byte[0..20]), 0, 4;
}</langsyntaxhighlight>
 
=={{header|Phix}}==
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>-- demo\rosetta\bitcoin_address_validation.exw
<span style="color: #000080;font-style:italic;">--
include builtins\sha256.e
-- demo\rosetta\bitcoin_address_validation.exw
 
-- ===========================================
constant b58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
--</span>
string charmap = ""
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
 
<span style="color: #008080;">include</span> <span style="color: #000000;">builtins</span><span style="color: #0000FF;">\</span><span style="color: #7060A8;">sha256</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
function valid(string s, bool expected)
bool res := (expected==false)
if charmap="" then
charmap = repeat('\0',256)
for i=1 to length(b58) do
charmap[b58[i]] = i
end for
end if
-- not at all sure about this:
-- if length(s)!=34 then
-- return {res,"bad length"}
-- end if
if not find(s[1],"13") then
return {res,"first character is not 1 or 3"}
end if
string out = repeat('\0',25)
for i=1 to length(s) do
integer c = charmap[s[i]]
if c=0 then
return {res,"bad char"}
end if
c -= 1
for j=25 to 1 by -1 do
c += 58 * out[j];
out[j] = and_bits(c,#FF)
c = floor(c/#100)
end for
if c!=0 then
return {res,"address too long"}
end if
end for
if out[1]!='\0' then
return {res,"not version 0"}
end if
if out[22..$]!=sha256(sha256(out[1..21]))[1..4] then
return {res,"bad digest"}
end if
res := (expected==true)
return {res,"OK"}
end function
<span style="color: #008080;">constant</span> <span style="color: #000000;">b58</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"</span>
constant tests = {{"1Q1pE5vPGEEMqRcVRMbtBK842Y6Pzo6nK9",true}, -- OK
<span style="color: #004080;">string</span> <span style="color: #000000;">charmap</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</span>
{"1Q1pE5vPGEEMqRcVRMbtBK842Y6Pzo6nJ9",false}, -- bad digest
{"1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i",true}, -- OK
<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>
{"1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62j",false}, -- bad disgest
<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>
{"1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62X",false}, -- bad digest (checksum changed, original data.)
<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>
{"1ANNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i",false}, -- bad digest (data changed, original checksum.)
<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>
{"1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62iz",false}, -- not version 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;">b58</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
{"1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62izz",false}, -- address too long
<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>
{"1BGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i",false}, -- bad digest
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
{"1A Na15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i",false}, -- bad char
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
{"1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62I",false}, -- bad char
<span style="color: #000080;font-style:italic;">-- not at all sure about this:
{"1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62!",false}, -- bad char
-- if length(s)!=34 then
{"1AGNa15ZQXAZUgFiqJ3i7Z2DPU2J6hW62i",false}, -- bad digest
-- return {expected==false,"bad length"}
{"1111111111111111111114oLvT2", true}, -- OK
-- end if</span>
{"17NdbrSGoUotzeGCcMMCqnFkEvLymoou9j",true}, -- OK
<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>
{"1badbadbadbadbadbadbadbadbadbadbad",false}, -- 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;">"first character is not 1 or 3"</span><span style="color: #0000FF;">}</span>
{"BZbvjr",false}, -- first character is not 1 or 3 (checksum is fine, address too short)
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
{"i55j",false}, -- first character is not 1 or 3 (checksum is fine, address too short)
<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>
{"16UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM", true}, -- OK (from public_point_to_address)
<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>
$}
<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>
 
<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>
for i=1 to length(tests) do
<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>
{string ti, bool expected} = tests[i]
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
{bool res, string coin_err} = valid(ti,expected)
<span style="color: #000000;">c</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">1</span>
if not res then
<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>
printf(1,"%s: %s\n", {ti, coin_err})
<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>
{} = wait_key()
<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>
end if
<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</lang>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
(No output since all tests pass)
<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>
 
<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>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<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>
<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>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<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: #7060A8;">sha256</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">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>
<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>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</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;">true</span><span style="color: #0000FF;">)</span>
<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>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<span style="color: #0000FF;">{</span><span style="color: #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>
<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>
<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>
<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>
<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>
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #000000;">res</span> <span style="color: #008080;">then</span>
<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>
<span style="color: #0000FF;">{}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">wait_key</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #0000FF;">?</span><span style="color: #008000;">"done"</span>
<span style="color: #0000FF;">{}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">wait_key</span><span style="color: #0000FF;">()</span>
<!--</syntaxhighlight>-->
(No output other than "done" since all tests pass)
=={{header|PHP}}==
<langsyntaxhighlight lang="php">
function validate($address){
$decoded = decodeBase58($address);
Line 1,773 ⟶ 1,760:
main();
 
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,782 ⟶ 1,769:
1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62I: invalid character found
</pre>
 
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(load "sha256.l")
 
(setq *Alphabet
Line 1,813 ⟶ 1,799:
(valid "1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62!")
(valid "1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62iz")
(valid "1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62izz") ) )</langsyntaxhighlight>
 
=={{header|PureBasic}}==
<syntaxhighlight lang="purebasic">
<lang PureBasic>
; using PureBasic 5.50 (x64)
EnableExplicit
Line 1,894 ⟶ 1,879:
EndIf
 
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,902 ⟶ 1,887:
1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62I -> Invalid
</pre>
 
=={{header|Python}}==
<langsyntaxhighlight lang="python">from hashlib import sha256
 
digits58 = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
Line 1,921 ⟶ 1,905:
 
print(check_bc('1AGNa15ZQXAZUgFiqJ3i7Z2DPU2J6hW62i'))
print(check_bc("17NdbrSGoUotzeGCcMMCqnFkEvLymoou9j"))</langsyntaxhighlight>
 
{{out}}
Line 1,931 ⟶ 1,915:
:Yuuki-chan edit: Delete this help if it's not needed anymore
:For those looking at examples here to try and work out what is required, the <code>n.to_bytes()</code> call is equivalent to this code which converts a (long) integer into individual bytes of a byte array in a particular order:
:<langsyntaxhighlight lang="python">>>> n = 2491969579123783355964723219455906992268673266682165637887
>>> length = 25
>>> list( reversed(range(length)) )
[24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
>>> assert n.to_bytes(length, 'big') == bytes( (n >> i*8) & 0xff for i in reversed(range(length)))
>>> </langsyntaxhighlight>
 
=={{header|Racket}}==
<langsyntaxhighlight lang="racket">
#lang racket/base
 
Line 1,984 ⟶ 1,967:
(validate-bitcoin-address "1Q1pE5vPGEEMqRcVRMbtBK842Y6Pzo6nK9") ; => #t
(validate-bitcoin-address "1badbadbadbadbadbadbadbadbadbadbad") ; => #f
</syntaxhighlight>
</lang>
 
=={{header|Raku}}==
(formerly Perl 6)
<syntaxhighlight lang="raku" line>sub sha256(blob8 $b) returns blob8 {
<lang perl6>my $bitcoin-address = rx/
given run <openssl dgst -sha256 -binary>, :in, :out, :bin {
<+alnum-[0IOl]> ** 26..* # an address is at least 26 characters long
.in.write: $b;
.in.close;
return .out.slurp;
}
}
 
my $bitcoin-address = rx/
<< <+alnum-[0IOl]> ** 26..* >> # an address is at least 26 characters long
<?{
.subbuf(21, 4) eq sha256(sha256 .subbuf(0, 21)).subbuf(0, 4) given
use Digest::SHA;
blob8.new: <
.subbuf(21, 4) eqv sha256(sha256 .subbuf(0, 21)).subbuf(0, 4) given
Blob.new: <
1 2 3 4 5 6 7 8 9
A B C D E F G H J K L M N P Q R S T U V W X Y Z
Line 2,004 ⟶ 1,993:
/;
say "Here is a bitcoin address: 1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i" ~~ $bitcoin-address;</langsyntaxhighlight>
{{out}}
<pre>「1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i」</pre>
 
=={{header|Ruby}}==
<langsyntaxhighlight lang="ruby">
# Validate Bitcoin address
#
Line 2,026 ⟶ 2,014:
(n.length...42).each{n.insert(0,'0')}
puts "I think the checksum should be #{g}\nI calculate that it is #{Digest::SHA256.hexdigest(Digest::SHA256.digest(convert(n)))[0,8]}"
</syntaxhighlight>
</lang>
{{out}}
With A = '1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i'
Line 2,038 ⟶ 2,026:
I calculate that it is c046b2ff
</pre>
 
=={{header|Rust}}==
This requires the [https://crates.io/crates/rust-crypto rust-crypto] crate for sha256.
<syntaxhighlight lang="rust">
<lang Rust>
extern crate crypto;
 
Line 2,097 ⟶ 2,084:
Ok(res)
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 2,105 ⟶ 2,092:
false
</pre>
 
=={{header|Scala}}==
<langsyntaxhighlight Scalalang="scala">import java.security.MessageDigest
import java.util.Arrays.copyOfRange
 
Line 2,173 ⟶ 2,159:
println(s"Successfully completed without errors. [total ${scala.compat.Platform.currentTime - executionStart}ms]")
 
}</langsyntaxhighlight>
 
=={{header|Seed7}}==
The Seed7 library [http://seed7.sourceforge.net/libraries/encoding.htm encoding.s7i] defines
Line 2,184 ⟶ 2,169:
No external library is needed.
 
<langsyntaxhighlight lang="seed7">$ include "seed7_05.s7i";
include "msgdigest.s7i";
include "encoding.s7i";
Line 2,233 ⟶ 2,218:
checkValidationFunction("i55j", FALSE); # wrong length
checkValidationFunction("16UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM", TRUE); # okay
end func;</langsyntaxhighlight>
 
{{out}}
Line 2,257 ⟶ 2,242:
16UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM: TRUE
</pre>
 
=={{header|Tcl}}==
{{tcllib|sha256}}
<langsyntaxhighlight lang="tcl">package require sha256
 
# Generate a large and boring piece of code to do the decoding of
Line 2,293 ⟶ 2,277:
}
return "$address is ok"
}</langsyntaxhighlight>
Testing if it works
<langsyntaxhighlight lang="tcl">puts [bitcoin_addressValid 1Q1pE5vPGEEMqRcVRMbtBK842Y6Pzo6nK9]
puts [bitcoin_addressValid 1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i]</langsyntaxhighlight>
{{out}}
<pre>
Line 2,302 ⟶ 2,286:
1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i is ok
</pre>
 
=={{header|UNIX Shell}}==
{{works with|bash}}
<langsyntaxhighlight lang="bash">base58=({1..9} {A..H} {J..N} {P..Z} {a..k} {m..z})
bitcoinregex="^[$(printf "%s" "${base58[@]}")]{34}$"
 
Line 2,332 ⟶ 2,315:
else return 2
fi
}</langsyntaxhighlight>
 
=={{header|Wren}}==
{{trans|Kotlin}}
Line 2,339 ⟶ 2,321:
{{libheader|wren-str}}
{{libheader|Wren-fmt}}
<langsyntaxhighlight ecmascriptlang="wren">import "./crypto" for Sha256
import "./str" for Str
import "./fmt" for Conv, Fmt
 
class Bitcoin {
Line 2,400 ⟶ 2,382:
for (address in addresses) {
Fmt.print("$-36s -> $s", address, Bitcoin.validateAddress(address) ? "valid" : "invalid")
}</langsyntaxhighlight>
 
{{out}}
Line 2,421 ⟶ 2,403:
=={{header|zkl}}==
Uses shared library zklMsgHash.
<langsyntaxhighlight lang="zkl">var [const] MsgHash=Import("zklMsgHash"); // SHA-256, etc
const symbols="123456789" // 58 characters: no cap i,o; ell, zero
"ABCDEFGHJKLMNPQRSTUVWXYZ"
Line 2,445 ⟶ 2,427:
(2).reduce(MsgHash.SHA256.fp1(1,dec),dec); // dec is i/o buffer
dec[0,4]==chkSum;
}</langsyntaxhighlight>
<langsyntaxhighlight lang="zkl">T("1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i","1Q1pE5vPGEEMqRcVRMbtBK842Y6Pzo6nK9",
"1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62X", // checksum changed, original data.
"1ANNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i", // data changed, original checksum.
"1A Na15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i", // invalid chars
"1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62izz", // too long
).apply(coinValide).println();</langsyntaxhighlight>
{{out}}
<pre>L(True,True,False,False,False,False)</pre>
{{omit from|Brlcad}}
{{omit from|GUISS}}
9,476

edits