Bitcoin/address validation: Difference between revisions

New post showing an alternative version of an existing example which was retained.
m (→‎{{header|Raku}}: Use faster module, suppress warning)
(New post showing an alternative version of an existing example which was retained.)
 
(7 intermediate revisions by 4 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|C++}}==
This example uses the C++ code from the SHA-256 task. This slightly complicates the code because the previous task
was designed to hash a string of ASCII characters rather than a byte array.
<syntaxhighlight lang="c++">
#include <algorithm>
#include <cstdint>
#include <iostream>
#include <map>
#include <stdexcept>
#include <string>
#include <vector>
 
#include "SHA256.cpp"
SHA256 sha256{ };
 
const std::string ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
 
std::map<char, uint32_t> base_map =
{ { '0', 0 }, { '1', 1 }, { '2', 2 }, { '3', 3 }, { '4', 4 }, { '5', 5 }, { '6', 6 }, { '7', 7 },
{ '8', 8 }, { '9', 9 }, { 'a', 10 }, { 'b', 11 }, { 'c', 12 }, { 'd', 13 }, { 'e', 14 }, { 'f', 15 },
{ 'A', 10 }, { 'B', 11 }, { 'C', 12 }, { 'D', 13 }, { 'E', 14 }, { 'F', 15 } };
 
std::vector<uint32_t> hex_to_bytes(const std::string& text) {
std::vector<uint32_t> bytes(text.size() / 2, 0);
for ( uint64_t i = 0; i < text.size(); i += 2 ) {
const uint32_t first_digit = base_map[text[i]];
const uint32_t second_digit = base_map[text[i + 1]];
bytes[i / 2] = ( first_digit << 4 ) + second_digit;
}
return bytes;
}
 
std::string vector_to_ascii_string(const std::vector<uint32_t>& bytes) {
std::string result = "";
for ( uint32_t i = 0; i < bytes.size(); ++i ) {
result += static_cast<char>(bytes[i]);
}
return result;
}
 
std::vector<uint32_t> decode_base_58(const std::string& text) {
std::vector<uint32_t> result(25, 0);
for ( const char& ch : text ) {
std::string::size_type index = ALPHABET.find(ch);
if ( index == static_cast<uint64_t>(-1) ) {
throw std::invalid_argument("Invalid character found in bitcoin address");
}
for ( uint64_t i = result.size() - 1; i > 0; i-- ) {
index += 58 * result[i];
result[i] = index & 0xFF;
index >>= 8;
}
if ( index != 0 ) {
throw std::invalid_argument("Bitcoin address is too long");
}
}
return result;
}
 
bool is_valid(const std::string& address) {
if ( address.size() < 26 || address.size() > 35 ) {
throw std::invalid_argument("Invalid length of bitcoin address");
}
 
std::vector<uint32_t> decoded = decode_base_58(address);
std::vector first21(decoded.begin(), decoded.begin() + 21);
 
// Convert the 'first21' into a suitable ASCII string for the first SHA256 hash
std::string text = vector_to_ascii_string(first21);
std::string hash_1 = sha256.message_digest(text);
// Convert 'hashOne' into a suitable ASCII string for the second SHA256 hash
std::vector<uint32_t> bytes_1 = hex_to_bytes(hash_1);
std::string ascii_1 = vector_to_ascii_string(bytes_1);
std::string hash_2 = sha256.message_digest(ascii_1);
 
std::vector<uint32_t> bytes_2 = hex_to_bytes(hash_2);
std::vector<uint32_t> checksum(bytes_2.begin(), bytes_2.begin() + 4);
std::vector<uint32_t> last4(decoded.begin() + 21, decoded.begin() + 25);
return checksum == last4;
}
 
int main() {
const std::vector<std::string> addresses = { "1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i",
"1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62j",
"1Q1pE5vPGEEMqRcVRMbtBK842Y6Pzo6nK9",
"1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62X",
"1ANNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i" };
 
for ( const std::string& address : addresses ) {
std::cout << address << " : " << std::boolalpha << is_valid(address) << std::endl;
}
}
</syntaxhighlight>
{{ out }}
<pre>
1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i : true
1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62j : false
1Q1pE5vPGEEMqRcVRMbtBK842Y6Pzo6nK9 : true
1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62X : false
1ANNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i : false
</pre>
 
=={{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 ⟶ 507:
writefln(`"%s": %s`, test, err.empty ? "OK." : err);
}
}</langsyntaxhighlight>
{{out}}
<pre>"1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i": OK.
Line 417 ⟶ 514:
"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 ⟶ 615:
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 ⟶ 687:
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 ⟶ 709:
{checksum, Checksum} = {checksum, Four_bytes},
ok.
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 626 ⟶ 720:
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 ⟶ 737:
 
: btc-valid? ( str -- ? ) base58> [ btc-checksum ] [ 4 tail* ] bi = ;
</syntaxhighlight>
</lang>
 
{{out}}
Line 652 ⟶ 745:
"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 ⟶ 951:
Print : Print "hit any key to end program"
Sleep
End</langsyntaxhighlight>
{{out}}
<pre>Bitcoin address: 1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i is valid
Line 866 ⟶ 958:
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 ⟶ 1,068:
os.Stderr.WriteString(m + "\n")
os.Exit(1)
}</langsyntaxhighlight>
{{out}}
Command line usage examples showing program exit status.
Line 1,002 ⟶ 1,093:
1
</pre>
 
=={{header|Haskell}}==
<langsyntaxhighlight lang="haskell">import Control.Monad (when)
import Data.List (elemIndex)
import Data.Monoid ((<>))
Line 1,062 ⟶ 1,152:
validate "1ANa55215ZQXAZUgFiqJ2i7Z2DPU2J6hW62i" -- too long
validate "i55j" -- too short
</syntaxhighlight>
</lang>
{{out}}
<pre style="font-size:80%">"1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i" -> Valid
Line 1,071 ⟶ 1,161:
"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,230:
throw new AssertionError(String.format("Expected %s for %s, but got %s.", expected, address, actual));
}
}</langsyntaxhighlight>
 
===Alternative Version===
This example uses the Java code from the SHA-256 task as an alternative to using Java's built-in SHA256 method. It
also decodes Base58 without using Java's built-in BigInteger class.
<syntaxhighlight lang="java">
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.List;
 
public final class BitcoinAddressValidation {
 
public static void main(String[] args) {
List<String> addresses = List.of ( "1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i",
"1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62j",
"1Q1pE5vPGEEMqRcVRMbtBK842Y6Pzo6nK9",
"1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62X",
"1ANNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i" );
for ( String address : addresses ) {
System.out.println(address + " : " + isValid(address));
}
}
private static boolean isValid(String address) {
if ( address.length() < 26 || address.length() > 35 ) {
throw new AssertionError("Invalid length of bitcoin address");
}
byte[] decoded = decodeBase58(address);
byte[] first21 = Arrays.copyOfRange(decoded, 0, 21);
// Convert 'first21' into an ASCII string for the first SHA256 hash
String text = new String(first21, StandardCharsets.ISO_8859_1);
String hashOne = SHA256.messageDigest(text);
// Convert 'hashOne' into an ASCII string for the second SHA256 hash
byte[] bytesOne = hexToBytes(hashOne);
String asciiOne = new String(bytesOne, StandardCharsets.ISO_8859_1);
String hashTwo = SHA256.messageDigest(asciiOne);
byte[] bytesTwo = hexToBytes(hashTwo);
byte[] checksum = Arrays.copyOfRange(bytesTwo, 0, 4);
byte[] last4 = Arrays.copyOfRange(decoded, 21, 25);
return Arrays.equals(last4, checksum);
}
private static byte[] decodeBase58(String text) {
byte[] result = new byte[25];
for ( char ch : text.toCharArray() ) {
int index = ALPHABET.indexOf(ch);
if ( index == -1 ) {
throw new AssertionError("Invalid character found in bitcoin address: " + ch);
}
for ( int i = result.length - 1; i > 0; i-- ) {
index += 58 * (int) ( result[i] & 0xFF );
result[i] = (byte) ( index & 0xFF );
index >>= 8;
}
if ( index != 0 ) {
throw new AssertionError("Bitcoin address is too long");
}
}
return result;
}
private static byte[] hexToBytes(String text) {
byte[] bytes = new byte[text.length() / 2];
for ( int i = 0; i < text.length(); i += 2 ) {
final int firstDigit = Character.digit(text.charAt(i), 16);
final int secondDigit = Character.digit(text.charAt(i + 1), 16);
bytes[i / 2] = (byte) ( ( firstDigit << 4 ) + secondDigit );
}
return bytes;
}
 
private static final String ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
 
}
</syntaxhighlight>
{{ out }}
<pre>
1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i : true
1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62j : false
1Q1pE5vPGEEMqRcVRMbtBK842Y6Pzo6nK9 : true
1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62X : false
1ANNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i : false
</pre>
 
=={{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,357:
for (addr, corr) in addresses
println("Address: $addr\nExpected: $corr\tChecked: ", checkbcaddress(addr))
end</langsyntaxhighlight>
 
{{out}}
Line 1,212 ⟶ 1,386:
Address: 1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62iz
Expected: false Checked: false</pre>
 
=={{header|Kotlin}}==
{{trans|Java}}
<langsyntaxhighlight lang="scala">import java.security.MessageDigest
 
object Bitcoin {
Line 1,274 ⟶ 1,447:
for (address in addresses)
println("${address.padEnd(36)} -> ${if (Bitcoin.validateAddress(address)) "valid" else "invalid"}")
}</langsyntaxhighlight>
 
{{out}}
Line 1,292 ⟶ 1,465:
1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62I -> invalid
</pre>
 
=={{header|Mathematica}} / {{header|Wolfram Language}}==
<langsyntaxhighlight Mathematicalang="mathematica">chars = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; data =
IntegerDigits[
FromDigits[
Line 1,303 ⟶ 1,475:
Hash[FromCharacterCode[
IntegerDigits[Hash[FromCharacterCode[data[[;; -5]]], "SHA256"],
256, 32]], "SHA256"], 256, 32][[;; 4]]</langsyntaxhighlight>
{{in}}
<pre>1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i
Line 1,310 ⟶ 1,482:
<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,487:
===Using “libssl”===
 
<langsyntaxhighlight lang="nim">import algorithm
 
const SHA256Len = 32
Line 1,396 ⟶ 1,567:
 
main()
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,414 ⟶ 1,585:
===Using “nimcrypto”===
{{libheader|nimcrypto}}
<langsyntaxhighlight Nimlang="nim">import nimcrypto
import strformat
 
Line 1,492 ⟶ 1,663:
 
for vector in testVectors:
vector.checkValidity()</langsyntaxhighlight>
 
{{out}}
Line 1,507 ⟶ 1,678:
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,761:
Out.Bool(Valid("1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62I"));Out.Ln
END BitcoinAddress.
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,600 ⟶ 1,770:
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,802:
(pack 'C*', @byte[21..24]) eq
substr sha256(sha256 pack 'C*', @byte[0..20]), 0, 4;
}</langsyntaxhighlight>
 
=={{header|Phix}}==
<!--<langsyntaxhighlight Phixlang="phix">(phixonline)-->
<span style="color: #000080;font-style:italic;">--
-- demo\rosetta\bitcoin_address_validation.exw
Line 1,720 ⟶ 1,888:
<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>
<!--</langsyntaxhighlight>-->
(No output other than "done" since all tests pass)
 
=={{header|PHP}}==
<langsyntaxhighlight lang="php">
function validate($address){
$decoded = decodeBase58($address);
Line 1,782 ⟶ 1,949:
main();
 
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,791 ⟶ 1,958:
1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62I: invalid character found
</pre>
 
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(load "sha256.l")
 
(setq *Alphabet
Line 1,822 ⟶ 1,988:
(valid "1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62!")
(valid "1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62iz")
(valid "1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62izz") ) )</langsyntaxhighlight>
 
=={{header|PureBasic}}==
<syntaxhighlight lang="purebasic">
<lang PureBasic>
; using PureBasic 5.50 (x64)
EnableExplicit
Line 1,903 ⟶ 2,068:
EndIf
 
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,911 ⟶ 2,076:
1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62I -> Invalid
</pre>
 
=={{header|Python}}==
<langsyntaxhighlight lang="python">from hashlib import sha256
 
digits58 = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
Line 1,930 ⟶ 2,094:
 
print(check_bc('1AGNa15ZQXAZUgFiqJ3i7Z2DPU2J6hW62i'))
print(check_bc("17NdbrSGoUotzeGCcMMCqnFkEvLymoou9j"))</langsyntaxhighlight>
 
{{out}}
Line 1,940 ⟶ 2,104:
: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,993 ⟶ 2,156:
(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::SHA256::Native;
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,013 ⟶ 2,182:
/;
say "Here is a bitcoin address: 1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i" ~~ $bitcoin-address;</langsyntaxhighlight>
{{out}}
<pre>「1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i」</pre>
 
=={{header|Ruby}}==
<langsyntaxhighlight lang="ruby">
# Validate Bitcoin address
#
Line 2,035 ⟶ 2,203:
(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,047 ⟶ 2,215:
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,106 ⟶ 2,273:
Ok(res)
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 2,114 ⟶ 2,281:
false
</pre>
 
=={{header|Scala}}==
<langsyntaxhighlight Scalalang="scala">import java.security.MessageDigest
import java.util.Arrays.copyOfRange
 
Line 2,182 ⟶ 2,348:
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,193 ⟶ 2,358:
No external library is needed.
 
<langsyntaxhighlight lang="seed7">$ include "seed7_05.s7i";
include "msgdigest.s7i";
include "encoding.s7i";
Line 2,242 ⟶ 2,407:
checkValidationFunction("i55j", FALSE); # wrong length
checkValidationFunction("16UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM", TRUE); # okay
end func;</langsyntaxhighlight>
 
{{out}}
Line 2,266 ⟶ 2,431:
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,302 ⟶ 2,466:
}
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,311 ⟶ 2,475:
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,341 ⟶ 2,504:
else return 2
fi
}</langsyntaxhighlight>
 
=={{header|Wren}}==
{{trans|Kotlin}}
Line 2,348 ⟶ 2,510:
{{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,409 ⟶ 2,571:
for (address in addresses) {
Fmt.print("$-36s -> $s", address, Bitcoin.validateAddress(address) ? "valid" : "invalid")
}</langsyntaxhighlight>
 
{{out}}
Line 2,430 ⟶ 2,592:
=={{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,454 ⟶ 2,616:
(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}}
913

edits