Bitcoin/address validation: Difference between revisions
Content deleted Content added
m actually RIPEMD-160 is not needed for address validation |
added perl solution |
||
Line 4: | Line 4: | ||
You can use a digest library for [[SHA-256]]. |
You can use a digest library for [[SHA-256]]. |
||
==Perl== |
|||
<lang perl>our @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 |
|||
a b c d e f g h i j k m n o p q r s t u v w x y z |
|||
}; |
|||
our %b58 = map { $b58[$_] => $_ } 0 .. 57; |
|||
our $b58 = qr/[@{[join '', @b58]}]/x; |
|||
sub decode { |
|||
use bigint; use integer; |
|||
shift =~ m/$b58\Z/p ? $b58{${^MATCH}} + 58*decode(${^PREMATCH}) : 0 |
|||
} |
|||
sub check_bitcoin_address { |
|||
use Digest::SHA qw(sha256 sha256_hex); |
|||
my $value = my $decode = decode my $addr = shift; |
|||
my @hash; for (1 .. 25) { push @hash, $value % 256; $value /= 256 } |
|||
@hash = reverse @hash; |
|||
my $checksum = join '', map { sprintf "%02x", $_ } @hash[21..24]; |
|||
die unless $checksum eq |
|||
substr sha256_hex(sha256 pack 'C*', @hash[0..20]), 0, 8; |
|||
}</lang> |
|||
==Unix shell== |
==Unix shell== |
Revision as of 23:56, 27 November 2012
Bitcoin/address validation is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.
Write a program that takes a bitcoin address as argument, and checks whether or not this address is valid. The program can either return a boolean value or throw an exception when not valid.
You can use a digest library for SHA-256.
Perl
<lang perl>our @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 a b c d e f g h i j k m n o p q r s t u v w x y z
}; our %b58 = map { $b58[$_] => $_ } 0 .. 57; our $b58 = qr/[@{[join , @b58]}]/x;
sub decode {
use bigint; use integer; shift =~ m/$b58\Z/p ? $b58{${^MATCH}} + 58*decode(${^PREMATCH}) : 0
}
sub check_bitcoin_address {
use Digest::SHA qw(sha256 sha256_hex); my $value = my $decode = decode my $addr = shift; my @hash; for (1 .. 25) { push @hash, $value % 256; $value /= 256 } @hash = reverse @hash; my $checksum = join , map { sprintf "%02x", $_ } @hash[21..24]; die unless $checksum eq substr sha256_hex(sha256 pack 'C*', @hash[0..20]), 0, 8;
}</lang>
Unix shell
<lang bash>base58=({1..9} {A..H} {J..N} {P..Z} {a..k} {m..z}) bitcoinregex="^[$(printf "%s" "${base58[@]}")]{34}$"
decodeBase58() {
local s=$1 for i in {0..57} do s="${s//${base58[i]}/ $i}" done dc <<< "16o0d${s// /+58*}+f"
}
checksum() {
xxd -p -r <<<"$1" | openssl dgst -sha256 -binary | openssl dgst -sha256 -binary | xxd -p -c 80 | head -c 8
}
checkBitcoinAddress() {
if "$1" =~ $bitcoinregex then h=$(decodeBase58 "$1") checksum "00${h::${#h}-8}" | grep -qi "^${h: -8}$" else return 2 fi
}</lang>