Bitcoin/public point to address: Difference between revisions

→‎{{header|Perl}}: complete rewrite. Shorter, faster, less data munging
(Added Haskell version)
(→‎{{header|Perl}}: complete rewrite. Shorter, faster, less data munging)
Line 299:
 
=={{header|Perl}}==
Here we'll use the standard Digest::SHA module, and the CPAN-available Crypt::RIPEMD160 and Encode::Base58::GMP.
<lang perl>use bigint;
use Crypt::RIPEMD160;
use Digest::SHA qw(sha256);
use Encode::Base58::GMP;
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
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
};
my $b58 = qr/[@{[join '', @b58]}]/x;
 
sub public_point_to_address {
sub encode { my $_ = shift; $_ < 58 ? $b58[$_] : encode($_/58) . $b58[$_%58] }
my $ec = '04' . join '', @_; # EC: concat x and y to one string and prepend '04' magic value
 
my @byte = map { hex } unpack('(a2)65', $ec); # transform the hex values to list of decimal values
sub public_point_to_address {
my $octets = pack 'C*', @byte; # actually build the octet stream
my ($x, $y) = @_;
my $hash = chr(0) . Crypt::RIPEMD160->hash(sha256 join$octets); '', map {# chr }perform @byteRIPEMD160(SHA256(octets);
my @byte;
my $checksum = substr sha256(sha256 chr(0).$hash), 0, 4; # build the checksum
for (1 .. 32) { push @byte, $y % 256; $y /= 256 }
my $hex = '0x' . join '', # build hex value of hash and checksum
for (1 .. 32) { push @byte, $x % 256; $x /= 256 }
map { sprintf("%02X", ord) }
@byte = (4, reverse @byte);
($hash.$checksum) =~ /./gs;
my $hash = Crypt::RIPEMD160->hash(sha256 join '', map { chr } @byte);
return '1' . sprintf "%32s", encode_base58($hex, 'bitcoin'); # Do the Base58 encoding, prepend "1"
my $checksum = substr sha256(sha256 chr(0).$hash), 0, 4;
my $value = 0;
for ( (chr(0).$hash.$checksum) =~ /./gs ) { $value = $value * 256 + ord }
(sprintf "%33s", encode $value) =~ y/ /1/r;
}
 
printsay public_point_to_address map {hex "0x$_"} <DATA>;
'50863AD64A87AE8A2FE83C1AF1A8403CB53F53E486D8511DAD8A04887E5B2352',
 
'2CD470243453A299FA9E77237716103ABC11A1DF38855ED6F2EE187E9C582BA6'
__DATA__
;
50863AD64A87AE8A2FE83C1AF1A8403CB53F53E486D8511DAD8A04887E5B2352
2CD470243453A299FA9E77237716103ABC11A1DF38855ED6F2EE187E9C582BA6
</lang>
{{out}}
Anonymous user