| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | package Encode::Base58::GMP; | 
| 2 | 7 |  |  | 7 |  | 609857 | use strict; | 
|  | 7 |  |  |  |  | 17 |  | 
|  | 7 |  |  |  |  | 231 |  | 
| 3 | 7 |  |  | 7 |  | 35 | use warnings; | 
|  | 7 |  |  |  |  | 15 |  | 
|  | 7 |  |  |  |  | 166 |  | 
| 4 | 7 |  |  | 7 |  | 179 | use 5.008_009; | 
|  | 7 |  |  |  |  | 39 |  | 
|  | 7 |  |  |  |  | 422 |  | 
| 5 |  |  |  |  |  |  | our $VERSION   = '1.00'; | 
| 6 |  |  |  |  |  |  |  | 
| 7 | 7 |  |  | 7 |  | 37 | use base         qw(Exporter); | 
|  | 7 |  |  |  |  | 12 |  | 
|  | 7 |  |  |  |  | 388 |  | 
| 8 |  |  |  |  |  |  | our @EXPORT    = qw(encode_base58 decode_base58); | 
| 9 |  |  |  |  |  |  | our @EXPORT_OK = qw(base58_from_to base58_flickr_to_gmp base58_gmp_to_flickr md5_base58); | 
| 10 |  |  |  |  |  |  |  | 
| 11 | 7 |  |  | 7 |  | 784 | use Carp; | 
|  | 7 |  |  |  |  | 15 |  | 
|  | 7 |  |  |  |  | 614 |  | 
| 12 | 7 |  |  | 7 |  | 39 | use Digest::MD5  qw(md5_hex); | 
|  | 7 |  |  |  |  | 12 |  | 
|  | 7 |  |  |  |  | 391 |  | 
| 13 | 7 |  |  | 7 |  | 14898 | use Math::GMPz   qw(Rmpz_get_str); | 
|  | 0 |  |  |  |  |  |  | 
|  | 0 |  |  |  |  |  |  | 
| 14 |  |  |  |  |  |  | use Scalar::Util qw(blessed); | 
| 15 |  |  |  |  |  |  |  | 
| 16 |  |  |  |  |  |  | sub encode_base58 { | 
| 17 |  |  |  |  |  |  | my ($int, $alphabet, $len) = @_; | 
| 18 |  |  |  |  |  |  |  | 
| 19 |  |  |  |  |  |  | my $base58 = blessed($int) && $int->isa('Math::GMPz') ? | 
| 20 |  |  |  |  |  |  | Rmpz_get_str($int, 58) : | 
| 21 |  |  |  |  |  |  | Rmpz_get_str(Math::GMPz->new($int), 58); | 
| 22 |  |  |  |  |  |  |  | 
| 23 |  |  |  |  |  |  | if ($len && $len =~ m|\A[0-9]+\Z|) { | 
| 24 |  |  |  |  |  |  | $base58 = sprintf("%0${len}s",$base58); | 
| 25 |  |  |  |  |  |  | } | 
| 26 |  |  |  |  |  |  |  | 
| 27 |  |  |  |  |  |  | $alphabet && lc $alphabet eq 'gmp' ? | 
| 28 |  |  |  |  |  |  | $base58 : | 
| 29 |  |  |  |  |  |  | base58_from_to($base58,'gmp',$alphabet||'flickr'); | 
| 30 |  |  |  |  |  |  | } | 
| 31 |  |  |  |  |  |  |  | 
| 32 |  |  |  |  |  |  | sub decode_base58 { | 
| 33 |  |  |  |  |  |  | my ($base58, $alphabet) = @_; | 
| 34 |  |  |  |  |  |  |  | 
| 35 |  |  |  |  |  |  | unless ($alphabet && lc $alphabet eq 'gmp') { | 
| 36 |  |  |  |  |  |  | $base58 = base58_from_to($base58,$alphabet||'flickr','gmp'); | 
| 37 |  |  |  |  |  |  | } | 
| 38 |  |  |  |  |  |  |  | 
| 39 |  |  |  |  |  |  | Math::GMPz->new($base58, 58); | 
| 40 |  |  |  |  |  |  | } | 
| 41 |  |  |  |  |  |  |  | 
| 42 |  |  |  |  |  |  | sub base58_from_to { | 
| 43 |  |  |  |  |  |  | my ($base58, $from_alphabet, $to_alphabet) = @_; | 
| 44 |  |  |  |  |  |  |  | 
| 45 |  |  |  |  |  |  | my $alphabets = { | 
| 46 |  |  |  |  |  |  | bitcoin => '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz', | 
| 47 |  |  |  |  |  |  | flickr  => '123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ', | 
| 48 |  |  |  |  |  |  | gmp     => '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv' | 
| 49 |  |  |  |  |  |  | }; | 
| 50 |  |  |  |  |  |  |  | 
| 51 |  |  |  |  |  |  | $from_alphabet = lc($from_alphabet||'flickr'); | 
| 52 |  |  |  |  |  |  | $to_alphabet   = lc($to_alphabet  ||'flickr'); | 
| 53 |  |  |  |  |  |  |  | 
| 54 |  |  |  |  |  |  | return $base58 if $from_alphabet eq $to_alphabet; | 
| 55 |  |  |  |  |  |  |  | 
| 56 |  |  |  |  |  |  | my $from_digits = $alphabets->{$from_alphabet} | 
| 57 |  |  |  |  |  |  | or croak("Encode::Base58::GMP::from_to called with invalid from_alphabet [$from_alphabet]"); | 
| 58 |  |  |  |  |  |  | my $to_digits   = $alphabets->{$to_alphabet} | 
| 59 |  |  |  |  |  |  | or croak("Encode::Base58::GMP::from_to called with invalid to_alphabet [$to_alphabet]"); | 
| 60 |  |  |  |  |  |  |  | 
| 61 |  |  |  |  |  |  | if ($from_alphabet eq 'gmp') { | 
| 62 |  |  |  |  |  |  | if ($to_alphabet eq 'flickr') { | 
| 63 |  |  |  |  |  |  | $base58 =~ y|0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv|123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ|; | 
| 64 |  |  |  |  |  |  | } else { | 
| 65 |  |  |  |  |  |  | $base58 =~ y|0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv|123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz|; | 
| 66 |  |  |  |  |  |  | } | 
| 67 |  |  |  |  |  |  | } elsif ($from_alphabet eq 'flickr') { | 
| 68 |  |  |  |  |  |  | if ($to_alphabet eq 'gmp') { | 
| 69 |  |  |  |  |  |  | $base58 =~ y|123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ|0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv|; | 
| 70 |  |  |  |  |  |  | } else { | 
| 71 |  |  |  |  |  |  | $base58 =~ y|123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ|123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz|; | 
| 72 |  |  |  |  |  |  | } | 
| 73 |  |  |  |  |  |  | } else { | 
| 74 |  |  |  |  |  |  | if ($to_alphabet eq 'gmp') { | 
| 75 |  |  |  |  |  |  | $base58 =~ y|123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz|0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv|; | 
| 76 |  |  |  |  |  |  | } else { | 
| 77 |  |  |  |  |  |  | $base58 =~ y|123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz|123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ|; | 
| 78 |  |  |  |  |  |  | } | 
| 79 |  |  |  |  |  |  | } | 
| 80 |  |  |  |  |  |  | return $base58; | 
| 81 |  |  |  |  |  |  | } | 
| 82 |  |  |  |  |  |  |  | 
| 83 |  |  |  |  |  |  | sub base58_gmp_to_flickr { | 
| 84 |  |  |  |  |  |  | return base58_from_to(shift||'','gmp','flickr'); | 
| 85 |  |  |  |  |  |  | } | 
| 86 |  |  |  |  |  |  |  | 
| 87 |  |  |  |  |  |  | sub base58_flickr_to_gmp { | 
| 88 |  |  |  |  |  |  | return base58_from_to(shift||'','flickr','gmp'); | 
| 89 |  |  |  |  |  |  | } | 
| 90 |  |  |  |  |  |  |  | 
| 91 |  |  |  |  |  |  | sub md5_base58 { | 
| 92 |  |  |  |  |  |  | encode_base58('0x'.md5_hex(shift), shift, 22); | 
| 93 |  |  |  |  |  |  | } | 
| 94 |  |  |  |  |  |  |  | 
| 95 |  |  |  |  |  |  | 1; | 
| 96 |  |  |  |  |  |  |  | 
| 97 |  |  |  |  |  |  | # ABSTRACT: High speed Base58 encoding using GMP with BigInt and MD5 support | 
| 98 |  |  |  |  |  |  |  | 
| 99 |  |  |  |  |  |  | =head1 NAME | 
| 100 |  |  |  |  |  |  |  | 
| 101 |  |  |  |  |  |  | Encode::Base58::GMP - High speed Base58 encoding using GMP with BigInt and MD5 support | 
| 102 |  |  |  |  |  |  |  | 
| 103 |  |  |  |  |  |  | For version 1.0 upgrades, please read the INCOMPATIBLE CHANGES section below. | 
| 104 |  |  |  |  |  |  |  | 
| 105 |  |  |  |  |  |  | =head1 SYNOPSIS | 
| 106 |  |  |  |  |  |  |  | 
| 107 |  |  |  |  |  |  | use Encode::Base58::GMP; | 
| 108 |  |  |  |  |  |  |  | 
| 109 |  |  |  |  |  |  | # Encode Int as Base58 | 
| 110 |  |  |  |  |  |  | encode_base58(12345);                        # => 4ER string | 
| 111 |  |  |  |  |  |  | encode_base58('0x3039');                     # => 4ER string | 
| 112 |  |  |  |  |  |  | encode_base58(Math::GMPz->new('0x3039'));    # => 4ER string | 
| 113 |  |  |  |  |  |  |  | 
| 114 |  |  |  |  |  |  | # Encode Int as Base58 using GMP alphabet | 
| 115 |  |  |  |  |  |  | encode_base58(12345,'bitcoin');              # => 4fr string | 
| 116 |  |  |  |  |  |  | encode_base58(12345,'gmp');                  # => 3cn string | 
| 117 |  |  |  |  |  |  |  | 
| 118 |  |  |  |  |  |  | # Decode Base58 as Math::GMPz Int | 
| 119 |  |  |  |  |  |  | decode_base58('4ER');                        # => 12345 Math::GMPz object | 
| 120 |  |  |  |  |  |  | int decode_base58('4ER');                    # => 12345 integer | 
| 121 |  |  |  |  |  |  |  | 
| 122 |  |  |  |  |  |  | # Decode Base58 as Math::GMPz Int using GMP alphabet | 
| 123 |  |  |  |  |  |  | decode_base58('4fr','bitcoin');              # => 12345 Math::GMPz object | 
| 124 |  |  |  |  |  |  | decode_base58('3cn','gmp');                  # => 12345 Math::GMPz object | 
| 125 |  |  |  |  |  |  |  | 
| 126 |  |  |  |  |  |  | # MD5 Base58 Digest | 
| 127 |  |  |  |  |  |  | md5_base58('foo@bar.com');                   # => w6fdCRXnUXyz7EtDn5TgN9 | 
| 128 |  |  |  |  |  |  |  | 
| 129 |  |  |  |  |  |  | # Convert between alphabets for Bitcoin, Flickr and GMP | 
| 130 |  |  |  |  |  |  | base58_from_to('123456789abcdefghijk','flickr','gmp') # => 0123456789ABCDEFGHIJ | 
| 131 |  |  |  |  |  |  | base58_from_to('0123456789ABCDEFGHIJ','gmp','flickr') # => 123456789abcdefghijk | 
| 132 |  |  |  |  |  |  |  | 
| 133 |  |  |  |  |  |  | # Convert between Flickr and GMP - Deprecated | 
| 134 |  |  |  |  |  |  | base58_flickr_to_gmp('123456789abcdefghijk') # => 0123456789ABCDEFGHIJ | 
| 135 |  |  |  |  |  |  | base58_gmp_to_flickr('0123456789ABCDEFGHIJ') # => 123456789abcdefghijk | 
| 136 |  |  |  |  |  |  |  | 
| 137 |  |  |  |  |  |  | =head1 DESCRIPTION | 
| 138 |  |  |  |  |  |  |  | 
| 139 |  |  |  |  |  |  | Encode::Base58::GMP is a Base58 encoder/decoder implementation using the GNU | 
| 140 |  |  |  |  |  |  | Multiple Precision Arithmetic Library (GMP) with transcoding between | 
| 141 |  |  |  |  |  |  | Flickr, Bitcoin and GMP Base58 implementations. The Flickr alphabet is the | 
| 142 |  |  |  |  |  |  | default and used when no alphabet is provided. | 
| 143 |  |  |  |  |  |  |  | 
| 144 |  |  |  |  |  |  | Flickr Alphabet: [0-9a-zA-Z] excluding [0OIl] to improve human readability | 
| 145 |  |  |  |  |  |  |  | 
| 146 |  |  |  |  |  |  | Bitcoin Alphabet: [0-9A-Za-z] excluding [0OIl] to improve human readability | 
| 147 |  |  |  |  |  |  |  | 
| 148 |  |  |  |  |  |  | GMP Alphabet: [0-9A-Za-v] | 
| 149 |  |  |  |  |  |  |  | 
| 150 |  |  |  |  |  |  | The encode_base58, decode_base58 and md5_base58 methods support an alphabet | 
| 151 |  |  |  |  |  |  | parameter which can be set to the supported alphabets ['bitcoin', 'flickr', | 
| 152 |  |  |  |  |  |  | 'gmp'] to indicate the value to be encoded or decoded. | 
| 153 |  |  |  |  |  |  |  | 
| 154 |  |  |  |  |  |  | =head2 Requirements | 
| 155 |  |  |  |  |  |  |  | 
| 156 |  |  |  |  |  |  | This module requires GMP 4.2.0 and above. Prior versions are limited to Base36. | 
| 157 |  |  |  |  |  |  |  | 
| 158 |  |  |  |  |  |  | Perl 5.8.9 or above is required to ensure proper bigint handling. If you are not | 
| 159 |  |  |  |  |  |  | using bigint numbers, it may be possible to skip the bigint tests and do a force | 
| 160 |  |  |  |  |  |  | install; however, lower Perl versions are not supported. | 
| 161 |  |  |  |  |  |  |  | 
| 162 |  |  |  |  |  |  | =head1 FUNCTIONS | 
| 163 |  |  |  |  |  |  |  | 
| 164 |  |  |  |  |  |  | =head2 encode_base58 ( $number [, $alphabet ] ) | 
| 165 |  |  |  |  |  |  |  | 
| 166 |  |  |  |  |  |  | This routine encodes a $number in Base58. $number can be a Math::GMPz object | 
| 167 |  |  |  |  |  |  | or a binary, octal, decimal or hexidecimal number. Binary, octal and hexidecimal | 
| 168 |  |  |  |  |  |  | string literals must be prefixed with 0[Bb]/0/0[Xx] respectively. The Flickr | 
| 169 |  |  |  |  |  |  | alphabet is used unless $alphabet is set to 'gmp'. | 
| 170 |  |  |  |  |  |  |  | 
| 171 |  |  |  |  |  |  | =head2 decode_base58 ( $base58 [, $alphabet ] ) | 
| 172 |  |  |  |  |  |  |  | 
| 173 |  |  |  |  |  |  | This routine decodes a Base58 value and returns a Math::GMPz object. Use int | 
| 174 |  |  |  |  |  |  | on the return value to convert the Math::GMPz object to an integer. | 
| 175 |  |  |  |  |  |  | The Flickr alphabet is used unless $alphabet is set to 'gmp'. | 
| 176 |  |  |  |  |  |  |  | 
| 177 |  |  |  |  |  |  | =head2 base58_from_to( $base58, $from_alphabet, $to_alphabet ) | 
| 178 |  |  |  |  |  |  |  | 
| 179 |  |  |  |  |  |  | This routine encodes a Base58 string from one encoding to another encoding. | 
| 180 |  |  |  |  |  |  | This routing is not exported by default. | 
| 181 |  |  |  |  |  |  |  | 
| 182 |  |  |  |  |  |  | =head2 base58_flickr_to_gmp( $base58_as_flickr ) | 
| 183 |  |  |  |  |  |  |  | 
| 184 |  |  |  |  |  |  | This routine converts a Flickr Base58 string to a GMP Base58 string. This | 
| 185 |  |  |  |  |  |  | routine is not exported by default. | 
| 186 |  |  |  |  |  |  |  | 
| 187 |  |  |  |  |  |  | =head2 base58_gmp_to_flickr( $base58_as_gmp ) | 
| 188 |  |  |  |  |  |  |  | 
| 189 |  |  |  |  |  |  | This routine converts a GMP Base58 string to a Flickr Base58 string. This | 
| 190 |  |  |  |  |  |  | routine is not exported by default. | 
| 191 |  |  |  |  |  |  |  | 
| 192 |  |  |  |  |  |  | =head2 md5_base58( $data [, $alphabet ] ) | 
| 193 |  |  |  |  |  |  |  | 
| 194 |  |  |  |  |  |  | This routine returns a MD5 digest in Base58. This routine is not exported | 
| 195 |  |  |  |  |  |  | by default. | 
| 196 |  |  |  |  |  |  |  | 
| 197 |  |  |  |  |  |  | =head1 CHANGES | 
| 198 |  |  |  |  |  |  |  | 
| 199 |  |  |  |  |  |  | =item 1.00 April 30, 2013 | 
| 200 |  |  |  |  |  |  |  | 
| 201 |  |  |  |  |  |  | Add Bitcoin alphabet support. | 
| 202 |  |  |  |  |  |  |  | 
| 203 |  |  |  |  |  |  | Add zero-padding for md5_base58. This is an incompatible change from version | 
| 204 |  |  |  |  |  |  | 0.09. | 
| 205 |  |  |  |  |  |  |  | 
| 206 |  |  |  |  |  |  | =head1 INCOMPATIBLE CHANGES | 
| 207 |  |  |  |  |  |  |  | 
| 208 |  |  |  |  |  |  | =item 1.00 April 30, 2013 | 
| 209 |  |  |  |  |  |  |  | 
| 210 |  |  |  |  |  |  | md5_base58 is now zero-padded to provide a fixed-length Base58 string. Prior | 
| 211 |  |  |  |  |  |  | versions were not padding with leading zero values. | 
| 212 |  |  |  |  |  |  |  | 
| 213 |  |  |  |  |  |  | =head1 SEE ALSO | 
| 214 |  |  |  |  |  |  |  | 
| 215 |  |  |  |  |  |  | L, L, L, L | 
| 216 |  |  |  |  |  |  |  | 
| 217 |  |  |  |  |  |  | L | 
| 218 |  |  |  |  |  |  |  | 
| 219 |  |  |  |  |  |  | L (Base58 using GMP in Ruby) | 
| 220 |  |  |  |  |  |  |  | 
| 221 |  |  |  |  |  |  | L (Base62 using GMP in PHP) | 
| 222 |  |  |  |  |  |  |  | 
| 223 |  |  |  |  |  |  | =head1 AUTHOR | 
| 224 |  |  |  |  |  |  |  | 
| 225 |  |  |  |  |  |  | John Wang , L | 
| 226 |  |  |  |  |  |  |  | 
| 227 |  |  |  |  |  |  | =head1 COPYRIGHT AND LICENSE (The MIT License) | 
| 228 |  |  |  |  |  |  |  | 
| 229 |  |  |  |  |  |  | Copyright (c) 2011-2013 John Wang | 
| 230 |  |  |  |  |  |  |  | 
| 231 |  |  |  |  |  |  | Permission is hereby granted, free of charge, to any person obtaining | 
| 232 |  |  |  |  |  |  | a copy of this software and associated documentation files (the | 
| 233 |  |  |  |  |  |  | "Software"), to deal in the Software without restriction, including | 
| 234 |  |  |  |  |  |  | without limitation the rights to use, copy, modify, merge, publish, | 
| 235 |  |  |  |  |  |  | distribute, sublicense, and/or sell copies of the Software, and to | 
| 236 |  |  |  |  |  |  | permit persons to whom the Software is furnished to do so, subject to | 
| 237 |  |  |  |  |  |  | the following conditions: | 
| 238 |  |  |  |  |  |  |  | 
| 239 |  |  |  |  |  |  | The above copyright notice and this permission notice shall be | 
| 240 |  |  |  |  |  |  | included in all copies or substantial portions of the Software. | 
| 241 |  |  |  |  |  |  |  | 
| 242 |  |  |  |  |  |  | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | 
| 243 |  |  |  |  |  |  | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | 
| 244 |  |  |  |  |  |  | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | 
| 245 |  |  |  |  |  |  | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | 
| 246 |  |  |  |  |  |  | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | 
| 247 |  |  |  |  |  |  | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | 
| 248 |  |  |  |  |  |  | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | 
| 249 |  |  |  |  |  |  |  | 
| 250 |  |  |  |  |  |  | =cut |