File Coverage

blib/lib/Crypt/Misc.pm
Criterion Covered Total %
statement 181 181 100.0
branch 68 88 77.2
condition 24 37 64.8
subroutine 34 34 100.0
pod 18 18 100.0
total 325 358 90.7


line stmt bran cond sub pod time code
1             package Crypt::Misc;
2              
3 19     19   182063 use strict;
  19         26  
  19         564  
4 19     19   64 use warnings;
  19         22  
  19         1346  
5             our $VERSION = '0.088_004';
6              
7             require Exporter; our @ISA = qw(Exporter); ### use Exporter 5.57 'import';
8 19     19   90 use Carp 'croak';
  19         45  
  19         2290  
9             our %EXPORT_TAGS = ( all => [qw(encode_b64 decode_b64
10             encode_b64u decode_b64u
11             encode_b58b decode_b58b
12             encode_b58f decode_b58f
13             encode_b58r decode_b58r
14             encode_b58t decode_b58t
15             encode_b58s decode_b58s
16             encode_b32r decode_b32r
17             encode_b32b decode_b32b
18             encode_b32z decode_b32z
19             encode_b32c decode_b32c
20             pem_to_der der_to_pem
21             read_rawfile write_rawfile
22             slow_eq is_v4uuid random_v4uuid
23             is_uuid random_v7uuid
24             increment_octets_be increment_octets_le
25             )] );
26             our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
27             our @EXPORT = qw();
28              
29 19     19   787 use CryptX;
  19         26  
  19         421  
30 19     19   3865 use Crypt::Digest 'digest_data';
  19         37  
  19         966  
31 19     19   6712 use Crypt::Mode::CBC;
  19         43  
  19         447  
32 19     19   6429 use Crypt::Mode::CFB;
  19         38  
  19         481  
33 19     19   6676 use Crypt::Mode::ECB;
  19         41  
  19         428  
34 19     19   6343 use Crypt::Mode::OFB;
  19         40  
  19         441  
35 19     19   89 use Crypt::Cipher;
  19         25  
  19         285  
36 19     19   6755 use Crypt::PRNG 'random_bytes';
  19         39  
  19         983  
37 19     19   78 use Time::HiRes (); # perl core module
  19         129  
  19         47268  
38              
39             sub _encode_b58 {
40 292     292   833 my ($bytes, $alphabet) = @_;
41              
42 292 100       830 return undef if !defined $bytes;
43 291 100       729 return '' if length($bytes) == 0;
44              
45             # handle leading zero-bytes
46 290         446 my $base58 = '';
47 290 100       1077 if ($bytes =~ /^(\x00+)/) {
48 80         302 $base58 = ('0' x length($1));
49             }
50 290         4414 $base58 .= _bin_to_radix($bytes, 58);
51              
52 290 50       772 if (defined $alphabet) {
53 290         435 my $default = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv";
54 290 50       1231 return undef if $alphabet !~ /^[a-zA-Z0-9]{58}$/;
55 290         457 my %map;
56 290         12030 @map{split //, $default} = split //, $alphabet;
57 290         2631 $base58 = join '', map { $map{$_} } split //, $base58;
  5545         11375  
58             }
59              
60 290         1576 return $base58;
61             }
62              
63             sub _decode_b58 {
64 294     294   659 my ($base58, $alphabet) = @_;
65              
66 294 100       748 return undef if !defined $base58;
67 293 100       617 return '' if length($base58) == 0;
68              
69 292         447 my $default = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv";
70 292 50       591 if (defined $alphabet) {
71 292 100 66     14802 return undef if $alphabet !~ /^[a-zA-Z0-9]{58}$/ || $base58 !~ /^[$alphabet]+$/;
72 290         723 my %map;
73 290         8826 @map{split //, $alphabet} = split //, $default;
74 290         2349 $base58 = join '', map { $map{$_} } split //, $base58;
  5545         9668  
75             }
76 290 50       2421 return undef if $base58 !~ /^[$default]+$/;
77              
78             # handle leading zeroes
79 290         477 my $bytes = '';
80 290 100       745 if ($base58 =~ /^(0+)(.*)$/) {
81 80         221 $base58 = $2;
82 80         185 $bytes = ("\x00" x length($1));
83             }
84 290 100 66     2368 $bytes .= _radix_to_bin($base58, 58) if defined $base58 && length($base58) > 0;
85              
86 290         1540 return $bytes;
87             }
88              
89 62     62 1 664 sub decode_b58b { _decode_b58(shift, "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz") } # Bitcoin
90 58     58 1 139 sub decode_b58f { _decode_b58(shift, "123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ") } # Flickr
91 58     58 1 114 sub decode_b58r { _decode_b58(shift, "rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz") } # Ripple
92 58     58 1 126 sub decode_b58t { _decode_b58(shift, "RPShNAF39wBUDnEGHJKLM4pQrsT7VWXYZ2bcdeCg65jkm8ofqi1tuvaxyz") } # Tipple
93 58     58 1 115 sub decode_b58s { _decode_b58(shift, "gsphnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCr65jkm8oFqi1tuvAxyz") } # Stellar
94              
95 60     60 1 271161 sub encode_b58b { _encode_b58(shift, "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz") } # Bitcoin
96 58     58 1 181 sub encode_b58f { _encode_b58(shift, "123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ") } # Flickr
97 58     58 1 198 sub encode_b58r { _encode_b58(shift, "rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz") } # Ripple
98 58     58 1 172 sub encode_b58t { _encode_b58(shift, "RPShNAF39wBUDnEGHJKLM4pQrsT7VWXYZ2bcdeCg65jkm8ofqi1tuvaxyz") } # Tipple
99 58     58 1 161 sub encode_b58s { _encode_b58(shift, "gsphnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCr65jkm8oFqi1tuvAxyz") } # Stellar
100              
101             sub pem_to_der {
102 28     28 1 1102 my ($data, $password) = @_;
103              
104 28         43 my ($begin, $obj1, $content, $end, $obj2);
105             # first try to load KEY (e.g. EC pem files might contain more parts)
106 28         244 ($begin, $obj1, $content, $end, $obj2) = $data =~ m/(----[- ]BEGIN ([^\r\n\-]+KEY)[ -]----)(.*?)(----[- ]END ([^\r\n\-]+)[ -]----)/s;
107             # if failed then try to load anything
108 28 100       96 ($begin, $obj1, $content, $end, $obj2) = $data =~ m/(----[- ]BEGIN ([^\r\n\-]+)[ -]----)(.*?)(----[- ]END ([^\r\n\-]+)[ -]----)/s unless defined $content;
109 28 50       53 return undef unless $content;
110 28 100 33     148 return undef if !defined($obj1) || !defined($obj2) || $obj1 ne $obj2;
      66        
111              
112 26         110 $content =~ s/^\s+//sg;
113 26         145 $content =~ s/\s+$//sg;
114 26         49 $content =~ s/\r\n/\n/sg; # CR-LF >> LF
115 26         37 $content =~ s/\r/\n/sg; # CR >> LF
116 26         37 $content =~ s/\\\n//sg; # \ + LF
117              
118 26         149 my ($headers, undef, $b64) = $content =~ /^(([^:]+:.*?\n)*)(.*)$/s;
119 26 50       49 return undef unless $b64;
120              
121 26         186 my $binary = decode_b64($b64);
122 26 50       47 return undef unless $binary;
123              
124 26         34 my ($ptype, $cipher_name, $iv_hex);
125 26   100     104 for my $h (split /\n/, ($headers||'')) {
126 20         44 my ($k, $v) = split /:\s*/, $h, 2;
127 20 100       33 $ptype = $v if $k eq 'Proc-Type';
128 20 100       61 ($cipher_name, $iv_hex) = $v =~ /^\s*(.*?)\s*,\s*([0-9a-fA-F]+)\s*$/ if $k eq 'DEK-Info';
129             }
130 26 50 66     86 if ($cipher_name && $iv_hex && $ptype && $ptype eq '4,ENCRYPTED') {
      66        
      33        
131 10 50       12 croak "FATAL: encrypted PEM but no password provided" unless defined $password;
132 10         30 my $iv = pack("H*", $iv_hex);
133 10         13 my ($mode, $klen) = _name2mode($cipher_name);
134 10         17 my $key = _password2key($password, $klen, $iv, 'MD5');
135 10         26 return $mode->decrypt($binary, $key, $iv);
136             }
137 16         11189 return $binary;
138             }
139              
140             sub der_to_pem {
141 37     37 1 13119 my ($data, $header_name, $password, $cipher_name) = @_;
142 37 100 100     708 croak "FATAL: der_to_pem invalid header name" unless defined $header_name && $header_name =~ /^[0-9A-Za-z ]+$/;
143 33         47 my $content = $data;
144 33         40 my @headers;
145              
146 33 100       69 if (defined $password) {
147 9   100     20 $cipher_name ||= 'AES-256-CBC';
148 9         16 my ($mode, $klen, $ilen) = _name2mode($cipher_name);
149 9         35 my $iv = random_bytes($ilen);
150 9         22 my $key = _password2key($password, $klen, $iv, 'MD5');
151 9         27 $content = $mode->encrypt($data, $key, $iv);
152 9         80 push @headers, 'Proc-Type: 4,ENCRYPTED', "DEK-Info: ".uc($cipher_name).",".unpack("H*", $iv);
153             }
154              
155 33         53 my $pem = "-----BEGIN $header_name-----\n";
156 33 100       74 if (@headers) {
157 9         26 $pem .= "$_\n" for @headers;
158 9         12 $pem .= "\n";
159             }
160 33         425 my @l = encode_b64($content) =~ /.{1,64}/g;
161 33         116 $pem .= join("\n", @l) . "\n";
162 33         50 $pem .= "-----END $header_name-----\n";
163 33         186 return $pem;
164             }
165              
166             sub read_rawfile {
167             # $data = read_rawfile($filename);
168 295     295 1 6777 my $f = shift;
169 295 50       2866 croak "FATAL: read_rawfile() non-existing file '$f'" unless -f $f;
170 295 50       10357 open my $fh, "<", $f or croak "FATAL: read_rawfile() cannot open file '$f': $!";
171 295         786 binmode $fh;
172 295         492 return do { local $/; <$fh> };
  295         1248  
  295         15687  
173             }
174              
175             sub write_rawfile {
176             # write_rawfile($filename, $data);
177 3 50   3 1 10 croak "FATAL: write_rawfile() no data" unless defined $_[1];
178 3 50       1044 open my $fh, ">", $_[0] or croak "FATAL: write_rawfile() cannot open file '$_[0]': $!";
179 3         13 binmode $fh;
180 3 50       46 print $fh $_[1] or croak "FATAL: write_rawfile() cannot write to '$_[0]': $!";
181 3 50       111 close $fh or croak "FATAL: write_rawfile() cannot close '$_[0]': $!";
182 3         20 return;
183             }
184              
185             ### slow_eq() is implemented in XS (CryptX.xs) using libtomcrypt's mem_neq()
186              
187             sub random_v4uuid() {
188             # Version 4 - random - UUID: xxxxxxxx-xxxx-4xxx-Yxxx-xxxxxxxxxxxx
189             # where x is any hexadecimal digit and Y is one of 8, 9, A, B (1000, 1001, 1010, 1011)
190             # e.g. f47ac10b-58cc-4372-a567-0e02b2c3d479
191 1     1 1 611 my $raw = random_bytes(16);
192             # xxxxxxxxxxxx4xxxYxxxxxxxxxxxxxxx
193 1         3 $raw &= pack("H*", "FFFFFFFFFFFF0FFFFFFFFFFFFFFFFFFF");
194 1         2 $raw |= pack("H*", "00000000000040000000000000000000");
195 1         2 $raw &= pack("H*", "FFFFFFFFFFFFFFFF3FFFFFFFFFFFFFFF"); # 0x3 == 0011b
196 1         1 $raw |= pack("H*", "00000000000000008000000000000000"); # 0x8 == 1000b
197 1         3 my $hex = unpack("H*", $raw);
198 1         21 $hex =~ s/^(.{8})(.{4})(.{4})(.{4})(.{12}).*$/$1-$2-$3-$4-$5/;
199 1         3 return $hex;
200             }
201              
202             sub random_v7uuid() {
203             # RFC 9562 §5.7 - Version 7 UUID (time-ordered)
204             # Format: xxxxxxxx-xxxx-7xxx-[89ab]xxx-xxxxxxxxxxxx
205             # Structure: 48-bit ms timestamp | 4-bit ver=7 | 12-bit rand | 2-bit var=10 | 62-bit rand
206 3     3 1 10 my ($sec, $usec) = Time::HiRes::gettimeofday();
207 3         7 my $ms = $sec * 1000 + int($usec / 1000);
208 3         6 my $rand = random_bytes(10);
209 3         23 my $raw = pack("N", int($ms / 65536)) . # bytes 0-3: ms[47:16]
210             pack("n", $ms % 65536) . # bytes 4-5: ms[15:0]
211             pack("n", 0x7000 | (unpack("n", substr($rand, 0, 2)) & 0x0FFF)) . # bytes 6-7: ver=7 + rand_a
212             pack("C", 0x80 | (unpack("C", substr($rand, 2, 1)) & 0x3F)) . # byte 8: var=10 + rand_b
213             substr($rand, 3, 7); # bytes 9-15: rand_b (cont.)
214 3         5 my $hex = unpack("H*", $raw);
215 3         24 $hex =~ s/^(.{8})(.{4})(.{4})(.{4})(.{12})$/$1-$2-$3-$4-$5/;
216 3         10 return $hex;
217             }
218              
219             sub is_v4uuid($) {
220 5     5 1 225 my $uuid = shift;
221 5 50       10 return 0 if !$uuid;
222 5 100       27 return 1 if $uuid =~ /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
223 3         8 return 0;
224             }
225              
226             sub is_uuid($) {
227 11     11 1 1304 my $uuid = shift;
228 11 100       22 return 0 if !$uuid;
229 10 100       53 return 1 if $uuid =~ /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
230 4         11 return 0;
231             }
232              
233             ### private functions
234              
235             sub _name2mode {
236 20     20   507 my $cipher_name = uc(shift);
237 20         43 my %trans = ( 'DES-EDE3' => 'DES_EDE' );
238              
239 20         115 my ($cipher, undef, $klen, $mode) = $cipher_name =~ /^(AES|CAMELLIA|DES|DES-EDE3|SEED)(-(\d+))?-(CBC|CFB|ECB|OFB)$/i;
240 20 100 66     147 croak "FATAL: unsupported cipher '$cipher_name'" unless $cipher && $mode;
241 19   66     41 $cipher = $trans{$cipher} || $cipher;
242 19 100       28 $klen = 192 if $cipher eq 'DES_EDE';
243 19 100       26 $klen = 64 if $cipher eq 'DES';
244 19 100       24 $klen = 128 if $cipher eq 'SEED';
245 19 50       47 $klen = $klen ? int($klen/8) : Crypt::Cipher::min_keysize($cipher);
246 19         71 my $ilen = Crypt::Cipher::blocksize($cipher);
247 19 50 33     57 croak "FATAL: unsupported cipher '$cipher_name'" unless $klen && $ilen;
248              
249 19 100       216 return (Crypt::Mode::CBC->new($cipher), $klen, $ilen) if $mode eq 'CBC';
250 4 100       23 return (Crypt::Mode::CFB->new($cipher), $klen, $ilen) if $mode eq 'CFB';
251 2 50       19 return (Crypt::Mode::ECB->new($cipher), $klen, $ilen) if $mode eq 'ECB';
252 2 50       43 return (Crypt::Mode::OFB->new($cipher), $klen, $ilen) if $mode eq 'OFB';
253             }
254              
255             sub _password2key {
256 19     19   37 my ($password, $klen, $iv, $hash) = @_;
257 19         22 my $salt = substr($iv, 0, 8);
258 19         21 my $key = '';
259 19         34 while (length($key) < $klen) {
260 32         162 $key .= digest_data($hash, $key . $password . $salt);
261             }
262 19         33 return substr($key, 0, $klen);
263             }
264              
265             1;
266              
267             =pod
268              
269             =head1 NAME
270              
271             Crypt::Misc - miscellaneous functions related to (or used by) CryptX
272              
273             =head1 SYNOPSIS
274              
275             use Crypt::Misc ':all';
276              
277             my $rawbytes = 'hello world';
278             my $filename = 'sample.bin';
279             my $pem_data = "-----BEGIN PUBLIC KEY-----\n...\n-----END PUBLIC KEY-----\n";
280             my $str1 = 'same';
281             my $str2 = 'same';
282              
283             # Base64 and Base64/URL-safe functions
284             my $base64 = encode_b64($rawbytes);
285             my $rawbytes2 = decode_b64($base64);
286             my $base64url = encode_b64u($rawbytes);
287             my $rawbytes3 = decode_b64u($base64url);
288              
289             # read/write file
290             my $rawdata = read_rawfile($filename);
291             write_rawfile($filename, $rawdata);
292              
293             # convert PEM/DER
294             my $der_data = pem_to_der($pem_data);
295             my $pem_data2 = der_to_pem($der_data, "PUBLIC KEY");
296              
297             # others
298             die "mismatch" unless slow_eq($str1, $str2);
299              
300             =head1 DESCRIPTION
301              
302             This module contains a collection of mostly unsorted functions loosely-related to CryptX distribution but not implementing cryptography.
303              
304             Most of them are also available in other perl modules but once you utilize CryptX you might avoid dependencies on other modules by using
305             functions from Crypt::Misc.
306              
307             By default, Crypt::Misc doesn't import any function. You can import individual functions
308             or use the C<:all> tag.
309              
310             =head1 FUNCTIONS
311              
312             By default, Crypt::Misc doesn't import any function. You can import individual functions like this:
313              
314             use Crypt::Misc qw(read_rawfile);
315              
316             Or import all available functions:
317              
318             use Crypt::Misc ':all';
319              
320             All encoding functions (C, C, etc.) accept a binary
321             string and return an ASCII string. All decoding functions (C,
322             C, etc.) accept an ASCII string and return a binary string, or
323             C if the input is malformed.
324              
325             An empty string is considered valid input and decodes to an empty string.
326             C is considered invalid input and results in C. Non-empty input
327             with no actual payload, such as whitespace-only or padding-only input, is also
328             considered malformed and results in C.
329              
330             The Base64 decoders C and C also accept otherwise
331             valid payload with embedded whitespace. The other decoder families in this
332             module do not; for them, embedded whitespace is treated as malformed input.
333              
334             =head2 read_rawfile
335              
336             I
337              
338             $rawdata = read_rawfile($filename);
339              
340             Read file C<$filename> into a scalar as a binary data (without decoding/transformation).
341              
342             =head2 write_rawfile
343              
344             I
345              
346             write_rawfile($filename, $rawdata);
347              
348             Write C<$rawdata> to file C<$filename> as binary data.
349              
350             =head2 slow_eq
351              
352             I
353              
354             if (slow_eq($data1, $data2)) { ... }
355              
356             Constant time compare (to avoid timing side-channel). Returns C<1> if the
357             strings are equal, C<0> if they differ, or C if either argument is
358             C.
359              
360             =head2 pem_to_der
361              
362             I
363              
364             $der_data = pem_to_der($pem_data);
365             #or
366             $der_data = pem_to_der($pem_data, $password);
367              
368             Convert PEM to DER representation. Supports also password protected PEM data.
369             Returns C if C<$pem_data> cannot be parsed (no valid PEM block found)
370             or if the C / C labels do not match. Croaks if the PEM is
371             encrypted but no C<$password> is provided. If an encrypted PEM is supplied
372             with the wrong password, decryption is expected to croak from the underlying
373             cipher/padding layer.
374              
375             =head2 der_to_pem
376              
377             I
378              
379             $pem_data = der_to_pem($der_data, $header_name);
380             #or
381             $pem_data = der_to_pem($der_data, $header_name, $password);
382             #or
383             $pem_data = der_to_pem($der_data, $header_name, $password, $cipher_name);
384              
385             # $header_name e.g. "PUBLIC KEY", "RSA PRIVATE KEY" ...
386             # $cipher_name e.g. "DES-EDE3-CBC", "AES-256-CBC" (DEFAULT) ...
387              
388             Convert DER to PEM representation. Returns a PEM string (ASCII).
389             Supports also password protected PEM data. Any defined C<$password>, including
390             false-like values like C<''> or C<'0'>, enables PEM encryption.
391              
392             B: do not use ECB-based ciphers (e.g. C) for PEM
393             encryption - ECB encrypts each block independently, leaking plaintext structure.
394             Use the default C or another chaining mode (CBC, CFB, OFB).
395              
396             B: the traditional PEM encryption format uses a single-iteration
397             MD5-based key derivation which is weak against brute-force. For new applications,
398             prefer PKCS#8 encrypted keys (e.g. via L) or
399             an independent encryption layer.
400              
401             =head2 random_v4uuid
402              
403             I
404              
405             my $uuid = random_v4uuid();
406              
407             Returns cryptographically strong Version 4 random UUID: C
408             where C is any hexadecimal digit and C is one of 8, 9, A, B (1000, 1001, 1010, 1011)
409             e.g. C.
410              
411             =head2 is_v4uuid
412              
413             I
414              
415             if (is_v4uuid($uuid)) {
416             ...
417             }
418              
419             Checks the given C<$uuid> string whether it matches Version 4 UUID format with
420             a relaxed variant policy. The variant nibble may be one of C<0>, C<8>, C<9>,
421             C, or C. Returns C<0> (mismatch) or C<1> (match).
422              
423             =head2 random_v7uuid
424              
425             I
426              
427             my $uuid = random_v7uuid();
428              
429             Returns a cryptographically strong Version 7 time-ordered UUID: C
430             where the first 48 bits encode the current Unix time in milliseconds (making UUIDs sortable by
431             generation time), followed by random bits. Ordering is therefore coarse at
432             millisecond granularity only; UUIDs generated within the same millisecond are
433             not guaranteed to be lexicographically monotonic. C is one of 8, 9, A, B
434             (RFC 9562 variant).
435              
436             =head2 is_uuid
437              
438             I
439              
440             if (is_uuid($uuid)) {
441             ...
442             }
443              
444             Checks whether C<$uuid> is a validly formatted UUID (any version) in the standard
445             C form with a relaxed variant policy.
446             The variant nibble may be one of C<0>, C<8>, C<9>, C, or C. Returns
447             C<1> (match) or C<0> (mismatch).
448             For a version-specific check see L.
449              
450             =head2 increment_octets_le
451              
452             I
453              
454             $octets = increment_octets_le($octets);
455              
456             Treat input C<$octets> as a little-endian big number and return the incremented value.
457              
458             =head2 increment_octets_be
459              
460             I
461              
462             $octets = increment_octets_be($octets);
463              
464             Treat input C<$octets> as a big-endian big number and return the incremented value.
465              
466             =head2 encode_b64
467              
468             I
469              
470             $base64string = encode_b64($rawdata);
471              
472             Encode $rawbytes into Base64 string, no line-endings in the output string.
473              
474             =head2 decode_b64
475              
476             I
477              
478             $rawdata = decode_b64($base64string);
479              
480             Decode a Base64 string.
481              
482             =head2 encode_b64u
483              
484             I
485              
486             $base64url_string = encode_b64u($rawdata);
487              
488             Encode $rawbytes into Base64/URL-Safe string, no line-endings in the output string.
489              
490             =head2 decode_b64u
491              
492             I
493              
494             $rawdata = decode_b64u($base64url_string);
495              
496             Decode a Base64/URL-Safe string.
497              
498             =head2 encode_b32r
499              
500             I
501              
502             $string = encode_b32r($rawdata);
503              
504             Encode bytes into Base32 (rfc4648 alphabet) string, without "=" padding.
505              
506             =head2 decode_b32r
507              
508             I
509              
510             $rawdata = decode_b32r($string);
511              
512             Decode a Base32 (rfc4648 alphabet) string into bytes.
513              
514             =head2 encode_b32b
515              
516             I
517              
518             $string = encode_b32b($rawdata);
519              
520             Encode bytes into Base32 (base32hex alphabet) string, without "=" padding.
521              
522             =head2 decode_b32b
523              
524             I
525              
526             $rawdata = decode_b32b($string);
527              
528             Decode a Base32 (base32hex alphabet) string into bytes.
529              
530             =head2 encode_b32z
531              
532             I
533              
534             $string = encode_b32z($rawdata);
535              
536             Encode bytes into Base32 (zbase32 alphabet) string.
537              
538             =head2 decode_b32z
539              
540             I
541              
542             $rawdata = decode_b32z($string);
543              
544             Decode a Base32 (zbase32 alphabet) string into bytes.
545              
546             =head2 encode_b32c
547              
548             I
549              
550             $string = encode_b32c($rawdata);
551              
552             Encode bytes into Base32 (crockford alphabet) string.
553              
554             =head2 decode_b32c
555              
556             I
557              
558             $rawdata = decode_b32c($string);
559              
560             Decode a Base32 (crockford alphabet) string into bytes.
561              
562             =head2 encode_b58b
563              
564             I
565              
566             $string = encode_b58b($rawdata);
567              
568             Encode bytes into Base58 (Bitcoin alphabet) string.
569              
570             =head2 decode_b58b
571              
572             I
573              
574             $rawdata = decode_b58b($string);
575              
576             Decode a Base58 (Bitcoin alphabet) string into bytes.
577              
578             =head2 encode_b58f
579              
580             I
581              
582             $string = encode_b58f($rawdata);
583              
584             Encode bytes into Base58 (Flickr alphabet) string.
585              
586             =head2 decode_b58f
587              
588             I
589              
590             $rawdata = decode_b58f($string);
591              
592             Decode a Base58 (Flickr alphabet) string into bytes.
593              
594             =head2 encode_b58r
595              
596             I
597              
598             $string = encode_b58r($rawdata);
599              
600             Encode bytes into Base58 (Ripple alphabet) string.
601              
602             =head2 decode_b58r
603              
604             I
605              
606             $rawdata = decode_b58r($string);
607              
608             Decode a Base58 (Ripple alphabet) string into bytes.
609              
610             =head2 encode_b58t
611              
612             I
613              
614             $string = encode_b58t($rawdata);
615              
616             Encode bytes into Base58 (Tipple alphabet) string.
617              
618             =head2 decode_b58t
619              
620             I
621              
622             $rawdata = decode_b58t($string);
623              
624             Decode a Base58 (Tipple alphabet) string into bytes.
625              
626             =head2 encode_b58s
627              
628             I
629              
630             $string = encode_b58s($rawdata);
631              
632             Encode bytes into Base58 (Stellar alphabet) string.
633              
634             =head2 decode_b58s
635              
636             I
637              
638             $rawdata = decode_b58s($string);
639              
640             Decode a Base58 (Stellar alphabet) string into bytes.
641              
642             =head1 SEE ALSO
643              
644             =over
645              
646             =item * L
647              
648             =back
649              
650             =cut