summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarel Miko <miko@dcit.cz>2013-09-11 10:57:17 +0200
committerKarel Miko <miko@dcit.cz>2013-09-11 10:57:17 +0200
commit808344dc8385127fb4e6c696936e737ad766cd7c (patch)
tree4877c6a628c83b45b7ee5d6b3eb7fb969abb625a
parent5784586cfa5c2eefdc57ea4d4fdf49a848387015 (diff)
digest/mac base64url support
-rwxr-xr-xChanges3
-rwxr-xr-x_generators/Digest.pm.tt58
-rwxr-xr-x_generators/Digest.t.tt8
-rwxr-xr-x_generators/Mac.pm.tt71
-rwxr-xr-x_generators/Mac.t.tt3
-rwxr-xr-x_generators/Mac.xs.inc.tt27
-rwxr-xr-x_generators/tt_digest.pl12
-rwxr-xr-x_generators/tt_mac.pl3
-rw-r--r--lib/Crypt/Digest.pm8
-rw-r--r--lib/Crypt/Digest/CHAES.pm58
-rw-r--r--lib/Crypt/Digest/MD2.pm58
-rw-r--r--lib/Crypt/Digest/MD4.pm58
-rw-r--r--lib/Crypt/Digest/MD5.pm58
-rw-r--r--lib/Crypt/Digest/RIPEMD128.pm58
-rw-r--r--lib/Crypt/Digest/RIPEMD160.pm58
-rw-r--r--lib/Crypt/Digest/RIPEMD256.pm58
-rw-r--r--lib/Crypt/Digest/RIPEMD320.pm58
-rw-r--r--lib/Crypt/Digest/SHA1.pm58
-rw-r--r--lib/Crypt/Digest/SHA224.pm58
-rw-r--r--lib/Crypt/Digest/SHA256.pm58
-rw-r--r--lib/Crypt/Digest/SHA384.pm58
-rw-r--r--lib/Crypt/Digest/SHA512.pm58
-rw-r--r--lib/Crypt/Digest/Tiger192.pm58
-rw-r--r--lib/Crypt/Digest/Whirlpool.pm58
-rw-r--r--lib/Crypt/Mac/F9.pm37
-rw-r--r--lib/Crypt/Mac/HMAC.pm37
-rw-r--r--lib/Crypt/Mac/OMAC.pm37
-rw-r--r--lib/Crypt/Mac/PMAC.pm37
-rw-r--r--lib/Crypt/Mac/Pelican.pm37
-rw-r--r--lib/Crypt/Mac/XCBC.pm37
-rw-r--r--lib/CryptX.pm2
-rw-r--r--t/digest_chaes.t27
-rw-r--r--t/digest_md2.t27
-rw-r--r--t/digest_md4.t27
-rw-r--r--t/digest_md5.t27
-rw-r--r--t/digest_ripemd128.t27
-rw-r--r--t/digest_ripemd160.t27
-rw-r--r--t/digest_ripemd256.t27
-rw-r--r--t/digest_ripemd320.t27
-rw-r--r--t/digest_sha1.t27
-rw-r--r--t/digest_sha224.t27
-rw-r--r--t/digest_sha256.t27
-rw-r--r--t/digest_sha384.t27
-rw-r--r--t/digest_sha512.t27
-rw-r--r--t/digest_tiger192.t27
-rw-r--r--t/digest_whirlpool.t27
-rw-r--r--t/mac_f9.t54
-rw-r--r--t/mac_hmac.t54
-rw-r--r--t/mac_omac.t54
-rw-r--r--t/mac_pelican.t54
-rw-r--r--t/mac_pmac.t54
-rw-r--r--t/mac_xcbc.t54
52 files changed, 1394 insertions, 622 deletions
diff --git a/Changes b/Changes
index bb66bada..0de13454 100755
--- a/Changes
+++ b/Changes
@@ -13,6 +13,9 @@ TODO:
DSA: my $sig = $pr1->sign("message");
RSA: my $k = Crypt::PK::RSA->new; $k->generate_key(256, 65537);
+0.014 2013/09/XXX
+ - Crypt::Digest::NNN and Crypt::Mac::NNN now can produce Base64-URL-Safe encoded digest/mac
+
0.013 2013/08/28
- DSA/RSA/ECC/DH - importing keys from string changed - now: $pk->import_key(\$buffer_with_key)
- DSA/RSA/ECC/DH - size() and is_private() now return undef if no key loaded
diff --git a/_generators/Digest.pm.tt b/_generators/Digest.pm.tt
index 99269635..b4045ca0 100755
--- a/_generators/Digest.pm.tt
+++ b/_generators/Digest.pm.tt
@@ -6,7 +6,7 @@ use strict;
use warnings;
use Exporter 'import';
-our %EXPORT_TAGS = ( all => [qw( [%lc_name%] [%lc_name%]_hex [%lc_name%]_b64 [%lc_name%]_file [%lc_name%]_file_hex [%lc_name%]_file_b64 )] );
+our %EXPORT_TAGS = ( all => [qw( [%lc_name%] [%lc_name%]_hex [%lc_name%]_b64 [%lc_name%]_b64u [%lc_name%]_file [%lc_name%]_file_hex [%lc_name%]_file_b64 [%lc_name%]_file_b64u )] );
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
our @EXPORT = qw();
@@ -20,10 +20,12 @@ sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) }
sub [%lc_name%] { Crypt::Digest::digest_data(__PACKAGE__, @_) }
sub [%lc_name%]_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) }
sub [%lc_name%]_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) }
+sub [%lc_name%]_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) }
sub [%lc_name%]_file { Crypt::Digest::digest_file(__PACKAGE__, @_) }
sub [%lc_name%]_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) }
sub [%lc_name%]_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) }
+sub [%lc_name%]_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) }
1;
@@ -36,20 +38,24 @@ Crypt::Digest::[%orig_name%] - [%info%]
=head1 SYNOPSIS
### Functional interface:
- use Crypt::Digest::[%orig_name%] qw( [%lc_name%] [%lc_name%]_hex [%lc_name%]_b64 [%lc_name%]_file [%lc_name%]_file_hex [%lc_name%]_file_b64 );
+ use Crypt::Digest::[%orig_name%] qw( [%lc_name%] [%lc_name%]_hex [%lc_name%]_b64 [%lc_name%]_b64u
+ [%lc_name%]_file [%lc_name%]_file_hex [%lc_name%]_file_b64 [%lc_name%]_file_b64u );
# calculate digest from string/buffer
- $[%lc_name%]_raw = [%lc_name%]('data string');
- $[%lc_name%]_hex = [%lc_name%]_hex('data string');
- $[%lc_name%]_b64 = [%lc_name%]_b64('data string');
+ $[%lc_name%]_raw = [%lc_name%]('data string');
+ $[%lc_name%]_hex = [%lc_name%]_hex('data string');
+ $[%lc_name%]_b64 = [%lc_name%]_b64('data string');
+ $[%lc_name%]_b64u = [%lc_name%]_b64u('data string');
# calculate digest from file
- $[%lc_name%]_raw = [%lc_name%]_file('filename.dat');
- $[%lc_name%]_hex = [%lc_name%]_file_hex('filename.dat');
- $[%lc_name%]_b64 = [%lc_name%]_file_b64('filename.dat');
+ $[%lc_name%]_raw = [%lc_name%]_file('filename.dat');
+ $[%lc_name%]_hex = [%lc_name%]_file_hex('filename.dat');
+ $[%lc_name%]_b64 = [%lc_name%]_file_b64('filename.dat');
+ $[%lc_name%]_b64u = [%lc_name%]_file_b64u('filename.dat');
# calculate digest from filehandle
- $[%lc_name%]_raw = [%lc_name%]_file(*FILEHANDLE);
- $[%lc_name%]_hex = [%lc_name%]_file_hex(*FILEHANDLE);
- $[%lc_name%]_b64 = [%lc_name%]_file_b64(*FILEHANDLE);
+ $[%lc_name%]_raw = [%lc_name%]_file(*FILEHANDLE);
+ $[%lc_name%]_hex = [%lc_name%]_file_hex(*FILEHANDLE);
+ $[%lc_name%]_b64 = [%lc_name%]_file_b64(*FILEHANDLE);
+ $[%lc_name%]_b64u = [%lc_name%]_file_b64u(*FILEHANDLE);
### OO interface:
use Crypt::Digest::[%orig_name%];
@@ -58,9 +64,10 @@ Crypt::Digest::[%orig_name%] - [%info%]
$d->add('any data');
$d->addfile('filename.dat');
$d->addfile(*FILEHANDLE);
- $result_raw = $d->digest; # raw bytes
- $result_hex = $d->hexdigest; # hexadecimal form
- $result_b64 = $d->b64digest; # Base64 form
+ $result_raw = $d->digest; # raw bytes
+ $result_hex = $d->hexdigest; # hexadecimal form
+ $result_b64 = $d->b64digest; # Base64 form
+ $result_b64u = $d->b64udigest; # Base64 URL Safe form
=head1 DESCRIPTION
@@ -72,7 +79,8 @@ Nothing is exported by default.
You can export selected functions:
- use Crypt::Digest::[%orig_name%] qw([%lc_name%] [%lc_name%]_hex [%lc_name%]_b64 [%lc_name%]_file [%lc_name%]_file_hex [%lc_name%]_file_b64);
+ use Crypt::Digest::[%orig_name%] qw([%lc_name%] [%lc_name%]_hex [%lc_name%]_b64 [%lc_name%]_b64u
+ [%lc_name%]_file [%lc_name%]_file_hex [%lc_name%]_file_b64 [%lc_name%]_file_b64u);
Or all of them at once:
@@ -104,6 +112,14 @@ Logically joins all arguments into a single string, and returns its [%orig_name%
#or
$[%lc_name%]_b64 = [%lc_name%]_b64('any data', 'more data', 'even more data');
+=head2 [%lc_name%]_b64u
+
+Logically joins all arguments into a single string, and returns its [%orig_name%] digest encoded as a Base64 URL Safe string (see RFC 4648 section 5).
+
+ $[%lc_name%]_b64url = [%lc_name%]_b64u('data string');
+ #or
+ $[%lc_name%]_b64url = [%lc_name%]_b64u('any data', 'more data', 'even more data');
+
=head2 [%lc_name%]_file
Reads file (defined by filename or filehandle) content, and returns its [%orig_name%] digest encoded as a binary string.
@@ -130,6 +146,14 @@ Reads file (defined by filename or filehandle) content, and returns its [%orig_n
#or
$[%lc_name%]_b64 = [%lc_name%]_file_b64(*FILEHANDLE);
+=head2 [%lc_name%]_file_b64u
+
+Reads file (defined by filename or filehandle) content, and returns its [%orig_name%] digest encoded as a Base64 URL Safe string (see RFC 4648 section 5).
+
+ $[%lc_name%]_b64url = [%lc_name%]_file_b64u('filename.dat');
+ #or
+ $[%lc_name%]_b64url = [%lc_name%]_file_b64u(*FILEHANDLE);
+
=head1 METHODS
The OO interface provides the same set of functions as L<Crypt::Digest>.
@@ -184,6 +208,10 @@ The OO interface provides the same set of functions as L<Crypt::Digest>.
$result_b64 = $d->b64digest();
+=head2 b64udigest
+
+ $result_b64url = $d->b64udigest();
+
=head1 SEE ALSO
=over 4
diff --git a/_generators/Digest.t.tt b/_generators/Digest.t.tt
index 30a31d45..95eaf40d 100755
--- a/_generators/Digest.t.tt
+++ b/_generators/Digest.t.tt
@@ -3,10 +3,10 @@
use strict;
use warnings;
-use Test::More tests => 7*[%t_strings_count%] + 8*[%t_files_count%] + 6;
+use Test::More tests => 8*[%t_strings_count%] + 9*[%t_files_count%] + 6;
-use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_file digest_file_hex digest_file_b64 );
-use Crypt::Digest::[%orig_name%] qw( [%lc_name%] [%lc_name%]_hex [%lc_name%]_b64 [%lc_name%]_file [%lc_name%]_file_hex [%lc_name%]_file_b64 );
+use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u );
+use Crypt::Digest::[%orig_name%] qw( [%lc_name%] [%lc_name%]_hex [%lc_name%]_b64 [%lc_name%]_b64u [%lc_name%]_file [%lc_name%]_file_hex [%lc_name%]_file_b64 [%lc_name%]_file_b64u );
is( Crypt::Digest::hashsize('[%orig_name%]'), [%hashsize%], 'hashsize/1');
is( Crypt::Digest->hashsize('[%orig_name%]'), [%hashsize%], 'hashsize/2');
@@ -22,6 +22,7 @@ is( [%lc_name%]_b64([%v.data%]), "[%v.base64%]", '[%lc_name%] (base64/[%loop.cou
is( digest_data('[%orig_name%]', [%v.data%]), pack("H*","[%v.hex%]"), '[%lc_name%] (digest_data_raw/[%loop.count%])');
is( digest_data_hex('[%orig_name%]', [%v.data%]), "[%v.hex%]", '[%lc_name%] (digest_data_hex/[%loop.count%])');
is( digest_data_b64('[%orig_name%]', [%v.data%]), "[%v.base64%]", '[%lc_name%] (digest_data_b64/[%loop.count%])');
+is( digest_data_b64u('[%orig_name%]', [%v.data%]), "[%v.base64url%]", '[%lc_name%] (digest_data_b64u/[%loop.count%])');
is( Crypt::Digest::[%orig_name%]->new->add([%v.data%])->hexdigest, "[%v.hex%]", '[%lc_name%] (OO/[%loop.count%])');
[% END %]
[% FOREACH v IN t_files %]
@@ -31,6 +32,7 @@ is( [%lc_name%]_file_b64('[%v.file%]'), "[%v.base64%]", '[%lc_name%] (base64/fil
is( digest_file('[%orig_name%]', '[%v.file%]'), pack("H*","[%v.hex%]"), '[%lc_name%] (digest_file_raw/file/[%loop.count%])');
is( digest_file_hex('[%orig_name%]', '[%v.file%]'), "[%v.hex%]", '[%lc_name%] (digest_file_hex/file/[%loop.count%])');
is( digest_file_b64('[%orig_name%]', '[%v.file%]'), "[%v.base64%]", '[%lc_name%] (digest_file_b64/file/[%loop.count%])');
+is( digest_file_b64u('[%orig_name%]', '[%v.file%]'), "[%v.base64url%]", '[%lc_name%] (digest_file_b64u/file/[%loop.count%])');
is( Crypt::Digest::[%orig_name%]->new->addfile('[%v.file%]')->hexdigest, "[%v.hex%]", '[%lc_name%] (OO/file/[%loop.count%])');
{
open(my $fh, '<', '[%v.file%]');
diff --git a/_generators/Mac.pm.tt b/_generators/Mac.pm.tt
index a8d838ee..bf2f85ff 100755
--- a/_generators/Mac.pm.tt
+++ b/_generators/Mac.pm.tt
@@ -6,7 +6,7 @@ use strict;
use warnings;
use Exporter 'import';
-our %EXPORT_TAGS = ( all => [qw( [%lc_name%] [%lc_name%]_hex [%lc_name%]_b64 )] );
+our %EXPORT_TAGS = ( all => [qw( [%lc_name%] [%lc_name%]_hex [%lc_name%]_b64 [%lc_name%]_b64u )] );
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
our @EXPORT = qw();
@@ -18,20 +18,23 @@ use Crypt::Digest;
sub new { my $class = shift; _new(Crypt::Digest::_trans_digest_name(shift), @_) }
sub [%lc_name%] { Crypt::Mac::[%orig_name%]->new(shift, shift)->add(@_)->mac }
-sub [%lc_name%]_hex { Crypt::Mac::[%orig_name%]->new(shift, shift)->add(@_)->hexmac }
-sub [%lc_name%]_b64 { Crypt::Mac::[%orig_name%]->new(shift, shift)->add(@_)->b64mac }
+sub [%lc_name%]_hex { Crypt::Mac::[%orig_name%]->new(shift, shift)->add(@_)->hexmac }
+sub [%lc_name%]_b64 { Crypt::Mac::[%orig_name%]->new(shift, shift)->add(@_)->b64mac }
+sub [%lc_name%]_b64u { Crypt::Mac::[%orig_name%]->new(shift, shift)->add(@_)->b64umac }
[%-ELSIF lc_name == 'pelican' %]
sub new { my $class = shift; _new(@_) }
sub [%lc_name%] { Crypt::Mac::[%orig_name%]->new(shift)->add(@_)->mac }
-sub [%lc_name%]_hex { Crypt::Mac::[%orig_name%]->new(shift)->add(@_)->hexmac }
-sub [%lc_name%]_b64 { Crypt::Mac::[%orig_name%]->new(shift)->add(@_)->b64mac }
+sub [%lc_name%]_hex { Crypt::Mac::[%orig_name%]->new(shift)->add(@_)->hexmac }
+sub [%lc_name%]_b64 { Crypt::Mac::[%orig_name%]->new(shift)->add(@_)->b64mac }
+sub [%lc_name%]_b64u { Crypt::Mac::[%orig_name%]->new(shift)->add(@_)->b64umac }
[%-ELSE%]
use Crypt::Cipher;
sub new { my $class = shift; _new(Crypt::Cipher::_trans_cipher_name(shift), @_) }
sub [%lc_name%] { Crypt::Mac::[%orig_name%]->new(shift, shift)->add(@_)->mac }
-sub [%lc_name%]_hex { Crypt::Mac::[%orig_name%]->new(shift, shift)->add(@_)->hexmac }
-sub [%lc_name%]_b64 { Crypt::Mac::[%orig_name%]->new(shift, shift)->add(@_)->b64mac }
+sub [%lc_name%]_hex { Crypt::Mac::[%orig_name%]->new(shift, shift)->add(@_)->hexmac }
+sub [%lc_name%]_b64 { Crypt::Mac::[%orig_name%]->new(shift, shift)->add(@_)->b64mac }
+sub [%lc_name%]_b64u { Crypt::Mac::[%orig_name%]->new(shift, shift)->add(@_)->b64umac }
[%-END%]
1;
@@ -49,17 +52,20 @@ Crypt::Mac::[%orig_name%] - [%info%]
# calculate MAC from string/buffer
[%-IF lc_name == 'hmac' %]
- $[%lc_name%]_raw = [%lc_name%]('SHA256', $key, 'data buffer');
- $[%lc_name%]_hex = [%lc_name%]_hex('SHA256', $key, 'data buffer');
- $[%lc_name%]_b64 = [%lc_name%]_b64('SHA256', $key, 'data buffer');
+ $[%lc_name%]_raw = [%lc_name%]('SHA256', $key, 'data buffer');
+ $[%lc_name%]_hex = [%lc_name%]_hex('SHA256', $key, 'data buffer');
+ $[%lc_name%]_b64 = [%lc_name%]_b64('SHA256', $key, 'data buffer');
+ $[%lc_name%]_b64u = [%lc_name%]_b64u('SHA256', $key, 'data buffer');
[%-ELSIF lc_name == 'pelican' %]
- $[%lc_name%]_raw = [%lc_name%]($key, 'data buffer');
- $[%lc_name%]_hex = [%lc_name%]_hex($key, 'data buffer');
- $[%lc_name%]_b64 = [%lc_name%]_b64($key, 'data buffer');
+ $[%lc_name%]_raw = [%lc_name%]($key, 'data buffer');
+ $[%lc_name%]_hex = [%lc_name%]_hex($key, 'data buffer');
+ $[%lc_name%]_b64 = [%lc_name%]_b64($key, 'data buffer');
+ $[%lc_name%]_b64u = [%lc_name%]_b64u($key, 'data buffer');
[%-ELSE%]
- $[%lc_name%]_raw = [%lc_name%]($cipher_name, $key, 'data buffer');
- $[%lc_name%]_hex = [%lc_name%]_hex($cipher_name, $key, 'data buffer');
- $[%lc_name%]_b64 = [%lc_name%]_b64($cipher_name, $key, 'data buffer');
+ $[%lc_name%]_raw = [%lc_name%]($cipher_name, $key, 'data buffer');
+ $[%lc_name%]_hex = [%lc_name%]_hex($cipher_name, $key, 'data buffer');
+ $[%lc_name%]_b64 = [%lc_name%]_b64($cipher_name, $key, 'data buffer');
+ $[%lc_name%]_b64u = [%lc_name%]_b64u($cipher_name, $key, 'data buffer');
[%-END%]
### OO interface:
@@ -75,9 +81,10 @@ Crypt::Mac::[%orig_name%] - [%info%]
$d->add('any data');
$d->addfile('filename.dat');
$d->addfile(*FILEHANDLE);
- $result_raw = $d->mac; # raw bytes
- $result_hex = $d->hexmac; # hexadecimal form
- $result_b64 = $d->b64mac; # Base64 form
+ $result_raw = $d->mac; # raw bytes
+ $result_hex = $d->hexmac; # hexadecimal form
+ $result_b64 = $d->b64mac; # Base64 form
+ $result_b64u = $d->b64umac; # Base64 URL Safe form
=head1 DESCRIPTION
@@ -135,7 +142,7 @@ Logically joins all arguments into a single string, and returns its [%orig_name%
=head2 [%lc_name%]_b64
-Logically joins all arguments into a single string, and returns its [%orig_name%] message authentication code encoded as a BASE64 string.
+Logically joins all arguments into a single string, and returns its [%orig_name%] message authentication code encoded as a Base64 string.
[%-IF lc_name == 'hmac' %]
$[%lc_name%]_b64 = [%lc_name%]_b64($hash_name, $key, 'data buffer');
@@ -151,9 +158,25 @@ Logically joins all arguments into a single string, and returns its [%orig_name%
$[%lc_name%]_b64 = [%lc_name%]_b64($cipher_name, $key, 'any data', 'more data', 'even more data');
[%-END%]
-=head1 METHODS
+=head2 [%lc_name%]_b64u
-The OO interface provides the same set of functions as L<Crypt::Mac>.
+Logically joins all arguments into a single string, and returns its [%orig_name%] message authentication code encoded as a Base64 URL Safe string (see RFC 4648 section 5).
+
+[%-IF lc_name == 'hmac' %]
+ $[%lc_name%]_b64url = [%lc_name%]_b64u($hash_name, $key, 'data buffer');
+ #or
+ $[%lc_name%]_b64url = [%lc_name%]_b64u($hash_name, $key, 'any data', 'more data', 'even more data');
+[%-ELSIF lc_name == 'pelican' %]
+ $[%lc_name%]_b64url = [%lc_name%]_b64u($key, 'data buffer');
+ #or
+ $[%lc_name%]_b64url = [%lc_name%]_b64u($key, 'any data', 'more data', 'even more data');
+[%-ELSE%]
+ $[%lc_name%]_b64url = [%lc_name%]_b64u($cipher_name, $key, 'data buffer');
+ #or
+ $[%lc_name%]_b64url = [%lc_name%]_b64u($cipher_name, $key, 'any data', 'more data', 'even more data');
+[%-END%]
+
+=head1 METHODS
=head2 new
@@ -197,6 +220,10 @@ The OO interface provides the same set of functions as L<Crypt::Mac>.
$result_b64 = $d->b64mac();
+=head2 b64umac
+
+ $result_b64url = $d->b64umac();
+
=head1 SEE ALSO
=over 4
diff --git a/_generators/Mac.t.tt b/_generators/Mac.t.tt
index 24183968..ec99c598 100755
--- a/_generators/Mac.t.tt
+++ b/_generators/Mac.t.tt
@@ -9,7 +9,7 @@ use Test::More;
use Test::More tests => 0;
[%- END %]
-use Crypt::Mac::[%orig_name%] qw( [%lc_name%] [%lc_name%]_hex [%lc_name%]_b64 );
+use Crypt::Mac::[%orig_name%] qw( [%lc_name%] [%lc_name%]_hex [%lc_name%]_b64 [%lc_name%]_b64u );
[%- FOREACH v IN t_strings %]
is( unpack('H*', Crypt::Mac::[%orig_name%]->new([%v.args%])->add([%v.data%])->mac), '[%v.mac%]', '[%orig_name%]/oo+raw/[%loop.count%]');
@@ -17,6 +17,7 @@ is( Crypt::Mac::[%orig_name%]->new([%v.args%])->add([%v.data%])->hexmac, '[%v.ma
is( unpack('H*', [%lc_name%]([%v.args%],[%v.data%])), '[%v.mac%]', '[%orig_name%]/func+raw/[%loop.count%]');
is( [%lc_name%]_hex([%v.args%],[%v.data%]), '[%v.mac%]', '[%orig_name%]/func+hex/[%loop.count%]');
is( [%lc_name%]_b64([%v.args%],[%v.data%]), '[%v.b64mac%]', '[%orig_name%]/func+b64/[%loop.count%]');
+is( [%lc_name%]_b64u([%v.args%],[%v.data%]), '[%v.b64umac%]', '[%orig_name%]/func+b64u/[%loop.count%]');
[%- END %]
done_testing();
diff --git a/_generators/Mac.xs.inc.tt b/_generators/Mac.xs.inc.tt
index 82c5131d..b5987e7a 100755
--- a/_generators/Mac.xs.inc.tt
+++ b/_generators/Mac.xs.inc.tt
@@ -123,6 +123,33 @@ b64mac(Crypt::Mac::[%orig_name%] self)
RETVAL
SV *
+b64umac(Crypt::Mac::[%orig_name%] self)
+ CODE:
+ {
+ unsigned char mac[MAXBLOCKSIZE];
+ unsigned long mac_len;
+ int rv;
+ unsigned long outlen;
+ char mac_base64[MAXBLOCKSIZE*2 + 1];
+
+[%-IF lc_name == 'pelican' %]
+ mac_len = 16;
+ rv = [%lc_name%]_done(&self->state, mac);
+ if (rv != CRYPT_OK) croak("FATAL: [%lc_name%]_done failed: %s", error_to_string(rv));
+[%-ELSE%]
+ mac_len = sizeof(mac);
+ rv = [%lc_name%]_done(&self->state, mac, &mac_len);
+ if (rv != CRYPT_OK) croak("FATAL: [%lc_name%]_done failed: %s", error_to_string(rv));
+[%-END%]
+ outlen = sizeof(mac_base64);
+ rv = base64url_encode(mac, mac_len, (unsigned char*)mac_base64, &outlen);
+ if (rv != CRYPT_OK) croak("FATAL: base64url_encode failed: %s", error_to_string(rv));
+ RETVAL = newSVpvn(mac_base64, outlen);
+ }
+ OUTPUT:
+ RETVAL
+
+SV *
hexmac(Crypt::Mac::[%orig_name%] self)
CODE:
{
diff --git a/_generators/tt_digest.pl b/_generators/tt_digest.pl
index cdeecdf8..518f7cf5 100755
--- a/_generators/tt_digest.pl
+++ b/_generators/tt_digest.pl
@@ -61,11 +61,19 @@ for my $n (keys %list) {
require Crypt::Digest;
Crypt::Digest::import(':all');
for (@test_strings) {
- push @{$data->{t_strings}}, { data=>pp($_), hex=>Crypt::Digest::digest_data_hex($n, $_), base64=>Crypt::Digest::digest_data_b64($n, $_) };
+ push @{$data->{t_strings}}, { data=>pp($_),
+ hex=>Crypt::Digest::digest_data_hex($n, $_),
+ base64=>Crypt::Digest::digest_data_b64($n, $_),
+ base64url=>Crypt::Digest::digest_data_b64u($n, $_),
+ };
}
for (@test_files) {
$_ =~ s|\\|/|g;
- push @{$data->{t_files}}, { file=>$_, hex=>Crypt::Digest::digest_file_hex($n, "$FindBin::Bin/../$_"), base64=>Crypt::Digest::digest_file_b64($n, "$FindBin::Bin/../$_") };
+ push @{$data->{t_files}}, { file=>$_,
+ hex=>Crypt::Digest::digest_file_hex($n, "$FindBin::Bin/../$_"),
+ base64=>Crypt::Digest::digest_file_b64($n, "$FindBin::Bin/../$_"),
+ base64url=>Crypt::Digest::digest_file_b64u($n, "$FindBin::Bin/../$_"),
+ };
}
$data->{t_files_count} = scalar(@{$data->{t_files}});
$data->{t_strings_count} = scalar(@{$data->{t_strings}});
diff --git a/_generators/tt_mac.pl b/_generators/tt_mac.pl
index 8229f477..7922fe3b 100755
--- a/_generators/tt_mac.pl
+++ b/_generators/tt_mac.pl
@@ -8,7 +8,7 @@ use File::Slurp;
use File::Copy;
use File::Spec::Functions qw(catfile catdir abs2rel canonpath);
use Data::Dump 'pp';
-use MIME::Base64;
+use MIME::Base64 qw(encode_base64 encode_base64url);
sub equal_files {
my $d1 = sha1_hex(read_file(shift, binmode => ':raw'));
@@ -72,6 +72,7 @@ for my $n (keys %list) {
}
}
$_->{b64mac} = encode_base64(pack("H*", $_->{mac}),'') for (@{$data->{t_strings}});
+ $_->{b64umac} = encode_base64url(pack("H*", $_->{mac}),'') for (@{$data->{t_strings}});
$data->{t_strings_count} = defined $data->{t_strings} ? scalar(@{$data->{t_strings}}) : 0;
my $t_out = catfile($outdir_t, "mac_".lc($n).".t");
diff --git a/lib/Crypt/Digest.pm b/lib/Crypt/Digest.pm
index 12c79aba..c1e9ab12 100644
--- a/lib/Crypt/Digest.pm
+++ b/lib/Crypt/Digest.pm
@@ -144,10 +144,10 @@ Crypt::Digest - Generic interface to hash/digest functions
$d->add('any data');
$d->addfile('filename.dat');
$d->addfile(*FILEHANDLE);
- $result_raw = $d->digest; # raw bytes
- $result_hex = $d->hexdigest; # hexadecimal form
- $result_b64 = $d->b64digest; # Base64 form
- $result_b64u = $d->b64digest; # Base64 URL Safe form
+ $result_raw = $d->digest; # raw bytes
+ $result_hex = $d->hexdigest; # hexadecimal form
+ $result_b64 = $d->b64digest; # Base64 form
+ $result_b64u = $d->b64udigest; # Base64 URL Safe form
=head1 DESCRIPTION
diff --git a/lib/Crypt/Digest/CHAES.pm b/lib/Crypt/Digest/CHAES.pm
index 3b5c3684..d086e173 100644
--- a/lib/Crypt/Digest/CHAES.pm
+++ b/lib/Crypt/Digest/CHAES.pm
@@ -6,7 +6,7 @@ use strict;
use warnings;
use Exporter 'import';
-our %EXPORT_TAGS = ( all => [qw( chaes chaes_hex chaes_b64 chaes_file chaes_file_hex chaes_file_b64 )] );
+our %EXPORT_TAGS = ( all => [qw( chaes chaes_hex chaes_b64 chaes_b64u chaes_file chaes_file_hex chaes_file_b64 chaes_file_b64u )] );
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
our @EXPORT = qw();
@@ -20,10 +20,12 @@ sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) }
sub chaes { Crypt::Digest::digest_data(__PACKAGE__, @_) }
sub chaes_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) }
sub chaes_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) }
+sub chaes_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) }
sub chaes_file { Crypt::Digest::digest_file(__PACKAGE__, @_) }
sub chaes_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) }
sub chaes_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) }
+sub chaes_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) }
1;
@@ -36,20 +38,24 @@ Crypt::Digest::CHAES - Hash function - CipherHash based on AES [size: 128 bits]
=head1 SYNOPSIS
### Functional interface:
- use Crypt::Digest::CHAES qw( chaes chaes_hex chaes_b64 chaes_file chaes_file_hex chaes_file_b64 );
+ use Crypt::Digest::CHAES qw( chaes chaes_hex chaes_b64 chaes_b64u
+ chaes_file chaes_file_hex chaes_file_b64 chaes_file_b64u );
# calculate digest from string/buffer
- $chaes_raw = chaes('data string');
- $chaes_hex = chaes_hex('data string');
- $chaes_b64 = chaes_b64('data string');
+ $chaes_raw = chaes('data string');
+ $chaes_hex = chaes_hex('data string');
+ $chaes_b64 = chaes_b64('data string');
+ $chaes_b64u = chaes_b64u('data string');
# calculate digest from file
- $chaes_raw = chaes_file('filename.dat');
- $chaes_hex = chaes_file_hex('filename.dat');
- $chaes_b64 = chaes_file_b64('filename.dat');
+ $chaes_raw = chaes_file('filename.dat');
+ $chaes_hex = chaes_file_hex('filename.dat');
+ $chaes_b64 = chaes_file_b64('filename.dat');
+ $chaes_b64u = chaes_file_b64u('filename.dat');
# calculate digest from filehandle
- $chaes_raw = chaes_file(*FILEHANDLE);
- $chaes_hex = chaes_file_hex(*FILEHANDLE);
- $chaes_b64 = chaes_file_b64(*FILEHANDLE);
+ $chaes_raw = chaes_file(*FILEHANDLE);
+ $chaes_hex = chaes_file_hex(*FILEHANDLE);
+ $chaes_b64 = chaes_file_b64(*FILEHANDLE);
+ $chaes_b64u = chaes_file_b64u(*FILEHANDLE);
### OO interface:
use Crypt::Digest::CHAES;
@@ -58,9 +64,10 @@ Crypt::Digest::CHAES - Hash function - CipherHash based on AES [size: 128 bits]
$d->add('any data');
$d->addfile('filename.dat');
$d->addfile(*FILEHANDLE);
- $result_raw = $d->digest; # raw bytes
- $result_hex = $d->hexdigest; # hexadecimal form
- $result_b64 = $d->b64digest; # Base64 form
+ $result_raw = $d->digest; # raw bytes
+ $result_hex = $d->hexdigest; # hexadecimal form
+ $result_b64 = $d->b64digest; # Base64 form
+ $result_b64u = $d->b64udigest; # Base64 URL Safe form
=head1 DESCRIPTION
@@ -72,7 +79,8 @@ Nothing is exported by default.
You can export selected functions:
- use Crypt::Digest::CHAES qw(chaes chaes_hex chaes_b64 chaes_file chaes_file_hex chaes_file_b64);
+ use Crypt::Digest::CHAES qw(chaes chaes_hex chaes_b64 chaes_b64u
+ chaes_file chaes_file_hex chaes_file_b64 chaes_file_b64u);
Or all of them at once:
@@ -104,6 +112,14 @@ Logically joins all arguments into a single string, and returns its CHAES digest
#or
$chaes_b64 = chaes_b64('any data', 'more data', 'even more data');
+=head2 chaes_b64u
+
+Logically joins all arguments into a single string, and returns its CHAES digest encoded as a Base64 URL Safe string (see RFC 4648 section 5).
+
+ $chaes_b64url = chaes_b64u('data string');
+ #or
+ $chaes_b64url = chaes_b64u('any data', 'more data', 'even more data');
+
=head2 chaes_file
Reads file (defined by filename or filehandle) content, and returns its CHAES digest encoded as a binary string.
@@ -130,6 +146,14 @@ Reads file (defined by filename or filehandle) content, and returns its CHAES di
#or
$chaes_b64 = chaes_file_b64(*FILEHANDLE);
+=head2 chaes_file_b64u
+
+Reads file (defined by filename or filehandle) content, and returns its CHAES digest encoded as a Base64 URL Safe string (see RFC 4648 section 5).
+
+ $chaes_b64url = chaes_file_b64u('filename.dat');
+ #or
+ $chaes_b64url = chaes_file_b64u(*FILEHANDLE);
+
=head1 METHODS
The OO interface provides the same set of functions as L<Crypt::Digest>.
@@ -184,6 +208,10 @@ The OO interface provides the same set of functions as L<Crypt::Digest>.
$result_b64 = $d->b64digest();
+=head2 b64udigest
+
+ $result_b64url = $d->b64udigest();
+
=head1 SEE ALSO
=over 4
diff --git a/lib/Crypt/Digest/MD2.pm b/lib/Crypt/Digest/MD2.pm
index 72e3596e..cdf6d8cb 100644
--- a/lib/Crypt/Digest/MD2.pm
+++ b/lib/Crypt/Digest/MD2.pm
@@ -6,7 +6,7 @@ use strict;
use warnings;
use Exporter 'import';
-our %EXPORT_TAGS = ( all => [qw( md2 md2_hex md2_b64 md2_file md2_file_hex md2_file_b64 )] );
+our %EXPORT_TAGS = ( all => [qw( md2 md2_hex md2_b64 md2_b64u md2_file md2_file_hex md2_file_b64 md2_file_b64u )] );
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
our @EXPORT = qw();
@@ -20,10 +20,12 @@ sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) }
sub md2 { Crypt::Digest::digest_data(__PACKAGE__, @_) }
sub md2_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) }
sub md2_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) }
+sub md2_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) }
sub md2_file { Crypt::Digest::digest_file(__PACKAGE__, @_) }
sub md2_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) }
sub md2_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) }
+sub md2_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) }
1;
@@ -36,20 +38,24 @@ Crypt::Digest::MD2 - Hash function MD2 [size: 128 bits]
=head1 SYNOPSIS
### Functional interface:
- use Crypt::Digest::MD2 qw( md2 md2_hex md2_b64 md2_file md2_file_hex md2_file_b64 );
+ use Crypt::Digest::MD2 qw( md2 md2_hex md2_b64 md2_b64u
+ md2_file md2_file_hex md2_file_b64 md2_file_b64u );
# calculate digest from string/buffer
- $md2_raw = md2('data string');
- $md2_hex = md2_hex('data string');
- $md2_b64 = md2_b64('data string');
+ $md2_raw = md2('data string');
+ $md2_hex = md2_hex('data string');
+ $md2_b64 = md2_b64('data string');
+ $md2_b64u = md2_b64u('data string');
# calculate digest from file
- $md2_raw = md2_file('filename.dat');
- $md2_hex = md2_file_hex('filename.dat');
- $md2_b64 = md2_file_b64('filename.dat');
+ $md2_raw = md2_file('filename.dat');
+ $md2_hex = md2_file_hex('filename.dat');
+ $md2_b64 = md2_file_b64('filename.dat');
+ $md2_b64u = md2_file_b64u('filename.dat');
# calculate digest from filehandle
- $md2_raw = md2_file(*FILEHANDLE);
- $md2_hex = md2_file_hex(*FILEHANDLE);
- $md2_b64 = md2_file_b64(*FILEHANDLE);
+ $md2_raw = md2_file(*FILEHANDLE);
+ $md2_hex = md2_file_hex(*FILEHANDLE);
+ $md2_b64 = md2_file_b64(*FILEHANDLE);
+ $md2_b64u = md2_file_b64u(*FILEHANDLE);
### OO interface:
use Crypt::Digest::MD2;
@@ -58,9 +64,10 @@ Crypt::Digest::MD2 - Hash function MD2 [size: 128 bits]
$d->add('any data');
$d->addfile('filename.dat');
$d->addfile(*FILEHANDLE);
- $result_raw = $d->digest; # raw bytes
- $result_hex = $d->hexdigest; # hexadecimal form
- $result_b64 = $d->b64digest; # Base64 form
+ $result_raw = $d->digest; # raw bytes
+ $result_hex = $d->hexdigest; # hexadecimal form
+ $result_b64 = $d->b64digest; # Base64 form
+ $result_b64u = $d->b64udigest; # Base64 URL Safe form
=head1 DESCRIPTION
@@ -72,7 +79,8 @@ Nothing is exported by default.
You can export selected functions:
- use Crypt::Digest::MD2 qw(md2 md2_hex md2_b64 md2_file md2_file_hex md2_file_b64);
+ use Crypt::Digest::MD2 qw(md2 md2_hex md2_b64 md2_b64u
+ md2_file md2_file_hex md2_file_b64 md2_file_b64u);
Or all of them at once:
@@ -104,6 +112,14 @@ Logically joins all arguments into a single string, and returns its MD2 digest e
#or
$md2_b64 = md2_b64('any data', 'more data', 'even more data');
+=head2 md2_b64u
+
+Logically joins all arguments into a single string, and returns its MD2 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5).
+
+ $md2_b64url = md2_b64u('data string');
+ #or
+ $md2_b64url = md2_b64u('any data', 'more data', 'even more data');
+
=head2 md2_file
Reads file (defined by filename or filehandle) content, and returns its MD2 digest encoded as a binary string.
@@ -130,6 +146,14 @@ Reads file (defined by filename or filehandle) content, and returns its MD2 dige
#or
$md2_b64 = md2_file_b64(*FILEHANDLE);
+=head2 md2_file_b64u
+
+Reads file (defined by filename or filehandle) content, and returns its MD2 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5).
+
+ $md2_b64url = md2_file_b64u('filename.dat');
+ #or
+ $md2_b64url = md2_file_b64u(*FILEHANDLE);
+
=head1 METHODS
The OO interface provides the same set of functions as L<Crypt::Digest>.
@@ -184,6 +208,10 @@ The OO interface provides the same set of functions as L<Crypt::Digest>.
$result_b64 = $d->b64digest();
+=head2 b64udigest
+
+ $result_b64url = $d->b64udigest();
+
=head1 SEE ALSO
=over 4
diff --git a/lib/Crypt/Digest/MD4.pm b/lib/Crypt/Digest/MD4.pm
index 261d60d8..3edb803d 100644
--- a/lib/Crypt/Digest/MD4.pm
+++ b/lib/Crypt/Digest/MD4.pm
@@ -6,7 +6,7 @@ use strict;
use warnings;
use Exporter 'import';
-our %EXPORT_TAGS = ( all => [qw( md4 md4_hex md4_b64 md4_file md4_file_hex md4_file_b64 )] );
+our %EXPORT_TAGS = ( all => [qw( md4 md4_hex md4_b64 md4_b64u md4_file md4_file_hex md4_file_b64 md4_file_b64u )] );
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
our @EXPORT = qw();
@@ -20,10 +20,12 @@ sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) }
sub md4 { Crypt::Digest::digest_data(__PACKAGE__, @_) }
sub md4_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) }
sub md4_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) }
+sub md4_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) }
sub md4_file { Crypt::Digest::digest_file(__PACKAGE__, @_) }
sub md4_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) }
sub md4_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) }
+sub md4_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) }
1;
@@ -36,20 +38,24 @@ Crypt::Digest::MD4 - Hash function MD4 [size: 128 bits]
=head1 SYNOPSIS
### Functional interface:
- use Crypt::Digest::MD4 qw( md4 md4_hex md4_b64 md4_file md4_file_hex md4_file_b64 );
+ use Crypt::Digest::MD4 qw( md4 md4_hex md4_b64 md4_b64u
+ md4_file md4_file_hex md4_file_b64 md4_file_b64u );
# calculate digest from string/buffer
- $md4_raw = md4('data string');
- $md4_hex = md4_hex('data string');
- $md4_b64 = md4_b64('data string');
+ $md4_raw = md4('data string');
+ $md4_hex = md4_hex('data string');
+ $md4_b64 = md4_b64('data string');
+ $md4_b64u = md4_b64u('data string');
# calculate digest from file
- $md4_raw = md4_file('filename.dat');
- $md4_hex = md4_file_hex('filename.dat');
- $md4_b64 = md4_file_b64('filename.dat');
+ $md4_raw = md4_file('filename.dat');
+ $md4_hex = md4_file_hex('filename.dat');
+ $md4_b64 = md4_file_b64('filename.dat');
+ $md4_b64u = md4_file_b64u('filename.dat');
# calculate digest from filehandle
- $md4_raw = md4_file(*FILEHANDLE);
- $md4_hex = md4_file_hex(*FILEHANDLE);
- $md4_b64 = md4_file_b64(*FILEHANDLE);
+ $md4_raw = md4_file(*FILEHANDLE);
+ $md4_hex = md4_file_hex(*FILEHANDLE);
+ $md4_b64 = md4_file_b64(*FILEHANDLE);
+ $md4_b64u = md4_file_b64u(*FILEHANDLE);
### OO interface:
use Crypt::Digest::MD4;
@@ -58,9 +64,10 @@ Crypt::Digest::MD4 - Hash function MD4 [size: 128 bits]
$d->add('any data');
$d->addfile('filename.dat');
$d->addfile(*FILEHANDLE);
- $result_raw = $d->digest; # raw bytes
- $result_hex = $d->hexdigest; # hexadecimal form
- $result_b64 = $d->b64digest; # Base64 form
+ $result_raw = $d->digest; # raw bytes
+ $result_hex = $d->hexdigest; # hexadecimal form
+ $result_b64 = $d->b64digest; # Base64 form
+ $result_b64u = $d->b64udigest; # Base64 URL Safe form
=head1 DESCRIPTION
@@ -72,7 +79,8 @@ Nothing is exported by default.
You can export selected functions:
- use Crypt::Digest::MD4 qw(md4 md4_hex md4_b64 md4_file md4_file_hex md4_file_b64);
+ use Crypt::Digest::MD4 qw(md4 md4_hex md4_b64 md4_b64u
+ md4_file md4_file_hex md4_file_b64 md4_file_b64u);
Or all of them at once:
@@ -104,6 +112,14 @@ Logically joins all arguments into a single string, and returns its MD4 digest e
#or
$md4_b64 = md4_b64('any data', 'more data', 'even more data');
+=head2 md4_b64u
+
+Logically joins all arguments into a single string, and returns its MD4 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5).
+
+ $md4_b64url = md4_b64u('data string');
+ #or
+ $md4_b64url = md4_b64u('any data', 'more data', 'even more data');
+
=head2 md4_file
Reads file (defined by filename or filehandle) content, and returns its MD4 digest encoded as a binary string.
@@ -130,6 +146,14 @@ Reads file (defined by filename or filehandle) content, and returns its MD4 dige
#or
$md4_b64 = md4_file_b64(*FILEHANDLE);
+=head2 md4_file_b64u
+
+Reads file (defined by filename or filehandle) content, and returns its MD4 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5).
+
+ $md4_b64url = md4_file_b64u('filename.dat');
+ #or
+ $md4_b64url = md4_file_b64u(*FILEHANDLE);
+
=head1 METHODS
The OO interface provides the same set of functions as L<Crypt::Digest>.
@@ -184,6 +208,10 @@ The OO interface provides the same set of functions as L<Crypt::Digest>.
$result_b64 = $d->b64digest();
+=head2 b64udigest
+
+ $result_b64url = $d->b64udigest();
+
=head1 SEE ALSO
=over 4
diff --git a/lib/Crypt/Digest/MD5.pm b/lib/Crypt/Digest/MD5.pm
index 10ffba60..4a52e149 100644
--- a/lib/Crypt/Digest/MD5.pm
+++ b/lib/Crypt/Digest/MD5.pm
@@ -6,7 +6,7 @@ use strict;
use warnings;
use Exporter 'import';
-our %EXPORT_TAGS = ( all => [qw( md5 md5_hex md5_b64 md5_file md5_file_hex md5_file_b64 )] );
+our %EXPORT_TAGS = ( all => [qw( md5 md5_hex md5_b64 md5_b64u md5_file md5_file_hex md5_file_b64 md5_file_b64u )] );
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
our @EXPORT = qw();
@@ -20,10 +20,12 @@ sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) }
sub md5 { Crypt::Digest::digest_data(__PACKAGE__, @_) }
sub md5_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) }
sub md5_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) }
+sub md5_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) }
sub md5_file { Crypt::Digest::digest_file(__PACKAGE__, @_) }
sub md5_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) }
sub md5_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) }
+sub md5_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) }
1;
@@ -36,20 +38,24 @@ Crypt::Digest::MD5 - Hash function MD5 [size: 128 bits]
=head1 SYNOPSIS
### Functional interface:
- use Crypt::Digest::MD5 qw( md5 md5_hex md5_b64 md5_file md5_file_hex md5_file_b64 );
+ use Crypt::Digest::MD5 qw( md5 md5_hex md5_b64 md5_b64u
+ md5_file md5_file_hex md5_file_b64 md5_file_b64u );
# calculate digest from string/buffer
- $md5_raw = md5('data string');
- $md5_hex = md5_hex('data string');
- $md5_b64 = md5_b64('data string');
+ $md5_raw = md5('data string');
+ $md5_hex = md5_hex('data string');
+ $md5_b64 = md5_b64('data string');
+ $md5_b64u = md5_b64u('data string');
# calculate digest from file
- $md5_raw = md5_file('filename.dat');
- $md5_hex = md5_file_hex('filename.dat');
- $md5_b64 = md5_file_b64('filename.dat');
+ $md5_raw = md5_file('filename.dat');
+ $md5_hex = md5_file_hex('filename.dat');
+ $md5_b64 = md5_file_b64('filename.dat');
+ $md5_b64u = md5_file_b64u('filename.dat');
# calculate digest from filehandle
- $md5_raw = md5_file(*FILEHANDLE);
- $md5_hex = md5_file_hex(*FILEHANDLE);
- $md5_b64 = md5_file_b64(*FILEHANDLE);
+ $md5_raw = md5_file(*FILEHANDLE);
+ $md5_hex = md5_file_hex(*FILEHANDLE);
+ $md5_b64 = md5_file_b64(*FILEHANDLE);
+ $md5_b64u = md5_file_b64u(*FILEHANDLE);
### OO interface:
use Crypt::Digest::MD5;
@@ -58,9 +64,10 @@ Crypt::Digest::MD5 - Hash function MD5 [size: 128 bits]
$d->add('any data');
$d->addfile('filename.dat');
$d->addfile(*FILEHANDLE);
- $result_raw = $d->digest; # raw bytes
- $result_hex = $d->hexdigest; # hexadecimal form
- $result_b64 = $d->b64digest; # Base64 form
+ $result_raw = $d->digest; # raw bytes
+ $result_hex = $d->hexdigest; # hexadecimal form
+ $result_b64 = $d->b64digest; # Base64 form
+ $result_b64u = $d->b64udigest; # Base64 URL Safe form
=head1 DESCRIPTION
@@ -72,7 +79,8 @@ Nothing is exported by default.
You can export selected functions:
- use Crypt::Digest::MD5 qw(md5 md5_hex md5_b64 md5_file md5_file_hex md5_file_b64);
+ use Crypt::Digest::MD5 qw(md5 md5_hex md5_b64 md5_b64u
+ md5_file md5_file_hex md5_file_b64 md5_file_b64u);
Or all of them at once:
@@ -104,6 +112,14 @@ Logically joins all arguments into a single string, and returns its MD5 digest e
#or
$md5_b64 = md5_b64('any data', 'more data', 'even more data');
+=head2 md5_b64u
+
+Logically joins all arguments into a single string, and returns its MD5 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5).
+
+ $md5_b64url = md5_b64u('data string');
+ #or
+ $md5_b64url = md5_b64u('any data', 'more data', 'even more data');
+
=head2 md5_file
Reads file (defined by filename or filehandle) content, and returns its MD5 digest encoded as a binary string.
@@ -130,6 +146,14 @@ Reads file (defined by filename or filehandle) content, and returns its MD5 dige
#or
$md5_b64 = md5_file_b64(*FILEHANDLE);
+=head2 md5_file_b64u
+
+Reads file (defined by filename or filehandle) content, and returns its MD5 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5).
+
+ $md5_b64url = md5_file_b64u('filename.dat');
+ #or
+ $md5_b64url = md5_file_b64u(*FILEHANDLE);
+
=head1 METHODS
The OO interface provides the same set of functions as L<Crypt::Digest>.
@@ -184,6 +208,10 @@ The OO interface provides the same set of functions as L<Crypt::Digest>.
$result_b64 = $d->b64digest();
+=head2 b64udigest
+
+ $result_b64url = $d->b64udigest();
+
=head1 SEE ALSO
=over 4
diff --git a/lib/Crypt/Digest/RIPEMD128.pm b/lib/Crypt/Digest/RIPEMD128.pm
index 1f86d0cf..50819734 100644
--- a/lib/Crypt/Digest/RIPEMD128.pm
+++ b/lib/Crypt/Digest/RIPEMD128.pm
@@ -6,7 +6,7 @@ use strict;
use warnings;
use Exporter 'import';
-our %EXPORT_TAGS = ( all => [qw( ripemd128 ripemd128_hex ripemd128_b64 ripemd128_file ripemd128_file_hex ripemd128_file_b64 )] );
+our %EXPORT_TAGS = ( all => [qw( ripemd128 ripemd128_hex ripemd128_b64 ripemd128_b64u ripemd128_file ripemd128_file_hex ripemd128_file_b64 ripemd128_file_b64u )] );
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
our @EXPORT = qw();
@@ -20,10 +20,12 @@ sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) }
sub ripemd128 { Crypt::Digest::digest_data(__PACKAGE__, @_) }
sub ripemd128_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) }
sub ripemd128_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) }
+sub ripemd128_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) }
sub ripemd128_file { Crypt::Digest::digest_file(__PACKAGE__, @_) }
sub ripemd128_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) }
sub ripemd128_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) }
+sub ripemd128_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) }
1;
@@ -36,20 +38,24 @@ Crypt::Digest::RIPEMD128 - Hash function RIPEMD-128 [size: 128 bits]
=head1 SYNOPSIS
### Functional interface:
- use Crypt::Digest::RIPEMD128 qw( ripemd128 ripemd128_hex ripemd128_b64 ripemd128_file ripemd128_file_hex ripemd128_file_b64 );
+ use Crypt::Digest::RIPEMD128 qw( ripemd128 ripemd128_hex ripemd128_b64 ripemd128_b64u
+ ripemd128_file ripemd128_file_hex ripemd128_file_b64 ripemd128_file_b64u );
# calculate digest from string/buffer
- $ripemd128_raw = ripemd128('data string');
- $ripemd128_hex = ripemd128_hex('data string');
- $ripemd128_b64 = ripemd128_b64('data string');
+ $ripemd128_raw = ripemd128('data string');
+ $ripemd128_hex = ripemd128_hex('data string');
+ $ripemd128_b64 = ripemd128_b64('data string');
+ $ripemd128_b64u = ripemd128_b64u('data string');
# calculate digest from file
- $ripemd128_raw = ripemd128_file('filename.dat');
- $ripemd128_hex = ripemd128_file_hex('filename.dat');
- $ripemd128_b64 = ripemd128_file_b64('filename.dat');
+ $ripemd128_raw = ripemd128_file('filename.dat');
+ $ripemd128_hex = ripemd128_file_hex('filename.dat');
+ $ripemd128_b64 = ripemd128_file_b64('filename.dat');
+ $ripemd128_b64u = ripemd128_file_b64u('filename.dat');
# calculate digest from filehandle
- $ripemd128_raw = ripemd128_file(*FILEHANDLE);
- $ripemd128_hex = ripemd128_file_hex(*FILEHANDLE);
- $ripemd128_b64 = ripemd128_file_b64(*FILEHANDLE);
+ $ripemd128_raw = ripemd128_file(*FILEHANDLE);
+ $ripemd128_hex = ripemd128_file_hex(*FILEHANDLE);
+ $ripemd128_b64 = ripemd128_file_b64(*FILEHANDLE);
+ $ripemd128_b64u = ripemd128_file_b64u(*FILEHANDLE);
### OO interface:
use Crypt::Digest::RIPEMD128;
@@ -58,9 +64,10 @@ Crypt::Digest::RIPEMD128 - Hash function RIPEMD-128 [size: 128 bits]
$d->add('any data');
$d->addfile('filename.dat');
$d->addfile(*FILEHANDLE);
- $result_raw = $d->digest; # raw bytes
- $result_hex = $d->hexdigest; # hexadecimal form
- $result_b64 = $d->b64digest; # Base64 form
+ $result_raw = $d->digest; # raw bytes
+ $result_hex = $d->hexdigest; # hexadecimal form
+ $result_b64 = $d->b64digest; # Base64 form
+ $result_b64u = $d->b64udigest; # Base64 URL Safe form
=head1 DESCRIPTION
@@ -72,7 +79,8 @@ Nothing is exported by default.
You can export selected functions:
- use Crypt::Digest::RIPEMD128 qw(ripemd128 ripemd128_hex ripemd128_b64 ripemd128_file ripemd128_file_hex ripemd128_file_b64);
+ use Crypt::Digest::RIPEMD128 qw(ripemd128 ripemd128_hex ripemd128_b64 ripemd128_b64u
+ ripemd128_file ripemd128_file_hex ripemd128_file_b64 ripemd128_file_b64u);
Or all of them at once:
@@ -104,6 +112,14 @@ Logically joins all arguments into a single string, and returns its RIPEMD128 di
#or
$ripemd128_b64 = ripemd128_b64('any data', 'more data', 'even more data');
+=head2 ripemd128_b64u
+
+Logically joins all arguments into a single string, and returns its RIPEMD128 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5).
+
+ $ripemd128_b64url = ripemd128_b64u('data string');
+ #or
+ $ripemd128_b64url = ripemd128_b64u('any data', 'more data', 'even more data');
+
=head2 ripemd128_file
Reads file (defined by filename or filehandle) content, and returns its RIPEMD128 digest encoded as a binary string.
@@ -130,6 +146,14 @@ Reads file (defined by filename or filehandle) content, and returns its RIPEMD12
#or
$ripemd128_b64 = ripemd128_file_b64(*FILEHANDLE);
+=head2 ripemd128_file_b64u
+
+Reads file (defined by filename or filehandle) content, and returns its RIPEMD128 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5).
+
+ $ripemd128_b64url = ripemd128_file_b64u('filename.dat');
+ #or
+ $ripemd128_b64url = ripemd128_file_b64u(*FILEHANDLE);
+
=head1 METHODS
The OO interface provides the same set of functions as L<Crypt::Digest>.
@@ -184,6 +208,10 @@ The OO interface provides the same set of functions as L<Crypt::Digest>.
$result_b64 = $d->b64digest();
+=head2 b64udigest
+
+ $result_b64url = $d->b64udigest();
+
=head1 SEE ALSO
=over 4
diff --git a/lib/Crypt/Digest/RIPEMD160.pm b/lib/Crypt/Digest/RIPEMD160.pm
index d8f205cd..0a28df4c 100644
--- a/lib/Crypt/Digest/RIPEMD160.pm
+++ b/lib/Crypt/Digest/RIPEMD160.pm
@@ -6,7 +6,7 @@ use strict;
use warnings;
use Exporter 'import';
-our %EXPORT_TAGS = ( all => [qw( ripemd160 ripemd160_hex ripemd160_b64 ripemd160_file ripemd160_file_hex ripemd160_file_b64 )] );
+our %EXPORT_TAGS = ( all => [qw( ripemd160 ripemd160_hex ripemd160_b64 ripemd160_b64u ripemd160_file ripemd160_file_hex ripemd160_file_b64 ripemd160_file_b64u )] );
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
our @EXPORT = qw();
@@ -20,10 +20,12 @@ sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) }
sub ripemd160 { Crypt::Digest::digest_data(__PACKAGE__, @_) }
sub ripemd160_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) }
sub ripemd160_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) }
+sub ripemd160_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) }
sub ripemd160_file { Crypt::Digest::digest_file(__PACKAGE__, @_) }
sub ripemd160_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) }
sub ripemd160_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) }
+sub ripemd160_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) }
1;
@@ -36,20 +38,24 @@ Crypt::Digest::RIPEMD160 - Hash function RIPEMD-160 [size: 160 bits]
=head1 SYNOPSIS
### Functional interface:
- use Crypt::Digest::RIPEMD160 qw( ripemd160 ripemd160_hex ripemd160_b64 ripemd160_file ripemd160_file_hex ripemd160_file_b64 );
+ use Crypt::Digest::RIPEMD160 qw( ripemd160 ripemd160_hex ripemd160_b64 ripemd160_b64u
+ ripemd160_file ripemd160_file_hex ripemd160_file_b64 ripemd160_file_b64u );
# calculate digest from string/buffer
- $ripemd160_raw = ripemd160('data string');
- $ripemd160_hex = ripemd160_hex('data string');
- $ripemd160_b64 = ripemd160_b64('data string');
+ $ripemd160_raw = ripemd160('data string');
+ $ripemd160_hex = ripemd160_hex('data string');
+ $ripemd160_b64 = ripemd160_b64('data string');
+ $ripemd160_b64u = ripemd160_b64u('data string');
# calculate digest from file
- $ripemd160_raw = ripemd160_file('filename.dat');
- $ripemd160_hex = ripemd160_file_hex('filename.dat');
- $ripemd160_b64 = ripemd160_file_b64('filename.dat');
+ $ripemd160_raw = ripemd160_file('filename.dat');
+ $ripemd160_hex = ripemd160_file_hex('filename.dat');
+ $ripemd160_b64 = ripemd160_file_b64('filename.dat');
+ $ripemd160_b64u = ripemd160_file_b64u('filename.dat');
# calculate digest from filehandle
- $ripemd160_raw = ripemd160_file(*FILEHANDLE);
- $ripemd160_hex = ripemd160_file_hex(*FILEHANDLE);
- $ripemd160_b64 = ripemd160_file_b64(*FILEHANDLE);
+ $ripemd160_raw = ripemd160_file(*FILEHANDLE);
+ $ripemd160_hex = ripemd160_file_hex(*FILEHANDLE);
+ $ripemd160_b64 = ripemd160_file_b64(*FILEHANDLE);
+ $ripemd160_b64u = ripemd160_file_b64u(*FILEHANDLE);
### OO interface:
use Crypt::Digest::RIPEMD160;
@@ -58,9 +64,10 @@ Crypt::Digest::RIPEMD160 - Hash function RIPEMD-160 [size: 160 bits]
$d->add('any data');
$d->addfile('filename.dat');
$d->addfile(*FILEHANDLE);
- $result_raw = $d->digest; # raw bytes
- $result_hex = $d->hexdigest; # hexadecimal form
- $result_b64 = $d->b64digest; # Base64 form
+ $result_raw = $d->digest; # raw bytes
+ $result_hex = $d->hexdigest; # hexadecimal form
+ $result_b64 = $d->b64digest; # Base64 form
+ $result_b64u = $d->b64udigest; # Base64 URL Safe form
=head1 DESCRIPTION
@@ -72,7 +79,8 @@ Nothing is exported by default.
You can export selected functions:
- use Crypt::Digest::RIPEMD160 qw(ripemd160 ripemd160_hex ripemd160_b64 ripemd160_file ripemd160_file_hex ripemd160_file_b64);
+ use Crypt::Digest::RIPEMD160 qw(ripemd160 ripemd160_hex ripemd160_b64 ripemd160_b64u
+ ripemd160_file ripemd160_file_hex ripemd160_file_b64 ripemd160_file_b64u);
Or all of them at once:
@@ -104,6 +112,14 @@ Logically joins all arguments into a single string, and returns its RIPEMD160 di
#or
$ripemd160_b64 = ripemd160_b64('any data', 'more data', 'even more data');
+=head2 ripemd160_b64u
+
+Logically joins all arguments into a single string, and returns its RIPEMD160 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5).
+
+ $ripemd160_b64url = ripemd160_b64u('data string');
+ #or
+ $ripemd160_b64url = ripemd160_b64u('any data', 'more data', 'even more data');
+
=head2 ripemd160_file
Reads file (defined by filename or filehandle) content, and returns its RIPEMD160 digest encoded as a binary string.
@@ -130,6 +146,14 @@ Reads file (defined by filename or filehandle) content, and returns its RIPEMD16
#or
$ripemd160_b64 = ripemd160_file_b64(*FILEHANDLE);
+=head2 ripemd160_file_b64u
+
+Reads file (defined by filename or filehandle) content, and returns its RIPEMD160 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5).
+
+ $ripemd160_b64url = ripemd160_file_b64u('filename.dat');
+ #or
+ $ripemd160_b64url = ripemd160_file_b64u(*FILEHANDLE);
+
=head1 METHODS
The OO interface provides the same set of functions as L<Crypt::Digest>.
@@ -184,6 +208,10 @@ The OO interface provides the same set of functions as L<Crypt::Digest>.
$result_b64 = $d->b64digest();
+=head2 b64udigest
+
+ $result_b64url = $d->b64udigest();
+
=head1 SEE ALSO
=over 4
diff --git a/lib/Crypt/Digest/RIPEMD256.pm b/lib/Crypt/Digest/RIPEMD256.pm
index 0be098a5..41934eea 100644
--- a/lib/Crypt/Digest/RIPEMD256.pm
+++ b/lib/Crypt/Digest/RIPEMD256.pm
@@ -6,7 +6,7 @@ use strict;
use warnings;
use Exporter 'import';
-our %EXPORT_TAGS = ( all => [qw( ripemd256 ripemd256_hex ripemd256_b64 ripemd256_file ripemd256_file_hex ripemd256_file_b64 )] );
+our %EXPORT_TAGS = ( all => [qw( ripemd256 ripemd256_hex ripemd256_b64 ripemd256_b64u ripemd256_file ripemd256_file_hex ripemd256_file_b64 ripemd256_file_b64u )] );
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
our @EXPORT = qw();
@@ -20,10 +20,12 @@ sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) }
sub ripemd256 { Crypt::Digest::digest_data(__PACKAGE__, @_) }
sub ripemd256_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) }
sub ripemd256_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) }
+sub ripemd256_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) }
sub ripemd256_file { Crypt::Digest::digest_file(__PACKAGE__, @_) }
sub ripemd256_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) }
sub ripemd256_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) }
+sub ripemd256_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) }
1;
@@ -36,20 +38,24 @@ Crypt::Digest::RIPEMD256 - Hash function RIPEMD-256 [size: 256 bits]
=head1 SYNOPSIS
### Functional interface:
- use Crypt::Digest::RIPEMD256 qw( ripemd256 ripemd256_hex ripemd256_b64 ripemd256_file ripemd256_file_hex ripemd256_file_b64 );
+ use Crypt::Digest::RIPEMD256 qw( ripemd256 ripemd256_hex ripemd256_b64 ripemd256_b64u
+ ripemd256_file ripemd256_file_hex ripemd256_file_b64 ripemd256_file_b64u );
# calculate digest from string/buffer
- $ripemd256_raw = ripemd256('data string');
- $ripemd256_hex = ripemd256_hex('data string');
- $ripemd256_b64 = ripemd256_b64('data string');
+ $ripemd256_raw = ripemd256('data string');
+ $ripemd256_hex = ripemd256_hex('data string');
+ $ripemd256_b64 = ripemd256_b64('data string');
+ $ripemd256_b64u = ripemd256_b64u('data string');
# calculate digest from file
- $ripemd256_raw = ripemd256_file('filename.dat');
- $ripemd256_hex = ripemd256_file_hex('filename.dat');
- $ripemd256_b64 = ripemd256_file_b64('filename.dat');
+ $ripemd256_raw = ripemd256_file('filename.dat');
+ $ripemd256_hex = ripemd256_file_hex('filename.dat');
+ $ripemd256_b64 = ripemd256_file_b64('filename.dat');
+ $ripemd256_b64u = ripemd256_file_b64u('filename.dat');
# calculate digest from filehandle
- $ripemd256_raw = ripemd256_file(*FILEHANDLE);
- $ripemd256_hex = ripemd256_file_hex(*FILEHANDLE);
- $ripemd256_b64 = ripemd256_file_b64(*FILEHANDLE);
+ $ripemd256_raw = ripemd256_file(*FILEHANDLE);
+ $ripemd256_hex = ripemd256_file_hex(*FILEHANDLE);
+ $ripemd256_b64 = ripemd256_file_b64(*FILEHANDLE);
+ $ripemd256_b64u = ripemd256_file_b64u(*FILEHANDLE);
### OO interface:
use Crypt::Digest::RIPEMD256;
@@ -58,9 +64,10 @@ Crypt::Digest::RIPEMD256 - Hash function RIPEMD-256 [size: 256 bits]
$d->add('any data');
$d->addfile('filename.dat');
$d->addfile(*FILEHANDLE);
- $result_raw = $d->digest; # raw bytes
- $result_hex = $d->hexdigest; # hexadecimal form
- $result_b64 = $d->b64digest; # Base64 form
+ $result_raw = $d->digest; # raw bytes
+ $result_hex = $d->hexdigest; # hexadecimal form
+ $result_b64 = $d->b64digest; # Base64 form
+ $result_b64u = $d->b64udigest; # Base64 URL Safe form
=head1 DESCRIPTION
@@ -72,7 +79,8 @@ Nothing is exported by default.
You can export selected functions:
- use Crypt::Digest::RIPEMD256 qw(ripemd256 ripemd256_hex ripemd256_b64 ripemd256_file ripemd256_file_hex ripemd256_file_b64);
+ use Crypt::Digest::RIPEMD256 qw(ripemd256 ripemd256_hex ripemd256_b64 ripemd256_b64u
+ ripemd256_file ripemd256_file_hex ripemd256_file_b64 ripemd256_file_b64u);
Or all of them at once:
@@ -104,6 +112,14 @@ Logically joins all arguments into a single string, and returns its RIPEMD256 di
#or
$ripemd256_b64 = ripemd256_b64('any data', 'more data', 'even more data');
+=head2 ripemd256_b64u
+
+Logically joins all arguments into a single string, and returns its RIPEMD256 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5).
+
+ $ripemd256_b64url = ripemd256_b64u('data string');
+ #or
+ $ripemd256_b64url = ripemd256_b64u('any data', 'more data', 'even more data');
+
=head2 ripemd256_file
Reads file (defined by filename or filehandle) content, and returns its RIPEMD256 digest encoded as a binary string.
@@ -130,6 +146,14 @@ Reads file (defined by filename or filehandle) content, and returns its RIPEMD25
#or
$ripemd256_b64 = ripemd256_file_b64(*FILEHANDLE);
+=head2 ripemd256_file_b64u
+
+Reads file (defined by filename or filehandle) content, and returns its RIPEMD256 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5).
+
+ $ripemd256_b64url = ripemd256_file_b64u('filename.dat');
+ #or
+ $ripemd256_b64url = ripemd256_file_b64u(*FILEHANDLE);
+
=head1 METHODS
The OO interface provides the same set of functions as L<Crypt::Digest>.
@@ -184,6 +208,10 @@ The OO interface provides the same set of functions as L<Crypt::Digest>.
$result_b64 = $d->b64digest();
+=head2 b64udigest
+
+ $result_b64url = $d->b64udigest();
+
=head1 SEE ALSO
=over 4
diff --git a/lib/Crypt/Digest/RIPEMD320.pm b/lib/Crypt/Digest/RIPEMD320.pm
index 8dc7bc0c..a06731c7 100644
--- a/lib/Crypt/Digest/RIPEMD320.pm
+++ b/lib/Crypt/Digest/RIPEMD320.pm
@@ -6,7 +6,7 @@ use strict;
use warnings;
use Exporter 'import';
-our %EXPORT_TAGS = ( all => [qw( ripemd320 ripemd320_hex ripemd320_b64 ripemd320_file ripemd320_file_hex ripemd320_file_b64 )] );
+our %EXPORT_TAGS = ( all => [qw( ripemd320 ripemd320_hex ripemd320_b64 ripemd320_b64u ripemd320_file ripemd320_file_hex ripemd320_file_b64 ripemd320_file_b64u )] );
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
our @EXPORT = qw();
@@ -20,10 +20,12 @@ sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) }
sub ripemd320 { Crypt::Digest::digest_data(__PACKAGE__, @_) }
sub ripemd320_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) }
sub ripemd320_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) }
+sub ripemd320_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) }
sub ripemd320_file { Crypt::Digest::digest_file(__PACKAGE__, @_) }
sub ripemd320_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) }
sub ripemd320_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) }
+sub ripemd320_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) }
1;
@@ -36,20 +38,24 @@ Crypt::Digest::RIPEMD320 - Hash function RIPEMD-320 [size: 320 bits]
=head1 SYNOPSIS
### Functional interface:
- use Crypt::Digest::RIPEMD320 qw( ripemd320 ripemd320_hex ripemd320_b64 ripemd320_file ripemd320_file_hex ripemd320_file_b64 );
+ use Crypt::Digest::RIPEMD320 qw( ripemd320 ripemd320_hex ripemd320_b64 ripemd320_b64u
+ ripemd320_file ripemd320_file_hex ripemd320_file_b64 ripemd320_file_b64u );
# calculate digest from string/buffer
- $ripemd320_raw = ripemd320('data string');
- $ripemd320_hex = ripemd320_hex('data string');
- $ripemd320_b64 = ripemd320_b64('data string');
+ $ripemd320_raw = ripemd320('data string');
+ $ripemd320_hex = ripemd320_hex('data string');
+ $ripemd320_b64 = ripemd320_b64('data string');
+ $ripemd320_b64u = ripemd320_b64u('data string');
# calculate digest from file
- $ripemd320_raw = ripemd320_file('filename.dat');
- $ripemd320_hex = ripemd320_file_hex('filename.dat');
- $ripemd320_b64 = ripemd320_file_b64('filename.dat');
+ $ripemd320_raw = ripemd320_file('filename.dat');
+ $ripemd320_hex = ripemd320_file_hex('filename.dat');
+ $ripemd320_b64 = ripemd320_file_b64('filename.dat');
+ $ripemd320_b64u = ripemd320_file_b64u('filename.dat');
# calculate digest from filehandle
- $ripemd320_raw = ripemd320_file(*FILEHANDLE);
- $ripemd320_hex = ripemd320_file_hex(*FILEHANDLE);
- $ripemd320_b64 = ripemd320_file_b64(*FILEHANDLE);
+ $ripemd320_raw = ripemd320_file(*FILEHANDLE);
+ $ripemd320_hex = ripemd320_file_hex(*FILEHANDLE);
+ $ripemd320_b64 = ripemd320_file_b64(*FILEHANDLE);
+ $ripemd320_b64u = ripemd320_file_b64u(*FILEHANDLE);
### OO interface:
use Crypt::Digest::RIPEMD320;
@@ -58,9 +64,10 @@ Crypt::Digest::RIPEMD320 - Hash function RIPEMD-320 [size: 320 bits]
$d->add('any data');
$d->addfile('filename.dat');
$d->addfile(*FILEHANDLE);
- $result_raw = $d->digest; # raw bytes
- $result_hex = $d->hexdigest; # hexadecimal form
- $result_b64 = $d->b64digest; # Base64 form
+ $result_raw = $d->digest; # raw bytes
+ $result_hex = $d->hexdigest; # hexadecimal form
+ $result_b64 = $d->b64digest; # Base64 form
+ $result_b64u = $d->b64udigest; # Base64 URL Safe form
=head1 DESCRIPTION
@@ -72,7 +79,8 @@ Nothing is exported by default.
You can export selected functions:
- use Crypt::Digest::RIPEMD320 qw(ripemd320 ripemd320_hex ripemd320_b64 ripemd320_file ripemd320_file_hex ripemd320_file_b64);
+ use Crypt::Digest::RIPEMD320 qw(ripemd320 ripemd320_hex ripemd320_b64 ripemd320_b64u
+ ripemd320_file ripemd320_file_hex ripemd320_file_b64 ripemd320_file_b64u);
Or all of them at once:
@@ -104,6 +112,14 @@ Logically joins all arguments into a single string, and returns its RIPEMD320 di
#or
$ripemd320_b64 = ripemd320_b64('any data', 'more data', 'even more data');
+=head2 ripemd320_b64u
+
+Logically joins all arguments into a single string, and returns its RIPEMD320 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5).
+
+ $ripemd320_b64url = ripemd320_b64u('data string');
+ #or
+ $ripemd320_b64url = ripemd320_b64u('any data', 'more data', 'even more data');
+
=head2 ripemd320_file
Reads file (defined by filename or filehandle) content, and returns its RIPEMD320 digest encoded as a binary string.
@@ -130,6 +146,14 @@ Reads file (defined by filename or filehandle) content, and returns its RIPEMD32
#or
$ripemd320_b64 = ripemd320_file_b64(*FILEHANDLE);
+=head2 ripemd320_file_b64u
+
+Reads file (defined by filename or filehandle) content, and returns its RIPEMD320 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5).
+
+ $ripemd320_b64url = ripemd320_file_b64u('filename.dat');
+ #or
+ $ripemd320_b64url = ripemd320_file_b64u(*FILEHANDLE);
+
=head1 METHODS
The OO interface provides the same set of functions as L<Crypt::Digest>.
@@ -184,6 +208,10 @@ The OO interface provides the same set of functions as L<Crypt::Digest>.
$result_b64 = $d->b64digest();
+=head2 b64udigest
+
+ $result_b64url = $d->b64udigest();
+
=head1 SEE ALSO
=over 4
diff --git a/lib/Crypt/Digest/SHA1.pm b/lib/Crypt/Digest/SHA1.pm
index 77e40a17..43137e75 100644
--- a/lib/Crypt/Digest/SHA1.pm
+++ b/lib/Crypt/Digest/SHA1.pm
@@ -6,7 +6,7 @@ use strict;
use warnings;
use Exporter 'import';
-our %EXPORT_TAGS = ( all => [qw( sha1 sha1_hex sha1_b64 sha1_file sha1_file_hex sha1_file_b64 )] );
+our %EXPORT_TAGS = ( all => [qw( sha1 sha1_hex sha1_b64 sha1_b64u sha1_file sha1_file_hex sha1_file_b64 sha1_file_b64u )] );
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
our @EXPORT = qw();
@@ -20,10 +20,12 @@ sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) }
sub sha1 { Crypt::Digest::digest_data(__PACKAGE__, @_) }
sub sha1_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) }
sub sha1_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) }
+sub sha1_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) }
sub sha1_file { Crypt::Digest::digest_file(__PACKAGE__, @_) }
sub sha1_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) }
sub sha1_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) }
+sub sha1_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) }
1;
@@ -36,20 +38,24 @@ Crypt::Digest::SHA1 - Hash function SHA-1 [size: 160 bits]
=head1 SYNOPSIS
### Functional interface:
- use Crypt::Digest::SHA1 qw( sha1 sha1_hex sha1_b64 sha1_file sha1_file_hex sha1_file_b64 );
+ use Crypt::Digest::SHA1 qw( sha1 sha1_hex sha1_b64 sha1_b64u
+ sha1_file sha1_file_hex sha1_file_b64 sha1_file_b64u );
# calculate digest from string/buffer
- $sha1_raw = sha1('data string');
- $sha1_hex = sha1_hex('data string');
- $sha1_b64 = sha1_b64('data string');
+ $sha1_raw = sha1('data string');
+ $sha1_hex = sha1_hex('data string');
+ $sha1_b64 = sha1_b64('data string');
+ $sha1_b64u = sha1_b64u('data string');
# calculate digest from file
- $sha1_raw = sha1_file('filename.dat');
- $sha1_hex = sha1_file_hex('filename.dat');
- $sha1_b64 = sha1_file_b64('filename.dat');
+ $sha1_raw = sha1_file('filename.dat');
+ $sha1_hex = sha1_file_hex('filename.dat');
+ $sha1_b64 = sha1_file_b64('filename.dat');
+ $sha1_b64u = sha1_file_b64u('filename.dat');
# calculate digest from filehandle
- $sha1_raw = sha1_file(*FILEHANDLE);
- $sha1_hex = sha1_file_hex(*FILEHANDLE);
- $sha1_b64 = sha1_file_b64(*FILEHANDLE);
+ $sha1_raw = sha1_file(*FILEHANDLE);
+ $sha1_hex = sha1_file_hex(*FILEHANDLE);
+ $sha1_b64 = sha1_file_b64(*FILEHANDLE);
+ $sha1_b64u = sha1_file_b64u(*FILEHANDLE);
### OO interface:
use Crypt::Digest::SHA1;
@@ -58,9 +64,10 @@ Crypt::Digest::SHA1 - Hash function SHA-1 [size: 160 bits]
$d->add('any data');
$d->addfile('filename.dat');
$d->addfile(*FILEHANDLE);
- $result_raw = $d->digest; # raw bytes
- $result_hex = $d->hexdigest; # hexadecimal form
- $result_b64 = $d->b64digest; # Base64 form
+ $result_raw = $d->digest; # raw bytes
+ $result_hex = $d->hexdigest; # hexadecimal form
+ $result_b64 = $d->b64digest; # Base64 form
+ $result_b64u = $d->b64udigest; # Base64 URL Safe form
=head1 DESCRIPTION
@@ -72,7 +79,8 @@ Nothing is exported by default.
You can export selected functions:
- use Crypt::Digest::SHA1 qw(sha1 sha1_hex sha1_b64 sha1_file sha1_file_hex sha1_file_b64);
+ use Crypt::Digest::SHA1 qw(sha1 sha1_hex sha1_b64 sha1_b64u
+ sha1_file sha1_file_hex sha1_file_b64 sha1_file_b64u);
Or all of them at once:
@@ -104,6 +112,14 @@ Logically joins all arguments into a single string, and returns its SHA1 digest
#or
$sha1_b64 = sha1_b64('any data', 'more data', 'even more data');
+=head2 sha1_b64u
+
+Logically joins all arguments into a single string, and returns its SHA1 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5).
+
+ $sha1_b64url = sha1_b64u('data string');
+ #or
+ $sha1_b64url = sha1_b64u('any data', 'more data', 'even more data');
+
=head2 sha1_file
Reads file (defined by filename or filehandle) content, and returns its SHA1 digest encoded as a binary string.
@@ -130,6 +146,14 @@ Reads file (defined by filename or filehandle) content, and returns its SHA1 dig
#or
$sha1_b64 = sha1_file_b64(*FILEHANDLE);
+=head2 sha1_file_b64u
+
+Reads file (defined by filename or filehandle) content, and returns its SHA1 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5).
+
+ $sha1_b64url = sha1_file_b64u('filename.dat');
+ #or
+ $sha1_b64url = sha1_file_b64u(*FILEHANDLE);
+
=head1 METHODS
The OO interface provides the same set of functions as L<Crypt::Digest>.
@@ -184,6 +208,10 @@ The OO interface provides the same set of functions as L<Crypt::Digest>.
$result_b64 = $d->b64digest();
+=head2 b64udigest
+
+ $result_b64url = $d->b64udigest();
+
=head1 SEE ALSO
=over 4
diff --git a/lib/Crypt/Digest/SHA224.pm b/lib/Crypt/Digest/SHA224.pm
index fe9484a0..003754f1 100644
--- a/lib/Crypt/Digest/SHA224.pm
+++ b/lib/Crypt/Digest/SHA224.pm
@@ -6,7 +6,7 @@ use strict;
use warnings;
use Exporter 'import';
-our %EXPORT_TAGS = ( all => [qw( sha224 sha224_hex sha224_b64 sha224_file sha224_file_hex sha224_file_b64 )] );
+our %EXPORT_TAGS = ( all => [qw( sha224 sha224_hex sha224_b64 sha224_b64u sha224_file sha224_file_hex sha224_file_b64 sha224_file_b64u )] );
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
our @EXPORT = qw();
@@ -20,10 +20,12 @@ sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) }
sub sha224 { Crypt::Digest::digest_data(__PACKAGE__, @_) }
sub sha224_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) }
sub sha224_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) }
+sub sha224_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) }
sub sha224_file { Crypt::Digest::digest_file(__PACKAGE__, @_) }
sub sha224_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) }
sub sha224_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) }
+sub sha224_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) }
1;
@@ -36,20 +38,24 @@ Crypt::Digest::SHA224 - Hash function SHA-224 [size: 224 bits]
=head1 SYNOPSIS
### Functional interface:
- use Crypt::Digest::SHA224 qw( sha224 sha224_hex sha224_b64 sha224_file sha224_file_hex sha224_file_b64 );
+ use Crypt::Digest::SHA224 qw( sha224 sha224_hex sha224_b64 sha224_b64u
+ sha224_file sha224_file_hex sha224_file_b64 sha224_file_b64u );
# calculate digest from string/buffer
- $sha224_raw = sha224('data string');
- $sha224_hex = sha224_hex('data string');
- $sha224_b64 = sha224_b64('data string');
+ $sha224_raw = sha224('data string');
+ $sha224_hex = sha224_hex('data string');
+ $sha224_b64 = sha224_b64('data string');
+ $sha224_b64u = sha224_b64u('data string');
# calculate digest from file
- $sha224_raw = sha224_file('filename.dat');
- $sha224_hex = sha224_file_hex('filename.dat');
- $sha224_b64 = sha224_file_b64('filename.dat');
+ $sha224_raw = sha224_file('filename.dat');
+ $sha224_hex = sha224_file_hex('filename.dat');
+ $sha224_b64 = sha224_file_b64('filename.dat');
+ $sha224_b64u = sha224_file_b64u('filename.dat');
# calculate digest from filehandle
- $sha224_raw = sha224_file(*FILEHANDLE);
- $sha224_hex = sha224_file_hex(*FILEHANDLE);
- $sha224_b64 = sha224_file_b64(*FILEHANDLE);
+ $sha224_raw = sha224_file(*FILEHANDLE);
+ $sha224_hex = sha224_file_hex(*FILEHANDLE);
+ $sha224_b64 = sha224_file_b64(*FILEHANDLE);
+ $sha224_b64u = sha224_file_b64u(*FILEHANDLE);
### OO interface:
use Crypt::Digest::SHA224;
@@ -58,9 +64,10 @@ Crypt::Digest::SHA224 - Hash function SHA-224 [size: 224 bits]
$d->add('any data');
$d->addfile('filename.dat');
$d->addfile(*FILEHANDLE);
- $result_raw = $d->digest; # raw bytes
- $result_hex = $d->hexdigest; # hexadecimal form
- $result_b64 = $d->b64digest; # Base64 form
+ $result_raw = $d->digest; # raw bytes
+ $result_hex = $d->hexdigest; # hexadecimal form
+ $result_b64 = $d->b64digest; # Base64 form
+ $result_b64u = $d->b64udigest; # Base64 URL Safe form
=head1 DESCRIPTION
@@ -72,7 +79,8 @@ Nothing is exported by default.
You can export selected functions:
- use Crypt::Digest::SHA224 qw(sha224 sha224_hex sha224_b64 sha224_file sha224_file_hex sha224_file_b64);
+ use Crypt::Digest::SHA224 qw(sha224 sha224_hex sha224_b64 sha224_b64u
+ sha224_file sha224_file_hex sha224_file_b64 sha224_file_b64u);
Or all of them at once:
@@ -104,6 +112,14 @@ Logically joins all arguments into a single string, and returns its SHA224 diges
#or
$sha224_b64 = sha224_b64('any data', 'more data', 'even more data');
+=head2 sha224_b64u
+
+Logically joins all arguments into a single string, and returns its SHA224 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5).
+
+ $sha224_b64url = sha224_b64u('data string');
+ #or
+ $sha224_b64url = sha224_b64u('any data', 'more data', 'even more data');
+
=head2 sha224_file
Reads file (defined by filename or filehandle) content, and returns its SHA224 digest encoded as a binary string.
@@ -130,6 +146,14 @@ Reads file (defined by filename or filehandle) content, and returns its SHA224 d
#or
$sha224_b64 = sha224_file_b64(*FILEHANDLE);
+=head2 sha224_file_b64u
+
+Reads file (defined by filename or filehandle) content, and returns its SHA224 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5).
+
+ $sha224_b64url = sha224_file_b64u('filename.dat');
+ #or
+ $sha224_b64url = sha224_file_b64u(*FILEHANDLE);
+
=head1 METHODS
The OO interface provides the same set of functions as L<Crypt::Digest>.
@@ -184,6 +208,10 @@ The OO interface provides the same set of functions as L<Crypt::Digest>.
$result_b64 = $d->b64digest();
+=head2 b64udigest
+
+ $result_b64url = $d->b64udigest();
+
=head1 SEE ALSO
=over 4
diff --git a/lib/Crypt/Digest/SHA256.pm b/lib/Crypt/Digest/SHA256.pm
index 9536ecff..74437713 100644
--- a/lib/Crypt/Digest/SHA256.pm
+++ b/lib/Crypt/Digest/SHA256.pm
@@ -6,7 +6,7 @@ use strict;
use warnings;
use Exporter 'import';
-our %EXPORT_TAGS = ( all => [qw( sha256 sha256_hex sha256_b64 sha256_file sha256_file_hex sha256_file_b64 )] );
+our %EXPORT_TAGS = ( all => [qw( sha256 sha256_hex sha256_b64 sha256_b64u sha256_file sha256_file_hex sha256_file_b64 sha256_file_b64u )] );
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
our @EXPORT = qw();
@@ -20,10 +20,12 @@ sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) }
sub sha256 { Crypt::Digest::digest_data(__PACKAGE__, @_) }
sub sha256_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) }
sub sha256_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) }
+sub sha256_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) }
sub sha256_file { Crypt::Digest::digest_file(__PACKAGE__, @_) }
sub sha256_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) }
sub sha256_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) }
+sub sha256_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) }
1;
@@ -36,20 +38,24 @@ Crypt::Digest::SHA256 - Hash function SHA-256 [size: 256 bits]
=head1 SYNOPSIS
### Functional interface:
- use Crypt::Digest::SHA256 qw( sha256 sha256_hex sha256_b64 sha256_file sha256_file_hex sha256_file_b64 );
+ use Crypt::Digest::SHA256 qw( sha256 sha256_hex sha256_b64 sha256_b64u
+ sha256_file sha256_file_hex sha256_file_b64 sha256_file_b64u );
# calculate digest from string/buffer
- $sha256_raw = sha256('data string');
- $sha256_hex = sha256_hex('data string');
- $sha256_b64 = sha256_b64('data string');
+ $sha256_raw = sha256('data string');
+ $sha256_hex = sha256_hex('data string');
+ $sha256_b64 = sha256_b64('data string');
+ $sha256_b64u = sha256_b64u('data string');
# calculate digest from file
- $sha256_raw = sha256_file('filename.dat');
- $sha256_hex = sha256_file_hex('filename.dat');
- $sha256_b64 = sha256_file_b64('filename.dat');
+ $sha256_raw = sha256_file('filename.dat');
+ $sha256_hex = sha256_file_hex('filename.dat');
+ $sha256_b64 = sha256_file_b64('filename.dat');
+ $sha256_b64u = sha256_file_b64u('filename.dat');
# calculate digest from filehandle
- $sha256_raw = sha256_file(*FILEHANDLE);
- $sha256_hex = sha256_file_hex(*FILEHANDLE);
- $sha256_b64 = sha256_file_b64(*FILEHANDLE);
+ $sha256_raw = sha256_file(*FILEHANDLE);
+ $sha256_hex = sha256_file_hex(*FILEHANDLE);
+ $sha256_b64 = sha256_file_b64(*FILEHANDLE);
+ $sha256_b64u = sha256_file_b64u(*FILEHANDLE);
### OO interface:
use Crypt::Digest::SHA256;
@@ -58,9 +64,10 @@ Crypt::Digest::SHA256 - Hash function SHA-256 [size: 256 bits]
$d->add('any data');
$d->addfile('filename.dat');
$d->addfile(*FILEHANDLE);
- $result_raw = $d->digest; # raw bytes
- $result_hex = $d->hexdigest; # hexadecimal form
- $result_b64 = $d->b64digest; # Base64 form
+ $result_raw = $d->digest; # raw bytes
+ $result_hex = $d->hexdigest; # hexadecimal form
+ $result_b64 = $d->b64digest; # Base64 form
+ $result_b64u = $d->b64udigest; # Base64 URL Safe form
=head1 DESCRIPTION
@@ -72,7 +79,8 @@ Nothing is exported by default.
You can export selected functions:
- use Crypt::Digest::SHA256 qw(sha256 sha256_hex sha256_b64 sha256_file sha256_file_hex sha256_file_b64);
+ use Crypt::Digest::SHA256 qw(sha256 sha256_hex sha256_b64 sha256_b64u
+ sha256_file sha256_file_hex sha256_file_b64 sha256_file_b64u);
Or all of them at once:
@@ -104,6 +112,14 @@ Logically joins all arguments into a single string, and returns its SHA256 diges
#or
$sha256_b64 = sha256_b64('any data', 'more data', 'even more data');
+=head2 sha256_b64u
+
+Logically joins all arguments into a single string, and returns its SHA256 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5).
+
+ $sha256_b64url = sha256_b64u('data string');
+ #or
+ $sha256_b64url = sha256_b64u('any data', 'more data', 'even more data');
+
=head2 sha256_file
Reads file (defined by filename or filehandle) content, and returns its SHA256 digest encoded as a binary string.
@@ -130,6 +146,14 @@ Reads file (defined by filename or filehandle) content, and returns its SHA256 d
#or
$sha256_b64 = sha256_file_b64(*FILEHANDLE);
+=head2 sha256_file_b64u
+
+Reads file (defined by filename or filehandle) content, and returns its SHA256 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5).
+
+ $sha256_b64url = sha256_file_b64u('filename.dat');
+ #or
+ $sha256_b64url = sha256_file_b64u(*FILEHANDLE);
+
=head1 METHODS
The OO interface provides the same set of functions as L<Crypt::Digest>.
@@ -184,6 +208,10 @@ The OO interface provides the same set of functions as L<Crypt::Digest>.
$result_b64 = $d->b64digest();
+=head2 b64udigest
+
+ $result_b64url = $d->b64udigest();
+
=head1 SEE ALSO
=over 4
diff --git a/lib/Crypt/Digest/SHA384.pm b/lib/Crypt/Digest/SHA384.pm
index 32e77138..9a3fac0a 100644
--- a/lib/Crypt/Digest/SHA384.pm
+++ b/lib/Crypt/Digest/SHA384.pm
@@ -6,7 +6,7 @@ use strict;
use warnings;
use Exporter 'import';
-our %EXPORT_TAGS = ( all => [qw( sha384 sha384_hex sha384_b64 sha384_file sha384_file_hex sha384_file_b64 )] );
+our %EXPORT_TAGS = ( all => [qw( sha384 sha384_hex sha384_b64 sha384_b64u sha384_file sha384_file_hex sha384_file_b64 sha384_file_b64u )] );
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
our @EXPORT = qw();
@@ -20,10 +20,12 @@ sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) }
sub sha384 { Crypt::Digest::digest_data(__PACKAGE__, @_) }
sub sha384_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) }
sub sha384_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) }
+sub sha384_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) }
sub sha384_file { Crypt::Digest::digest_file(__PACKAGE__, @_) }
sub sha384_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) }
sub sha384_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) }
+sub sha384_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) }
1;
@@ -36,20 +38,24 @@ Crypt::Digest::SHA384 - Hash function SHA-384 [size: 384 bits]
=head1 SYNOPSIS
### Functional interface:
- use Crypt::Digest::SHA384 qw( sha384 sha384_hex sha384_b64 sha384_file sha384_file_hex sha384_file_b64 );
+ use Crypt::Digest::SHA384 qw( sha384 sha384_hex sha384_b64 sha384_b64u
+ sha384_file sha384_file_hex sha384_file_b64 sha384_file_b64u );
# calculate digest from string/buffer
- $sha384_raw = sha384('data string');
- $sha384_hex = sha384_hex('data string');
- $sha384_b64 = sha384_b64('data string');
+ $sha384_raw = sha384('data string');
+ $sha384_hex = sha384_hex('data string');
+ $sha384_b64 = sha384_b64('data string');
+ $sha384_b64u = sha384_b64u('data string');
# calculate digest from file
- $sha384_raw = sha384_file('filename.dat');
- $sha384_hex = sha384_file_hex('filename.dat');
- $sha384_b64 = sha384_file_b64('filename.dat');
+ $sha384_raw = sha384_file('filename.dat');
+ $sha384_hex = sha384_file_hex('filename.dat');
+ $sha384_b64 = sha384_file_b64('filename.dat');
+ $sha384_b64u = sha384_file_b64u('filename.dat');
# calculate digest from filehandle
- $sha384_raw = sha384_file(*FILEHANDLE);
- $sha384_hex = sha384_file_hex(*FILEHANDLE);
- $sha384_b64 = sha384_file_b64(*FILEHANDLE);
+ $sha384_raw = sha384_file(*FILEHANDLE);
+ $sha384_hex = sha384_file_hex(*FILEHANDLE);
+ $sha384_b64 = sha384_file_b64(*FILEHANDLE);
+ $sha384_b64u = sha384_file_b64u(*FILEHANDLE);
### OO interface:
use Crypt::Digest::SHA384;
@@ -58,9 +64,10 @@ Crypt::Digest::SHA384 - Hash function SHA-384 [size: 384 bits]
$d->add('any data');
$d->addfile('filename.dat');
$d->addfile(*FILEHANDLE);
- $result_raw = $d->digest; # raw bytes
- $result_hex = $d->hexdigest; # hexadecimal form
- $result_b64 = $d->b64digest; # Base64 form
+ $result_raw = $d->digest; # raw bytes
+ $result_hex = $d->hexdigest; # hexadecimal form
+ $result_b64 = $d->b64digest; # Base64 form
+ $result_b64u = $d->b64udigest; # Base64 URL Safe form
=head1 DESCRIPTION
@@ -72,7 +79,8 @@ Nothing is exported by default.
You can export selected functions:
- use Crypt::Digest::SHA384 qw(sha384 sha384_hex sha384_b64 sha384_file sha384_file_hex sha384_file_b64);
+ use Crypt::Digest::SHA384 qw(sha384 sha384_hex sha384_b64 sha384_b64u
+ sha384_file sha384_file_hex sha384_file_b64 sha384_file_b64u);
Or all of them at once:
@@ -104,6 +112,14 @@ Logically joins all arguments into a single string, and returns its SHA384 diges
#or
$sha384_b64 = sha384_b64('any data', 'more data', 'even more data');
+=head2 sha384_b64u
+
+Logically joins all arguments into a single string, and returns its SHA384 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5).
+
+ $sha384_b64url = sha384_b64u('data string');
+ #or
+ $sha384_b64url = sha384_b64u('any data', 'more data', 'even more data');
+
=head2 sha384_file
Reads file (defined by filename or filehandle) content, and returns its SHA384 digest encoded as a binary string.
@@ -130,6 +146,14 @@ Reads file (defined by filename or filehandle) content, and returns its SHA384 d
#or
$sha384_b64 = sha384_file_b64(*FILEHANDLE);
+=head2 sha384_file_b64u
+
+Reads file (defined by filename or filehandle) content, and returns its SHA384 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5).
+
+ $sha384_b64url = sha384_file_b64u('filename.dat');
+ #or
+ $sha384_b64url = sha384_file_b64u(*FILEHANDLE);
+
=head1 METHODS
The OO interface provides the same set of functions as L<Crypt::Digest>.
@@ -184,6 +208,10 @@ The OO interface provides the same set of functions as L<Crypt::Digest>.
$result_b64 = $d->b64digest();
+=head2 b64udigest
+
+ $result_b64url = $d->b64udigest();
+
=head1 SEE ALSO
=over 4
diff --git a/lib/Crypt/Digest/SHA512.pm b/lib/Crypt/Digest/SHA512.pm
index 546abafb..5453ddc0 100644
--- a/lib/Crypt/Digest/SHA512.pm
+++ b/lib/Crypt/Digest/SHA512.pm
@@ -6,7 +6,7 @@ use strict;
use warnings;
use Exporter 'import';
-our %EXPORT_TAGS = ( all => [qw( sha512 sha512_hex sha512_b64 sha512_file sha512_file_hex sha512_file_b64 )] );
+our %EXPORT_TAGS = ( all => [qw( sha512 sha512_hex sha512_b64 sha512_b64u sha512_file sha512_file_hex sha512_file_b64 sha512_file_b64u )] );
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
our @EXPORT = qw();
@@ -20,10 +20,12 @@ sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) }
sub sha512 { Crypt::Digest::digest_data(__PACKAGE__, @_) }
sub sha512_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) }
sub sha512_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) }
+sub sha512_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) }
sub sha512_file { Crypt::Digest::digest_file(__PACKAGE__, @_) }
sub sha512_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) }
sub sha512_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) }
+sub sha512_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) }
1;
@@ -36,20 +38,24 @@ Crypt::Digest::SHA512 - Hash function SHA-512 [size: 512 bits]
=head1 SYNOPSIS
### Functional interface:
- use Crypt::Digest::SHA512 qw( sha512 sha512_hex sha512_b64 sha512_file sha512_file_hex sha512_file_b64 );
+ use Crypt::Digest::SHA512 qw( sha512 sha512_hex sha512_b64 sha512_b64u
+ sha512_file sha512_file_hex sha512_file_b64 sha512_file_b64u );
# calculate digest from string/buffer
- $sha512_raw = sha512('data string');
- $sha512_hex = sha512_hex('data string');
- $sha512_b64 = sha512_b64('data string');
+ $sha512_raw = sha512('data string');
+ $sha512_hex = sha512_hex('data string');
+ $sha512_b64 = sha512_b64('data string');
+ $sha512_b64u = sha512_b64u('data string');
# calculate digest from file
- $sha512_raw = sha512_file('filename.dat');
- $sha512_hex = sha512_file_hex('filename.dat');
- $sha512_b64 = sha512_file_b64('filename.dat');
+ $sha512_raw = sha512_file('filename.dat');
+ $sha512_hex = sha512_file_hex('filename.dat');
+ $sha512_b64 = sha512_file_b64('filename.dat');
+ $sha512_b64u = sha512_file_b64u('filename.dat');
# calculate digest from filehandle
- $sha512_raw = sha512_file(*FILEHANDLE);
- $sha512_hex = sha512_file_hex(*FILEHANDLE);
- $sha512_b64 = sha512_file_b64(*FILEHANDLE);
+ $sha512_raw = sha512_file(*FILEHANDLE);
+ $sha512_hex = sha512_file_hex(*FILEHANDLE);
+ $sha512_b64 = sha512_file_b64(*FILEHANDLE);
+ $sha512_b64u = sha512_file_b64u(*FILEHANDLE);
### OO interface:
use Crypt::Digest::SHA512;
@@ -58,9 +64,10 @@ Crypt::Digest::SHA512 - Hash function SHA-512 [size: 512 bits]
$d->add('any data');
$d->addfile('filename.dat');
$d->addfile(*FILEHANDLE);
- $result_raw = $d->digest; # raw bytes
- $result_hex = $d->hexdigest; # hexadecimal form
- $result_b64 = $d->b64digest; # Base64 form
+ $result_raw = $d->digest; # raw bytes
+ $result_hex = $d->hexdigest; # hexadecimal form
+ $result_b64 = $d->b64digest; # Base64 form
+ $result_b64u = $d->b64udigest; # Base64 URL Safe form
=head1 DESCRIPTION
@@ -72,7 +79,8 @@ Nothing is exported by default.
You can export selected functions:
- use Crypt::Digest::SHA512 qw(sha512 sha512_hex sha512_b64 sha512_file sha512_file_hex sha512_file_b64);
+ use Crypt::Digest::SHA512 qw(sha512 sha512_hex sha512_b64 sha512_b64u
+ sha512_file sha512_file_hex sha512_file_b64 sha512_file_b64u);
Or all of them at once:
@@ -104,6 +112,14 @@ Logically joins all arguments into a single string, and returns its SHA512 diges
#or
$sha512_b64 = sha512_b64('any data', 'more data', 'even more data');
+=head2 sha512_b64u
+
+Logically joins all arguments into a single string, and returns its SHA512 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5).
+
+ $sha512_b64url = sha512_b64u('data string');
+ #or
+ $sha512_b64url = sha512_b64u('any data', 'more data', 'even more data');
+
=head2 sha512_file
Reads file (defined by filename or filehandle) content, and returns its SHA512 digest encoded as a binary string.
@@ -130,6 +146,14 @@ Reads file (defined by filename or filehandle) content, and returns its SHA512 d
#or
$sha512_b64 = sha512_file_b64(*FILEHANDLE);
+=head2 sha512_file_b64u
+
+Reads file (defined by filename or filehandle) content, and returns its SHA512 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5).
+
+ $sha512_b64url = sha512_file_b64u('filename.dat');
+ #or
+ $sha512_b64url = sha512_file_b64u(*FILEHANDLE);
+
=head1 METHODS
The OO interface provides the same set of functions as L<Crypt::Digest>.
@@ -184,6 +208,10 @@ The OO interface provides the same set of functions as L<Crypt::Digest>.
$result_b64 = $d->b64digest();
+=head2 b64udigest
+
+ $result_b64url = $d->b64udigest();
+
=head1 SEE ALSO
=over 4
diff --git a/lib/Crypt/Digest/Tiger192.pm b/lib/Crypt/Digest/Tiger192.pm
index 9df8da4d..09f25b02 100644
--- a/lib/Crypt/Digest/Tiger192.pm
+++ b/lib/Crypt/Digest/Tiger192.pm
@@ -6,7 +6,7 @@ use strict;
use warnings;
use Exporter 'import';
-our %EXPORT_TAGS = ( all => [qw( tiger192 tiger192_hex tiger192_b64 tiger192_file tiger192_file_hex tiger192_file_b64 )] );
+our %EXPORT_TAGS = ( all => [qw( tiger192 tiger192_hex tiger192_b64 tiger192_b64u tiger192_file tiger192_file_hex tiger192_file_b64 tiger192_file_b64u )] );
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
our @EXPORT = qw();
@@ -20,10 +20,12 @@ sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) }
sub tiger192 { Crypt::Digest::digest_data(__PACKAGE__, @_) }
sub tiger192_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) }
sub tiger192_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) }
+sub tiger192_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) }
sub tiger192_file { Crypt::Digest::digest_file(__PACKAGE__, @_) }
sub tiger192_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) }
sub tiger192_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) }
+sub tiger192_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) }
1;
@@ -36,20 +38,24 @@ Crypt::Digest::Tiger192 - Hash function Tiger-192 [size: 192 bits]
=head1 SYNOPSIS
### Functional interface:
- use Crypt::Digest::Tiger192 qw( tiger192 tiger192_hex tiger192_b64 tiger192_file tiger192_file_hex tiger192_file_b64 );
+ use Crypt::Digest::Tiger192 qw( tiger192 tiger192_hex tiger192_b64 tiger192_b64u
+ tiger192_file tiger192_file_hex tiger192_file_b64 tiger192_file_b64u );
# calculate digest from string/buffer
- $tiger192_raw = tiger192('data string');
- $tiger192_hex = tiger192_hex('data string');
- $tiger192_b64 = tiger192_b64('data string');
+ $tiger192_raw = tiger192('data string');
+ $tiger192_hex = tiger192_hex('data string');
+ $tiger192_b64 = tiger192_b64('data string');
+ $tiger192_b64u = tiger192_b64u('data string');
# calculate digest from file
- $tiger192_raw = tiger192_file('filename.dat');
- $tiger192_hex = tiger192_file_hex('filename.dat');
- $tiger192_b64 = tiger192_file_b64('filename.dat');
+ $tiger192_raw = tiger192_file('filename.dat');
+ $tiger192_hex = tiger192_file_hex('filename.dat');
+ $tiger192_b64 = tiger192_file_b64('filename.dat');
+ $tiger192_b64u = tiger192_file_b64u('filename.dat');
# calculate digest from filehandle
- $tiger192_raw = tiger192_file(*FILEHANDLE);
- $tiger192_hex = tiger192_file_hex(*FILEHANDLE);
- $tiger192_b64 = tiger192_file_b64(*FILEHANDLE);
+ $tiger192_raw = tiger192_file(*FILEHANDLE);
+ $tiger192_hex = tiger192_file_hex(*FILEHANDLE);
+ $tiger192_b64 = tiger192_file_b64(*FILEHANDLE);
+ $tiger192_b64u = tiger192_file_b64u(*FILEHANDLE);
### OO interface:
use Crypt::Digest::Tiger192;
@@ -58,9 +64,10 @@ Crypt::Digest::Tiger192 - Hash function Tiger-192 [size: 192 bits]
$d->add('any data');
$d->addfile('filename.dat');
$d->addfile(*FILEHANDLE);
- $result_raw = $d->digest; # raw bytes
- $result_hex = $d->hexdigest; # hexadecimal form
- $result_b64 = $d->b64digest; # Base64 form
+ $result_raw = $d->digest; # raw bytes
+ $result_hex = $d->hexdigest; # hexadecimal form
+ $result_b64 = $d->b64digest; # Base64 form
+ $result_b64u = $d->b64udigest; # Base64 URL Safe form
=head1 DESCRIPTION
@@ -72,7 +79,8 @@ Nothing is exported by default.
You can export selected functions:
- use Crypt::Digest::Tiger192 qw(tiger192 tiger192_hex tiger192_b64 tiger192_file tiger192_file_hex tiger192_file_b64);
+ use Crypt::Digest::Tiger192 qw(tiger192 tiger192_hex tiger192_b64 tiger192_b64u
+ tiger192_file tiger192_file_hex tiger192_file_b64 tiger192_file_b64u);
Or all of them at once:
@@ -104,6 +112,14 @@ Logically joins all arguments into a single string, and returns its Tiger192 dig
#or
$tiger192_b64 = tiger192_b64('any data', 'more data', 'even more data');
+=head2 tiger192_b64u
+
+Logically joins all arguments into a single string, and returns its Tiger192 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5).
+
+ $tiger192_b64url = tiger192_b64u('data string');
+ #or
+ $tiger192_b64url = tiger192_b64u('any data', 'more data', 'even more data');
+
=head2 tiger192_file
Reads file (defined by filename or filehandle) content, and returns its Tiger192 digest encoded as a binary string.
@@ -130,6 +146,14 @@ Reads file (defined by filename or filehandle) content, and returns its Tiger192
#or
$tiger192_b64 = tiger192_file_b64(*FILEHANDLE);
+=head2 tiger192_file_b64u
+
+Reads file (defined by filename or filehandle) content, and returns its Tiger192 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5).
+
+ $tiger192_b64url = tiger192_file_b64u('filename.dat');
+ #or
+ $tiger192_b64url = tiger192_file_b64u(*FILEHANDLE);
+
=head1 METHODS
The OO interface provides the same set of functions as L<Crypt::Digest>.
@@ -184,6 +208,10 @@ The OO interface provides the same set of functions as L<Crypt::Digest>.
$result_b64 = $d->b64digest();
+=head2 b64udigest
+
+ $result_b64url = $d->b64udigest();
+
=head1 SEE ALSO
=over 4
diff --git a/lib/Crypt/Digest/Whirlpool.pm b/lib/Crypt/Digest/Whirlpool.pm
index eaa29b02..720fd757 100644
--- a/lib/Crypt/Digest/Whirlpool.pm
+++ b/lib/Crypt/Digest/Whirlpool.pm
@@ -6,7 +6,7 @@ use strict;
use warnings;
use Exporter 'import';
-our %EXPORT_TAGS = ( all => [qw( whirlpool whirlpool_hex whirlpool_b64 whirlpool_file whirlpool_file_hex whirlpool_file_b64 )] );
+our %EXPORT_TAGS = ( all => [qw( whirlpool whirlpool_hex whirlpool_b64 whirlpool_b64u whirlpool_file whirlpool_file_hex whirlpool_file_b64 whirlpool_file_b64u )] );
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
our @EXPORT = qw();
@@ -20,10 +20,12 @@ sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) }
sub whirlpool { Crypt::Digest::digest_data(__PACKAGE__, @_) }
sub whirlpool_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) }
sub whirlpool_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) }
+sub whirlpool_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) }
sub whirlpool_file { Crypt::Digest::digest_file(__PACKAGE__, @_) }
sub whirlpool_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) }
sub whirlpool_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) }
+sub whirlpool_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) }
1;
@@ -36,20 +38,24 @@ Crypt::Digest::Whirlpool - Hash function Whirlpool [size: 512 bits]
=head1 SYNOPSIS
### Functional interface:
- use Crypt::Digest::Whirlpool qw( whirlpool whirlpool_hex whirlpool_b64 whirlpool_file whirlpool_file_hex whirlpool_file_b64 );
+ use Crypt::Digest::Whirlpool qw( whirlpool whirlpool_hex whirlpool_b64 whirlpool_b64u
+ whirlpool_file whirlpool_file_hex whirlpool_file_b64 whirlpool_file_b64u );
# calculate digest from string/buffer
- $whirlpool_raw = whirlpool('data string');
- $whirlpool_hex = whirlpool_hex('data string');
- $whirlpool_b64 = whirlpool_b64('data string');
+ $whirlpool_raw = whirlpool('data string');
+ $whirlpool_hex = whirlpool_hex('data string');
+ $whirlpool_b64 = whirlpool_b64('data string');
+ $whirlpool_b64u = whirlpool_b64u('data string');
# calculate digest from file
- $whirlpool_raw = whirlpool_file('filename.dat');
- $whirlpool_hex = whirlpool_file_hex('filename.dat');
- $whirlpool_b64 = whirlpool_file_b64('filename.dat');
+ $whirlpool_raw = whirlpool_file('filename.dat');
+ $whirlpool_hex = whirlpool_file_hex('filename.dat');
+ $whirlpool_b64 = whirlpool_file_b64('filename.dat');
+ $whirlpool_b64u = whirlpool_file_b64u('filename.dat');
# calculate digest from filehandle
- $whirlpool_raw = whirlpool_file(*FILEHANDLE);
- $whirlpool_hex = whirlpool_file_hex(*FILEHANDLE);
- $whirlpool_b64 = whirlpool_file_b64(*FILEHANDLE);
+ $whirlpool_raw = whirlpool_file(*FILEHANDLE);
+ $whirlpool_hex = whirlpool_file_hex(*FILEHANDLE);
+ $whirlpool_b64 = whirlpool_file_b64(*FILEHANDLE);
+ $whirlpool_b64u = whirlpool_file_b64u(*FILEHANDLE);
### OO interface:
use Crypt::Digest::Whirlpool;
@@ -58,9 +64,10 @@ Crypt::Digest::Whirlpool - Hash function Whirlpool [size: 512 bits]
$d->add('any data');
$d->addfile('filename.dat');
$d->addfile(*FILEHANDLE);
- $result_raw = $d->digest; # raw bytes
- $result_hex = $d->hexdigest; # hexadecimal form
- $result_b64 = $d->b64digest; # Base64 form
+ $result_raw = $d->digest; # raw bytes
+ $result_hex = $d->hexdigest; # hexadecimal form
+ $result_b64 = $d->b64digest; # Base64 form
+ $result_b64u = $d->b64udigest; # Base64 URL Safe form
=head1 DESCRIPTION
@@ -72,7 +79,8 @@ Nothing is exported by default.
You can export selected functions:
- use Crypt::Digest::Whirlpool qw(whirlpool whirlpool_hex whirlpool_b64 whirlpool_file whirlpool_file_hex whirlpool_file_b64);
+ use Crypt::Digest::Whirlpool qw(whirlpool whirlpool_hex whirlpool_b64 whirlpool_b64u
+ whirlpool_file whirlpool_file_hex whirlpool_file_b64 whirlpool_file_b64u);
Or all of them at once:
@@ -104,6 +112,14 @@ Logically joins all arguments into a single string, and returns its Whirlpool di
#or
$whirlpool_b64 = whirlpool_b64('any data', 'more data', 'even more data');
+=head2 whirlpool_b64u
+
+Logically joins all arguments into a single string, and returns its Whirlpool digest encoded as a Base64 URL Safe string (see RFC 4648 section 5).
+
+ $whirlpool_b64url = whirlpool_b64u('data string');
+ #or
+ $whirlpool_b64url = whirlpool_b64u('any data', 'more data', 'even more data');
+
=head2 whirlpool_file
Reads file (defined by filename or filehandle) content, and returns its Whirlpool digest encoded as a binary string.
@@ -130,6 +146,14 @@ Reads file (defined by filename or filehandle) content, and returns its Whirlpoo
#or
$whirlpool_b64 = whirlpool_file_b64(*FILEHANDLE);
+=head2 whirlpool_file_b64u
+
+Reads file (defined by filename or filehandle) content, and returns its Whirlpool digest encoded as a Base64 URL Safe string (see RFC 4648 section 5).
+
+ $whirlpool_b64url = whirlpool_file_b64u('filename.dat');
+ #or
+ $whirlpool_b64url = whirlpool_file_b64u(*FILEHANDLE);
+
=head1 METHODS
The OO interface provides the same set of functions as L<Crypt::Digest>.
@@ -184,6 +208,10 @@ The OO interface provides the same set of functions as L<Crypt::Digest>.
$result_b64 = $d->b64digest();
+=head2 b64udigest
+
+ $result_b64url = $d->b64udigest();
+
=head1 SEE ALSO
=over 4
diff --git a/lib/Crypt/Mac/F9.pm b/lib/Crypt/Mac/F9.pm
index c2e4cad9..6faef77e 100644
--- a/lib/Crypt/Mac/F9.pm
+++ b/lib/Crypt/Mac/F9.pm
@@ -6,7 +6,7 @@ use strict;
use warnings;
use Exporter 'import';
-our %EXPORT_TAGS = ( all => [qw( f9 f9_hex f9_b64 )] );
+our %EXPORT_TAGS = ( all => [qw( f9 f9_hex f9_b64 f9_b64u )] );
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
our @EXPORT = qw();
@@ -17,8 +17,9 @@ use Crypt::Cipher;
sub new { my $class = shift; _new(Crypt::Cipher::_trans_cipher_name(shift), @_) }
sub f9 { Crypt::Mac::F9->new(shift, shift)->add(@_)->mac }
-sub f9_hex { Crypt::Mac::F9->new(shift, shift)->add(@_)->hexmac }
-sub f9_b64 { Crypt::Mac::F9->new(shift, shift)->add(@_)->b64mac }
+sub f9_hex { Crypt::Mac::F9->new(shift, shift)->add(@_)->hexmac }
+sub f9_b64 { Crypt::Mac::F9->new(shift, shift)->add(@_)->b64mac }
+sub f9_b64u { Crypt::Mac::F9->new(shift, shift)->add(@_)->b64umac }
1;
@@ -34,9 +35,10 @@ Crypt::Mac::F9 - Message authentication code F9
use Crypt::Mac::F9 qw( f9 f9_hex );
# calculate MAC from string/buffer
- $f9_raw = f9($cipher_name, $key, 'data buffer');
- $f9_hex = f9_hex($cipher_name, $key, 'data buffer');
- $f9_b64 = f9_b64($cipher_name, $key, 'data buffer');
+ $f9_raw = f9($cipher_name, $key, 'data buffer');
+ $f9_hex = f9_hex($cipher_name, $key, 'data buffer');
+ $f9_b64 = f9_b64($cipher_name, $key, 'data buffer');
+ $f9_b64u = f9_b64u($cipher_name, $key, 'data buffer');
### OO interface:
use Crypt::Mac::F9;
@@ -45,9 +47,10 @@ Crypt::Mac::F9 - Message authentication code F9
$d->add('any data');
$d->addfile('filename.dat');
$d->addfile(*FILEHANDLE);
- $result_raw = $d->mac; # raw bytes
- $result_hex = $d->hexmac; # hexadecimal form
- $result_b64 = $d->b64mac; # Base64 form
+ $result_raw = $d->mac; # raw bytes
+ $result_hex = $d->hexmac; # hexadecimal form
+ $result_b64 = $d->b64mac; # Base64 form
+ $result_b64u = $d->b64umac; # Base64 URL Safe form
=head1 DESCRIPTION
@@ -85,15 +88,21 @@ Logically joins all arguments into a single string, and returns its F9 message a
=head2 f9_b64
-Logically joins all arguments into a single string, and returns its F9 message authentication code encoded as a BASE64 string.
+Logically joins all arguments into a single string, and returns its F9 message authentication code encoded as a Base64 string.
$f9_b64 = f9_b64($cipher_name, $key, 'data buffer');
#or
$f9_b64 = f9_b64($cipher_name, $key, 'any data', 'more data', 'even more data');
-=head1 METHODS
+=head2 f9_b64u
+
+Logically joins all arguments into a single string, and returns its F9 message authentication code encoded as a Base64 URL Safe string (see RFC 4648 section 5).
-The OO interface provides the same set of functions as L<Crypt::Mac>.
+ $f9_b64url = f9_b64u($cipher_name, $key, 'data buffer');
+ #or
+ $f9_b64url = f9_b64u($cipher_name, $key, 'any data', 'more data', 'even more data');
+
+=head1 METHODS
=head2 new
@@ -131,6 +140,10 @@ The OO interface provides the same set of functions as L<Crypt::Mac>.
$result_b64 = $d->b64mac();
+=head2 b64umac
+
+ $result_b64url = $d->b64umac();
+
=head1 SEE ALSO
=over 4
diff --git a/lib/Crypt/Mac/HMAC.pm b/lib/Crypt/Mac/HMAC.pm
index 460155a0..15ffa0f9 100644
--- a/lib/Crypt/Mac/HMAC.pm
+++ b/lib/Crypt/Mac/HMAC.pm
@@ -6,7 +6,7 @@ use strict;
use warnings;
use Exporter 'import';
-our %EXPORT_TAGS = ( all => [qw( hmac hmac_hex hmac_b64 )] );
+our %EXPORT_TAGS = ( all => [qw( hmac hmac_hex hmac_b64 hmac_b64u )] );
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
our @EXPORT = qw();
@@ -17,8 +17,9 @@ use Crypt::Digest;
sub new { my $class = shift; _new(Crypt::Digest::_trans_digest_name(shift), @_) }
sub hmac { Crypt::Mac::HMAC->new(shift, shift)->add(@_)->mac }
-sub hmac_hex { Crypt::Mac::HMAC->new(shift, shift)->add(@_)->hexmac }
-sub hmac_b64 { Crypt::Mac::HMAC->new(shift, shift)->add(@_)->b64mac }
+sub hmac_hex { Crypt::Mac::HMAC->new(shift, shift)->add(@_)->hexmac }
+sub hmac_b64 { Crypt::Mac::HMAC->new(shift, shift)->add(@_)->b64mac }
+sub hmac_b64u { Crypt::Mac::HMAC->new(shift, shift)->add(@_)->b64umac }
1;
@@ -34,9 +35,10 @@ Crypt::Mac::HMAC - Message authentication code HMAC
use Crypt::Mac::HMAC qw( hmac hmac_hex );
# calculate MAC from string/buffer
- $hmac_raw = hmac('SHA256', $key, 'data buffer');
- $hmac_hex = hmac_hex('SHA256', $key, 'data buffer');
- $hmac_b64 = hmac_b64('SHA256', $key, 'data buffer');
+ $hmac_raw = hmac('SHA256', $key, 'data buffer');
+ $hmac_hex = hmac_hex('SHA256', $key, 'data buffer');
+ $hmac_b64 = hmac_b64('SHA256', $key, 'data buffer');
+ $hmac_b64u = hmac_b64u('SHA256', $key, 'data buffer');
### OO interface:
use Crypt::Mac::HMAC;
@@ -45,9 +47,10 @@ Crypt::Mac::HMAC - Message authentication code HMAC
$d->add('any data');
$d->addfile('filename.dat');
$d->addfile(*FILEHANDLE);
- $result_raw = $d->mac; # raw bytes
- $result_hex = $d->hexmac; # hexadecimal form
- $result_b64 = $d->b64mac; # Base64 form
+ $result_raw = $d->mac; # raw bytes
+ $result_hex = $d->hexmac; # hexadecimal form
+ $result_b64 = $d->b64mac; # Base64 form
+ $result_b64u = $d->b64umac; # Base64 URL Safe form
=head1 DESCRIPTION
@@ -85,15 +88,21 @@ Logically joins all arguments into a single string, and returns its HMAC message
=head2 hmac_b64
-Logically joins all arguments into a single string, and returns its HMAC message authentication code encoded as a BASE64 string.
+Logically joins all arguments into a single string, and returns its HMAC message authentication code encoded as a Base64 string.
$hmac_b64 = hmac_b64($hash_name, $key, 'data buffer');
#or
$hmac_b64 = hmac_b64($hash_name, $key, 'any data', 'more data', 'even more data');
-=head1 METHODS
+=head2 hmac_b64u
+
+Logically joins all arguments into a single string, and returns its HMAC message authentication code encoded as a Base64 URL Safe string (see RFC 4648 section 5).
-The OO interface provides the same set of functions as L<Crypt::Mac>.
+ $hmac_b64url = hmac_b64u($hash_name, $key, 'data buffer');
+ #or
+ $hmac_b64url = hmac_b64u($hash_name, $key, 'any data', 'more data', 'even more data');
+
+=head1 METHODS
=head2 new
@@ -131,6 +140,10 @@ The OO interface provides the same set of functions as L<Crypt::Mac>.
$result_b64 = $d->b64mac();
+=head2 b64umac
+
+ $result_b64url = $d->b64umac();
+
=head1 SEE ALSO
=over 4
diff --git a/lib/Crypt/Mac/OMAC.pm b/lib/Crypt/Mac/OMAC.pm
index c9a48802..47027b7c 100644
--- a/lib/Crypt/Mac/OMAC.pm
+++ b/lib/Crypt/Mac/OMAC.pm
@@ -6,7 +6,7 @@ use strict;
use warnings;
use Exporter 'import';
-our %EXPORT_TAGS = ( all => [qw( omac omac_hex omac_b64 )] );
+our %EXPORT_TAGS = ( all => [qw( omac omac_hex omac_b64 omac_b64u )] );
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
our @EXPORT = qw();
@@ -17,8 +17,9 @@ use Crypt::Cipher;
sub new { my $class = shift; _new(Crypt::Cipher::_trans_cipher_name(shift), @_) }
sub omac { Crypt::Mac::OMAC->new(shift, shift)->add(@_)->mac }
-sub omac_hex { Crypt::Mac::OMAC->new(shift, shift)->add(@_)->hexmac }
-sub omac_b64 { Crypt::Mac::OMAC->new(shift, shift)->add(@_)->b64mac }
+sub omac_hex { Crypt::Mac::OMAC->new(shift, shift)->add(@_)->hexmac }
+sub omac_b64 { Crypt::Mac::OMAC->new(shift, shift)->add(@_)->b64mac }
+sub omac_b64u { Crypt::Mac::OMAC->new(shift, shift)->add(@_)->b64umac }
1;
@@ -34,9 +35,10 @@ Crypt::Mac::OMAC - Message authentication code OMAC
use Crypt::Mac::OMAC qw( omac omac_hex );
# calculate MAC from string/buffer
- $omac_raw = omac($cipher_name, $key, 'data buffer');
- $omac_hex = omac_hex($cipher_name, $key, 'data buffer');
- $omac_b64 = omac_b64($cipher_name, $key, 'data buffer');
+ $omac_raw = omac($cipher_name, $key, 'data buffer');
+ $omac_hex = omac_hex($cipher_name, $key, 'data buffer');
+ $omac_b64 = omac_b64($cipher_name, $key, 'data buffer');
+ $omac_b64u = omac_b64u($cipher_name, $key, 'data buffer');
### OO interface:
use Crypt::Mac::OMAC;
@@ -45,9 +47,10 @@ Crypt::Mac::OMAC - Message authentication code OMAC
$d->add('any data');
$d->addfile('filename.dat');
$d->addfile(*FILEHANDLE);
- $result_raw = $d->mac; # raw bytes
- $result_hex = $d->hexmac; # hexadecimal form
- $result_b64 = $d->b64mac; # Base64 form
+ $result_raw = $d->mac; # raw bytes
+ $result_hex = $d->hexmac; # hexadecimal form
+ $result_b64 = $d->b64mac; # Base64 form
+ $result_b64u = $d->b64umac; # Base64 URL Safe form
=head1 DESCRIPTION
@@ -85,15 +88,21 @@ Logically joins all arguments into a single string, and returns its OMAC message
=head2 omac_b64
-Logically joins all arguments into a single string, and returns its OMAC message authentication code encoded as a BASE64 string.
+Logically joins all arguments into a single string, and returns its OMAC message authentication code encoded as a Base64 string.
$omac_b64 = omac_b64($cipher_name, $key, 'data buffer');
#or
$omac_b64 = omac_b64($cipher_name, $key, 'any data', 'more data', 'even more data');
-=head1 METHODS
+=head2 omac_b64u
+
+Logically joins all arguments into a single string, and returns its OMAC message authentication code encoded as a Base64 URL Safe string (see RFC 4648 section 5).
-The OO interface provides the same set of functions as L<Crypt::Mac>.
+ $omac_b64url = omac_b64u($cipher_name, $key, 'data buffer');
+ #or
+ $omac_b64url = omac_b64u($cipher_name, $key, 'any data', 'more data', 'even more data');
+
+=head1 METHODS
=head2 new
@@ -131,6 +140,10 @@ The OO interface provides the same set of functions as L<Crypt::Mac>.
$result_b64 = $d->b64mac();
+=head2 b64umac
+
+ $result_b64url = $d->b64umac();
+
=head1 SEE ALSO
=over 4
diff --git a/lib/Crypt/Mac/PMAC.pm b/lib/Crypt/Mac/PMAC.pm
index 90993c93..8e61481b 100644
--- a/lib/Crypt/Mac/PMAC.pm
+++ b/lib/Crypt/Mac/PMAC.pm
@@ -6,7 +6,7 @@ use strict;
use warnings;
use Exporter 'import';
-our %EXPORT_TAGS = ( all => [qw( pmac pmac_hex pmac_b64 )] );
+our %EXPORT_TAGS = ( all => [qw( pmac pmac_hex pmac_b64 pmac_b64u )] );
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
our @EXPORT = qw();
@@ -17,8 +17,9 @@ use Crypt::Cipher;
sub new { my $class = shift; _new(Crypt::Cipher::_trans_cipher_name(shift), @_) }
sub pmac { Crypt::Mac::PMAC->new(shift, shift)->add(@_)->mac }
-sub pmac_hex { Crypt::Mac::PMAC->new(shift, shift)->add(@_)->hexmac }
-sub pmac_b64 { Crypt::Mac::PMAC->new(shift, shift)->add(@_)->b64mac }
+sub pmac_hex { Crypt::Mac::PMAC->new(shift, shift)->add(@_)->hexmac }
+sub pmac_b64 { Crypt::Mac::PMAC->new(shift, shift)->add(@_)->b64mac }
+sub pmac_b64u { Crypt::Mac::PMAC->new(shift, shift)->add(@_)->b64umac }
1;
@@ -34,9 +35,10 @@ Crypt::Mac::PMAC - Message authentication code PMAC
use Crypt::Mac::PMAC qw( pmac pmac_hex );
# calculate MAC from string/buffer
- $pmac_raw = pmac($cipher_name, $key, 'data buffer');
- $pmac_hex = pmac_hex($cipher_name, $key, 'data buffer');
- $pmac_b64 = pmac_b64($cipher_name, $key, 'data buffer');
+ $pmac_raw = pmac($cipher_name, $key, 'data buffer');
+ $pmac_hex = pmac_hex($cipher_name, $key, 'data buffer');
+ $pmac_b64 = pmac_b64($cipher_name, $key, 'data buffer');
+ $pmac_b64u = pmac_b64u($cipher_name, $key, 'data buffer');
### OO interface:
use Crypt::Mac::PMAC;
@@ -45,9 +47,10 @@ Crypt::Mac::PMAC - Message authentication code PMAC
$d->add('any data');
$d->addfile('filename.dat');
$d->addfile(*FILEHANDLE);
- $result_raw = $d->mac; # raw bytes
- $result_hex = $d->hexmac; # hexadecimal form
- $result_b64 = $d->b64mac; # Base64 form
+ $result_raw = $d->mac; # raw bytes
+ $result_hex = $d->hexmac; # hexadecimal form
+ $result_b64 = $d->b64mac; # Base64 form
+ $result_b64u = $d->b64umac; # Base64 URL Safe form
=head1 DESCRIPTION
@@ -85,15 +88,21 @@ Logically joins all arguments into a single string, and returns its PMAC message
=head2 pmac_b64
-Logically joins all arguments into a single string, and returns its PMAC message authentication code encoded as a BASE64 string.
+Logically joins all arguments into a single string, and returns its PMAC message authentication code encoded as a Base64 string.
$pmac_b64 = pmac_b64($cipher_name, $key, 'data buffer');
#or
$pmac_b64 = pmac_b64($cipher_name, $key, 'any data', 'more data', 'even more data');
-=head1 METHODS
+=head2 pmac_b64u
+
+Logically joins all arguments into a single string, and returns its PMAC message authentication code encoded as a Base64 URL Safe string (see RFC 4648 section 5).
-The OO interface provides the same set of functions as L<Crypt::Mac>.
+ $pmac_b64url = pmac_b64u($cipher_name, $key, 'data buffer');
+ #or
+ $pmac_b64url = pmac_b64u($cipher_name, $key, 'any data', 'more data', 'even more data');
+
+=head1 METHODS
=head2 new
@@ -131,6 +140,10 @@ The OO interface provides the same set of functions as L<Crypt::Mac>.
$result_b64 = $d->b64mac();
+=head2 b64umac
+
+ $result_b64url = $d->b64umac();
+
=head1 SEE ALSO
=over 4
diff --git a/lib/Crypt/Mac/Pelican.pm b/lib/Crypt/Mac/Pelican.pm
index 133671c9..95fc2fc2 100644
--- a/lib/Crypt/Mac/Pelican.pm
+++ b/lib/Crypt/Mac/Pelican.pm
@@ -6,7 +6,7 @@ use strict;
use warnings;
use Exporter 'import';
-our %EXPORT_TAGS = ( all => [qw( pelican pelican_hex pelican_b64 )] );
+our %EXPORT_TAGS = ( all => [qw( pelican pelican_hex pelican_b64 pelican_b64u )] );
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
our @EXPORT = qw();
@@ -15,8 +15,9 @@ use base 'Crypt::Mac';
sub new { my $class = shift; _new(@_) }
sub pelican { Crypt::Mac::Pelican->new(shift)->add(@_)->mac }
-sub pelican_hex { Crypt::Mac::Pelican->new(shift)->add(@_)->hexmac }
-sub pelican_b64 { Crypt::Mac::Pelican->new(shift)->add(@_)->b64mac }
+sub pelican_hex { Crypt::Mac::Pelican->new(shift)->add(@_)->hexmac }
+sub pelican_b64 { Crypt::Mac::Pelican->new(shift)->add(@_)->b64mac }
+sub pelican_b64u { Crypt::Mac::Pelican->new(shift)->add(@_)->b64umac }
1;
@@ -32,9 +33,10 @@ Crypt::Mac::Pelican - Message authentication code Pelican (AES based MAC)
use Crypt::Mac::Pelican qw( pelican pelican_hex );
# calculate MAC from string/buffer
- $pelican_raw = pelican($key, 'data buffer');
- $pelican_hex = pelican_hex($key, 'data buffer');
- $pelican_b64 = pelican_b64($key, 'data buffer');
+ $pelican_raw = pelican($key, 'data buffer');
+ $pelican_hex = pelican_hex($key, 'data buffer');
+ $pelican_b64 = pelican_b64($key, 'data buffer');
+ $pelican_b64u = pelican_b64u($key, 'data buffer');
### OO interface:
use Crypt::Mac::Pelican;
@@ -43,9 +45,10 @@ Crypt::Mac::Pelican - Message authentication code Pelican (AES based MAC)
$d->add('any data');
$d->addfile('filename.dat');
$d->addfile(*FILEHANDLE);
- $result_raw = $d->mac; # raw bytes
- $result_hex = $d->hexmac; # hexadecimal form
- $result_b64 = $d->b64mac; # Base64 form
+ $result_raw = $d->mac; # raw bytes
+ $result_hex = $d->hexmac; # hexadecimal form
+ $result_b64 = $d->b64mac; # Base64 form
+ $result_b64u = $d->b64umac; # Base64 URL Safe form
=head1 DESCRIPTION
@@ -83,15 +86,21 @@ Logically joins all arguments into a single string, and returns its Pelican mess
=head2 pelican_b64
-Logically joins all arguments into a single string, and returns its Pelican message authentication code encoded as a BASE64 string.
+Logically joins all arguments into a single string, and returns its Pelican message authentication code encoded as a Base64 string.
$pelican_b64 = pelican_b64($key, 'data buffer');
#or
$pelican_b64 = pelican_b64($key, 'any data', 'more data', 'even more data');
-=head1 METHODS
+=head2 pelican_b64u
+
+Logically joins all arguments into a single string, and returns its Pelican message authentication code encoded as a Base64 URL Safe string (see RFC 4648 section 5).
-The OO interface provides the same set of functions as L<Crypt::Mac>.
+ $pelican_b64url = pelican_b64u($key, 'data buffer');
+ #or
+ $pelican_b64url = pelican_b64u($key, 'any data', 'more data', 'even more data');
+
+=head1 METHODS
=head2 new
@@ -129,6 +138,10 @@ The OO interface provides the same set of functions as L<Crypt::Mac>.
$result_b64 = $d->b64mac();
+=head2 b64umac
+
+ $result_b64url = $d->b64umac();
+
=head1 SEE ALSO
=over 4
diff --git a/lib/Crypt/Mac/XCBC.pm b/lib/Crypt/Mac/XCBC.pm
index c152c010..c5b2a1f5 100644
--- a/lib/Crypt/Mac/XCBC.pm
+++ b/lib/Crypt/Mac/XCBC.pm
@@ -6,7 +6,7 @@ use strict;
use warnings;
use Exporter 'import';
-our %EXPORT_TAGS = ( all => [qw( xcbc xcbc_hex xcbc_b64 )] );
+our %EXPORT_TAGS = ( all => [qw( xcbc xcbc_hex xcbc_b64 xcbc_b64u )] );
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
our @EXPORT = qw();
@@ -17,8 +17,9 @@ use Crypt::Cipher;
sub new { my $class = shift; _new(Crypt::Cipher::_trans_cipher_name(shift), @_) }
sub xcbc { Crypt::Mac::XCBC->new(shift, shift)->add(@_)->mac }
-sub xcbc_hex { Crypt::Mac::XCBC->new(shift, shift)->add(@_)->hexmac }
-sub xcbc_b64 { Crypt::Mac::XCBC->new(shift, shift)->add(@_)->b64mac }
+sub xcbc_hex { Crypt::Mac::XCBC->new(shift, shift)->add(@_)->hexmac }
+sub xcbc_b64 { Crypt::Mac::XCBC->new(shift, shift)->add(@_)->b64mac }
+sub xcbc_b64u { Crypt::Mac::XCBC->new(shift, shift)->add(@_)->b64umac }
1;
@@ -34,9 +35,10 @@ Crypt::Mac::XCBC - Message authentication code XCBC
use Crypt::Mac::XCBC qw( xcbc xcbc_hex );
# calculate MAC from string/buffer
- $xcbc_raw = xcbc($cipher_name, $key, 'data buffer');
- $xcbc_hex = xcbc_hex($cipher_name, $key, 'data buffer');
- $xcbc_b64 = xcbc_b64($cipher_name, $key, 'data buffer');
+ $xcbc_raw = xcbc($cipher_name, $key, 'data buffer');
+ $xcbc_hex = xcbc_hex($cipher_name, $key, 'data buffer');
+ $xcbc_b64 = xcbc_b64($cipher_name, $key, 'data buffer');
+ $xcbc_b64u = xcbc_b64u($cipher_name, $key, 'data buffer');
### OO interface:
use Crypt::Mac::XCBC;
@@ -45,9 +47,10 @@ Crypt::Mac::XCBC - Message authentication code XCBC
$d->add('any data');
$d->addfile('filename.dat');
$d->addfile(*FILEHANDLE);
- $result_raw = $d->mac; # raw bytes
- $result_hex = $d->hexmac; # hexadecimal form
- $result_b64 = $d->b64mac; # Base64 form
+ $result_raw = $d->mac; # raw bytes
+ $result_hex = $d->hexmac; # hexadecimal form
+ $result_b64 = $d->b64mac; # Base64 form
+ $result_b64u = $d->b64umac; # Base64 URL Safe form
=head1 DESCRIPTION
@@ -85,15 +88,21 @@ Logically joins all arguments into a single string, and returns its XCBC message
=head2 xcbc_b64
-Logically joins all arguments into a single string, and returns its XCBC message authentication code encoded as a BASE64 string.
+Logically joins all arguments into a single string, and returns its XCBC message authentication code encoded as a Base64 string.
$xcbc_b64 = xcbc_b64($cipher_name, $key, 'data buffer');
#or
$xcbc_b64 = xcbc_b64($cipher_name, $key, 'any data', 'more data', 'even more data');
-=head1 METHODS
+=head2 xcbc_b64u
+
+Logically joins all arguments into a single string, and returns its XCBC message authentication code encoded as a Base64 URL Safe string (see RFC 4648 section 5).
-The OO interface provides the same set of functions as L<Crypt::Mac>.
+ $xcbc_b64url = xcbc_b64u($cipher_name, $key, 'data buffer');
+ #or
+ $xcbc_b64url = xcbc_b64u($cipher_name, $key, 'any data', 'more data', 'even more data');
+
+=head1 METHODS
=head2 new
@@ -131,6 +140,10 @@ The OO interface provides the same set of functions as L<Crypt::Mac>.
$result_b64 = $d->b64mac();
+=head2 b64umac
+
+ $result_b64url = $d->b64umac();
+
=head1 SEE ALSO
=over 4
diff --git a/lib/CryptX.pm b/lib/CryptX.pm
index 0e4db6ad..9fe5da0f 100644
--- a/lib/CryptX.pm
+++ b/lib/CryptX.pm
@@ -3,7 +3,7 @@ package CryptX;
use strict;
use warnings ;
-our $VERSION = '0.013';
+our $VERSION = '0.014';
$VERSION = eval $VERSION;
require XSLoader;
diff --git a/t/digest_chaes.t b/t/digest_chaes.t
index 8a732172..2c5ea449 100644
--- a/t/digest_chaes.t
+++ b/t/digest_chaes.t
@@ -3,10 +3,10 @@
use strict;
use warnings;
-use Test::More tests => 7*3 + 8*4 + 6;
+use Test::More tests => 8*3 + 9*4 + 6;
-use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_file digest_file_hex digest_file_b64 );
-use Crypt::Digest::CHAES qw( chaes chaes_hex chaes_b64 chaes_file chaes_file_hex chaes_file_b64 );
+use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u );
+use Crypt::Digest::CHAES qw( chaes chaes_hex chaes_b64 chaes_b64u chaes_file chaes_file_hex chaes_file_b64 chaes_file_b64u );
is( Crypt::Digest::hashsize('CHAES'), 16, 'hashsize/1');
is( Crypt::Digest->hashsize('CHAES'), 16, 'hashsize/2');
@@ -22,15 +22,17 @@ is( chaes_b64(""), "QEeSnx9XJkO1X4KesykdEQ==", 'chaes (base64/1)');
is( digest_data('CHAES', ""), pack("H*","4047929f1f572643b55f829eb3291d11"), 'chaes (digest_data_raw/1)');
is( digest_data_hex('CHAES', ""), "4047929f1f572643b55f829eb3291d11", 'chaes (digest_data_hex/1)');
is( digest_data_b64('CHAES', ""), "QEeSnx9XJkO1X4KesykdEQ==", 'chaes (digest_data_b64/1)');
+is( digest_data_b64u('CHAES', ""), "QEeSnx9XJkO1X4KesykdEQ", 'chaes (digest_data_b64u/1)');
is( Crypt::Digest::CHAES->new->add("")->hexdigest, "4047929f1f572643b55f829eb3291d11", 'chaes (OO/1)');
-is( chaes(123), pack("H*","fc04dbd92bbb0311c6cfc6cb75d64a7c"), 'chaes (raw/2)');
-is( chaes_hex(123), "fc04dbd92bbb0311c6cfc6cb75d64a7c", 'chaes (hex/2)');
-is( chaes_b64(123), "/ATb2Su7AxHGz8bLddZKfA==", 'chaes (base64/2)');
-is( digest_data('CHAES', 123), pack("H*","fc04dbd92bbb0311c6cfc6cb75d64a7c"), 'chaes (digest_data_raw/2)');
-is( digest_data_hex('CHAES', 123), "fc04dbd92bbb0311c6cfc6cb75d64a7c", 'chaes (digest_data_hex/2)');
-is( digest_data_b64('CHAES', 123), "/ATb2Su7AxHGz8bLddZKfA==", 'chaes (digest_data_b64/2)');
-is( Crypt::Digest::CHAES->new->add(123)->hexdigest, "fc04dbd92bbb0311c6cfc6cb75d64a7c", 'chaes (OO/2)');
+is( chaes("123"), pack("H*","fc04dbd92bbb0311c6cfc6cb75d64a7c"), 'chaes (raw/2)');
+is( chaes_hex("123"), "fc04dbd92bbb0311c6cfc6cb75d64a7c", 'chaes (hex/2)');
+is( chaes_b64("123"), "/ATb2Su7AxHGz8bLddZKfA==", 'chaes (base64/2)');
+is( digest_data('CHAES', "123"), pack("H*","fc04dbd92bbb0311c6cfc6cb75d64a7c"), 'chaes (digest_data_raw/2)');
+is( digest_data_hex('CHAES', "123"), "fc04dbd92bbb0311c6cfc6cb75d64a7c", 'chaes (digest_data_hex/2)');
+is( digest_data_b64('CHAES', "123"), "/ATb2Su7AxHGz8bLddZKfA==", 'chaes (digest_data_b64/2)');
+is( digest_data_b64u('CHAES', "123"), "_ATb2Su7AxHGz8bLddZKfA", 'chaes (digest_data_b64u/2)');
+is( Crypt::Digest::CHAES->new->add("123")->hexdigest, "fc04dbd92bbb0311c6cfc6cb75d64a7c", 'chaes (OO/2)');
is( chaes("test\0test\0test\n"), pack("H*","b01f0f1c3dbfb727f8e8a1775fcd9dbc"), 'chaes (raw/3)');
is( chaes_hex("test\0test\0test\n"), "b01f0f1c3dbfb727f8e8a1775fcd9dbc", 'chaes (hex/3)');
@@ -38,6 +40,7 @@ is( chaes_b64("test\0test\0test\n"), "sB8PHD2/tyf46KF3X82dvA==", 'chaes (base64/
is( digest_data('CHAES', "test\0test\0test\n"), pack("H*","b01f0f1c3dbfb727f8e8a1775fcd9dbc"), 'chaes (digest_data_raw/3)');
is( digest_data_hex('CHAES', "test\0test\0test\n"), "b01f0f1c3dbfb727f8e8a1775fcd9dbc", 'chaes (digest_data_hex/3)');
is( digest_data_b64('CHAES', "test\0test\0test\n"), "sB8PHD2/tyf46KF3X82dvA==", 'chaes (digest_data_b64/3)');
+is( digest_data_b64u('CHAES', "test\0test\0test\n"), "sB8PHD2_tyf46KF3X82dvA", 'chaes (digest_data_b64u/3)');
is( Crypt::Digest::CHAES->new->add("test\0test\0test\n")->hexdigest, "b01f0f1c3dbfb727f8e8a1775fcd9dbc", 'chaes (OO/3)');
@@ -47,6 +50,7 @@ is( chaes_file_b64('t/data/binary-test.file'), "UDkKJHLQ3/4DIzYLKM+AYA==", 'chae
is( digest_file('CHAES', 't/data/binary-test.file'), pack("H*","50390a2472d0dffe0323360b28cf8060"), 'chaes (digest_file_raw/file/1)');
is( digest_file_hex('CHAES', 't/data/binary-test.file'), "50390a2472d0dffe0323360b28cf8060", 'chaes (digest_file_hex/file/1)');
is( digest_file_b64('CHAES', 't/data/binary-test.file'), "UDkKJHLQ3/4DIzYLKM+AYA==", 'chaes (digest_file_b64/file/1)');
+is( digest_file_b64u('CHAES', 't/data/binary-test.file'), "UDkKJHLQ3_4DIzYLKM-AYA", 'chaes (digest_file_b64u/file/1)');
is( Crypt::Digest::CHAES->new->addfile('t/data/binary-test.file')->hexdigest, "50390a2472d0dffe0323360b28cf8060", 'chaes (OO/file/1)');
{
open(my $fh, '<', 't/data/binary-test.file');
@@ -61,6 +65,7 @@ is( chaes_file_b64('t/data/text-CR.file'), "8Ix4OLqj29wCtqwpDbR2CQ==", 'chaes (b
is( digest_file('CHAES', 't/data/text-CR.file'), pack("H*","f08c7838baa3dbdc02b6ac290db47609"), 'chaes (digest_file_raw/file/2)');
is( digest_file_hex('CHAES', 't/data/text-CR.file'), "f08c7838baa3dbdc02b6ac290db47609", 'chaes (digest_file_hex/file/2)');
is( digest_file_b64('CHAES', 't/data/text-CR.file'), "8Ix4OLqj29wCtqwpDbR2CQ==", 'chaes (digest_file_b64/file/2)');
+is( digest_file_b64u('CHAES', 't/data/text-CR.file'), "8Ix4OLqj29wCtqwpDbR2CQ", 'chaes (digest_file_b64u/file/2)');
is( Crypt::Digest::CHAES->new->addfile('t/data/text-CR.file')->hexdigest, "f08c7838baa3dbdc02b6ac290db47609", 'chaes (OO/file/2)');
{
open(my $fh, '<', 't/data/text-CR.file');
@@ -75,6 +80,7 @@ is( chaes_file_b64('t/data/text-CRLF.file'), "t4dAIrGiVYov+jhMqDvdPw==", 'chaes
is( digest_file('CHAES', 't/data/text-CRLF.file'), pack("H*","b7874022b1a2558a2ffa384ca83bdd3f"), 'chaes (digest_file_raw/file/3)');
is( digest_file_hex('CHAES', 't/data/text-CRLF.file'), "b7874022b1a2558a2ffa384ca83bdd3f", 'chaes (digest_file_hex/file/3)');
is( digest_file_b64('CHAES', 't/data/text-CRLF.file'), "t4dAIrGiVYov+jhMqDvdPw==", 'chaes (digest_file_b64/file/3)');
+is( digest_file_b64u('CHAES', 't/data/text-CRLF.file'), "t4dAIrGiVYov-jhMqDvdPw", 'chaes (digest_file_b64u/file/3)');
is( Crypt::Digest::CHAES->new->addfile('t/data/text-CRLF.file')->hexdigest, "b7874022b1a2558a2ffa384ca83bdd3f", 'chaes (OO/file/3)');
{
open(my $fh, '<', 't/data/text-CRLF.file');
@@ -89,6 +95,7 @@ is( chaes_file_b64('t/data/text-LF.file'), "5KJnTcQSOz+jjcAUFLpYqg==", 'chaes (b
is( digest_file('CHAES', 't/data/text-LF.file'), pack("H*","e4a2674dc4123b3fa38dc01414ba58aa"), 'chaes (digest_file_raw/file/4)');
is( digest_file_hex('CHAES', 't/data/text-LF.file'), "e4a2674dc4123b3fa38dc01414ba58aa", 'chaes (digest_file_hex/file/4)');
is( digest_file_b64('CHAES', 't/data/text-LF.file'), "5KJnTcQSOz+jjcAUFLpYqg==", 'chaes (digest_file_b64/file/4)');
+is( digest_file_b64u('CHAES', 't/data/text-LF.file'), "5KJnTcQSOz-jjcAUFLpYqg", 'chaes (digest_file_b64u/file/4)');
is( Crypt::Digest::CHAES->new->addfile('t/data/text-LF.file')->hexdigest, "e4a2674dc4123b3fa38dc01414ba58aa", 'chaes (OO/file/4)');
{
open(my $fh, '<', 't/data/text-LF.file');
diff --git a/t/digest_md2.t b/t/digest_md2.t
index 3b6cbb36..2408ae35 100644
--- a/t/digest_md2.t
+++ b/t/digest_md2.t
@@ -3,10 +3,10 @@
use strict;
use warnings;
-use Test::More tests => 7*3 + 8*4 + 6;
+use Test::More tests => 8*3 + 9*4 + 6;
-use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_file digest_file_hex digest_file_b64 );
-use Crypt::Digest::MD2 qw( md2 md2_hex md2_b64 md2_file md2_file_hex md2_file_b64 );
+use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u );
+use Crypt::Digest::MD2 qw( md2 md2_hex md2_b64 md2_b64u md2_file md2_file_hex md2_file_b64 md2_file_b64u );
is( Crypt::Digest::hashsize('MD2'), 16, 'hashsize/1');
is( Crypt::Digest->hashsize('MD2'), 16, 'hashsize/2');
@@ -22,15 +22,17 @@ is( md2_b64(""), "g1Dlo+JMFT3yJ1yfgGkncw==", 'md2 (base64/1)');
is( digest_data('MD2', ""), pack("H*","8350e5a3e24c153df2275c9f80692773"), 'md2 (digest_data_raw/1)');
is( digest_data_hex('MD2', ""), "8350e5a3e24c153df2275c9f80692773", 'md2 (digest_data_hex/1)');
is( digest_data_b64('MD2', ""), "g1Dlo+JMFT3yJ1yfgGkncw==", 'md2 (digest_data_b64/1)');
+is( digest_data_b64u('MD2', ""), "g1Dlo-JMFT3yJ1yfgGkncw", 'md2 (digest_data_b64u/1)');
is( Crypt::Digest::MD2->new->add("")->hexdigest, "8350e5a3e24c153df2275c9f80692773", 'md2 (OO/1)');
-is( md2(123), pack("H*","ef1fedf5d32ead6b7aaf687de4ed1b71"), 'md2 (raw/2)');
-is( md2_hex(123), "ef1fedf5d32ead6b7aaf687de4ed1b71", 'md2 (hex/2)');
-is( md2_b64(123), "7x/t9dMurWt6r2h95O0bcQ==", 'md2 (base64/2)');
-is( digest_data('MD2', 123), pack("H*","ef1fedf5d32ead6b7aaf687de4ed1b71"), 'md2 (digest_data_raw/2)');
-is( digest_data_hex('MD2', 123), "ef1fedf5d32ead6b7aaf687de4ed1b71", 'md2 (digest_data_hex/2)');
-is( digest_data_b64('MD2', 123), "7x/t9dMurWt6r2h95O0bcQ==", 'md2 (digest_data_b64/2)');
-is( Crypt::Digest::MD2->new->add(123)->hexdigest, "ef1fedf5d32ead6b7aaf687de4ed1b71", 'md2 (OO/2)');
+is( md2("123"), pack("H*","ef1fedf5d32ead6b7aaf687de4ed1b71"), 'md2 (raw/2)');
+is( md2_hex("123"), "ef1fedf5d32ead6b7aaf687de4ed1b71", 'md2 (hex/2)');
+is( md2_b64("123"), "7x/t9dMurWt6r2h95O0bcQ==", 'md2 (base64/2)');
+is( digest_data('MD2', "123"), pack("H*","ef1fedf5d32ead6b7aaf687de4ed1b71"), 'md2 (digest_data_raw/2)');
+is( digest_data_hex('MD2', "123"), "ef1fedf5d32ead6b7aaf687de4ed1b71", 'md2 (digest_data_hex/2)');
+is( digest_data_b64('MD2', "123"), "7x/t9dMurWt6r2h95O0bcQ==", 'md2 (digest_data_b64/2)');
+is( digest_data_b64u('MD2', "123"), "7x_t9dMurWt6r2h95O0bcQ", 'md2 (digest_data_b64u/2)');
+is( Crypt::Digest::MD2->new->add("123")->hexdigest, "ef1fedf5d32ead6b7aaf687de4ed1b71", 'md2 (OO/2)');
is( md2("test\0test\0test\n"), pack("H*","2ab87f6a63c5a8095e4b1207f3ff860c"), 'md2 (raw/3)');
is( md2_hex("test\0test\0test\n"), "2ab87f6a63c5a8095e4b1207f3ff860c", 'md2 (hex/3)');
@@ -38,6 +40,7 @@ is( md2_b64("test\0test\0test\n"), "Krh/amPFqAleSxIH8/+GDA==", 'md2 (base64/3)')
is( digest_data('MD2', "test\0test\0test\n"), pack("H*","2ab87f6a63c5a8095e4b1207f3ff860c"), 'md2 (digest_data_raw/3)');
is( digest_data_hex('MD2', "test\0test\0test\n"), "2ab87f6a63c5a8095e4b1207f3ff860c", 'md2 (digest_data_hex/3)');
is( digest_data_b64('MD2', "test\0test\0test\n"), "Krh/amPFqAleSxIH8/+GDA==", 'md2 (digest_data_b64/3)');
+is( digest_data_b64u('MD2', "test\0test\0test\n"), "Krh_amPFqAleSxIH8_-GDA", 'md2 (digest_data_b64u/3)');
is( Crypt::Digest::MD2->new->add("test\0test\0test\n")->hexdigest, "2ab87f6a63c5a8095e4b1207f3ff860c", 'md2 (OO/3)');
@@ -47,6 +50,7 @@ is( md2_file_b64('t/data/binary-test.file'), "Q/pKQDzyuYJqchVNVrwJpw==", 'md2 (b
is( digest_file('MD2', 't/data/binary-test.file'), pack("H*","43fa4a403cf2b9826a72154d56bc09a7"), 'md2 (digest_file_raw/file/1)');
is( digest_file_hex('MD2', 't/data/binary-test.file'), "43fa4a403cf2b9826a72154d56bc09a7", 'md2 (digest_file_hex/file/1)');
is( digest_file_b64('MD2', 't/data/binary-test.file'), "Q/pKQDzyuYJqchVNVrwJpw==", 'md2 (digest_file_b64/file/1)');
+is( digest_file_b64u('MD2', 't/data/binary-test.file'), "Q_pKQDzyuYJqchVNVrwJpw", 'md2 (digest_file_b64u/file/1)');
is( Crypt::Digest::MD2->new->addfile('t/data/binary-test.file')->hexdigest, "43fa4a403cf2b9826a72154d56bc09a7", 'md2 (OO/file/1)');
{
open(my $fh, '<', 't/data/binary-test.file');
@@ -61,6 +65,7 @@ is( md2_file_b64('t/data/text-CR.file'), "rvtoOdrRqgYeIx6cOut60A==", 'md2 (base6
is( digest_file('MD2', 't/data/text-CR.file'), pack("H*","aefb6839dad1aa061e231e9c3aeb7ad0"), 'md2 (digest_file_raw/file/2)');
is( digest_file_hex('MD2', 't/data/text-CR.file'), "aefb6839dad1aa061e231e9c3aeb7ad0", 'md2 (digest_file_hex/file/2)');
is( digest_file_b64('MD2', 't/data/text-CR.file'), "rvtoOdrRqgYeIx6cOut60A==", 'md2 (digest_file_b64/file/2)');
+is( digest_file_b64u('MD2', 't/data/text-CR.file'), "rvtoOdrRqgYeIx6cOut60A", 'md2 (digest_file_b64u/file/2)');
is( Crypt::Digest::MD2->new->addfile('t/data/text-CR.file')->hexdigest, "aefb6839dad1aa061e231e9c3aeb7ad0", 'md2 (OO/file/2)');
{
open(my $fh, '<', 't/data/text-CR.file');
@@ -75,6 +80,7 @@ is( md2_file_b64('t/data/text-CRLF.file'), "XDJmX4NyuXqh2O1zPYj1Dg==", 'md2 (bas
is( digest_file('MD2', 't/data/text-CRLF.file'), pack("H*","5c32665f8372b97aa1d8ed733d88f50e"), 'md2 (digest_file_raw/file/3)');
is( digest_file_hex('MD2', 't/data/text-CRLF.file'), "5c32665f8372b97aa1d8ed733d88f50e", 'md2 (digest_file_hex/file/3)');
is( digest_file_b64('MD2', 't/data/text-CRLF.file'), "XDJmX4NyuXqh2O1zPYj1Dg==", 'md2 (digest_file_b64/file/3)');
+is( digest_file_b64u('MD2', 't/data/text-CRLF.file'), "XDJmX4NyuXqh2O1zPYj1Dg", 'md2 (digest_file_b64u/file/3)');
is( Crypt::Digest::MD2->new->addfile('t/data/text-CRLF.file')->hexdigest, "5c32665f8372b97aa1d8ed733d88f50e", 'md2 (OO/file/3)');
{
open(my $fh, '<', 't/data/text-CRLF.file');
@@ -89,6 +95,7 @@ is( md2_file_b64('t/data/text-LF.file'), "DkFCulvaolfkxhj5swl4TA==", 'md2 (base6
is( digest_file('MD2', 't/data/text-LF.file'), pack("H*","0e4142ba5bdaa257e4c618f9b309784c"), 'md2 (digest_file_raw/file/4)');
is( digest_file_hex('MD2', 't/data/text-LF.file'), "0e4142ba5bdaa257e4c618f9b309784c", 'md2 (digest_file_hex/file/4)');
is( digest_file_b64('MD2', 't/data/text-LF.file'), "DkFCulvaolfkxhj5swl4TA==", 'md2 (digest_file_b64/file/4)');
+is( digest_file_b64u('MD2', 't/data/text-LF.file'), "DkFCulvaolfkxhj5swl4TA", 'md2 (digest_file_b64u/file/4)');
is( Crypt::Digest::MD2->new->addfile('t/data/text-LF.file')->hexdigest, "0e4142ba5bdaa257e4c618f9b309784c", 'md2 (OO/file/4)');
{
open(my $fh, '<', 't/data/text-LF.file');
diff --git a/t/digest_md4.t b/t/digest_md4.t
index 06cf6f69..86a4443c 100644
--- a/t/digest_md4.t
+++ b/t/digest_md4.t
@@ -3,10 +3,10 @@
use strict;
use warnings;
-use Test::More tests => 7*3 + 8*4 + 6;
+use Test::More tests => 8*3 + 9*4 + 6;
-use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_file digest_file_hex digest_file_b64 );
-use Crypt::Digest::MD4 qw( md4 md4_hex md4_b64 md4_file md4_file_hex md4_file_b64 );
+use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u );
+use Crypt::Digest::MD4 qw( md4 md4_hex md4_b64 md4_b64u md4_file md4_file_hex md4_file_b64 md4_file_b64u );
is( Crypt::Digest::hashsize('MD4'), 16, 'hashsize/1');
is( Crypt::Digest->hashsize('MD4'), 16, 'hashsize/2');
@@ -22,15 +22,17 @@ is( md4_b64(""), "MdbP4NFq6TG3PFnX4MCJwA==", 'md4 (base64/1)');
is( digest_data('MD4', ""), pack("H*","31d6cfe0d16ae931b73c59d7e0c089c0"), 'md4 (digest_data_raw/1)');
is( digest_data_hex('MD4', ""), "31d6cfe0d16ae931b73c59d7e0c089c0", 'md4 (digest_data_hex/1)');
is( digest_data_b64('MD4', ""), "MdbP4NFq6TG3PFnX4MCJwA==", 'md4 (digest_data_b64/1)');
+is( digest_data_b64u('MD4', ""), "MdbP4NFq6TG3PFnX4MCJwA", 'md4 (digest_data_b64u/1)');
is( Crypt::Digest::MD4->new->add("")->hexdigest, "31d6cfe0d16ae931b73c59d7e0c089c0", 'md4 (OO/1)');
-is( md4(123), pack("H*","c58cda49f00748a3bc0fcfa511d516cb"), 'md4 (raw/2)');
-is( md4_hex(123), "c58cda49f00748a3bc0fcfa511d516cb", 'md4 (hex/2)');
-is( md4_b64(123), "xYzaSfAHSKO8D8+lEdUWyw==", 'md4 (base64/2)');
-is( digest_data('MD4', 123), pack("H*","c58cda49f00748a3bc0fcfa511d516cb"), 'md4 (digest_data_raw/2)');
-is( digest_data_hex('MD4', 123), "c58cda49f00748a3bc0fcfa511d516cb", 'md4 (digest_data_hex/2)');
-is( digest_data_b64('MD4', 123), "xYzaSfAHSKO8D8+lEdUWyw==", 'md4 (digest_data_b64/2)');
-is( Crypt::Digest::MD4->new->add(123)->hexdigest, "c58cda49f00748a3bc0fcfa511d516cb", 'md4 (OO/2)');
+is( md4("123"), pack("H*","c58cda49f00748a3bc0fcfa511d516cb"), 'md4 (raw/2)');
+is( md4_hex("123"), "c58cda49f00748a3bc0fcfa511d516cb", 'md4 (hex/2)');
+is( md4_b64("123"), "xYzaSfAHSKO8D8+lEdUWyw==", 'md4 (base64/2)');
+is( digest_data('MD4', "123"), pack("H*","c58cda49f00748a3bc0fcfa511d516cb"), 'md4 (digest_data_raw/2)');
+is( digest_data_hex('MD4', "123"), "c58cda49f00748a3bc0fcfa511d516cb", 'md4 (digest_data_hex/2)');
+is( digest_data_b64('MD4', "123"), "xYzaSfAHSKO8D8+lEdUWyw==", 'md4 (digest_data_b64/2)');
+is( digest_data_b64u('MD4', "123"), "xYzaSfAHSKO8D8-lEdUWyw", 'md4 (digest_data_b64u/2)');
+is( Crypt::Digest::MD4->new->add("123")->hexdigest, "c58cda49f00748a3bc0fcfa511d516cb", 'md4 (OO/2)');
is( md4("test\0test\0test\n"), pack("H*","6c94f5386a75255cb008ea5ef7979eed"), 'md4 (raw/3)');
is( md4_hex("test\0test\0test\n"), "6c94f5386a75255cb008ea5ef7979eed", 'md4 (hex/3)');
@@ -38,6 +40,7 @@ is( md4_b64("test\0test\0test\n"), "bJT1OGp1JVywCOpe95ee7Q==", 'md4 (base64/3)')
is( digest_data('MD4', "test\0test\0test\n"), pack("H*","6c94f5386a75255cb008ea5ef7979eed"), 'md4 (digest_data_raw/3)');
is( digest_data_hex('MD4', "test\0test\0test\n"), "6c94f5386a75255cb008ea5ef7979eed", 'md4 (digest_data_hex/3)');
is( digest_data_b64('MD4', "test\0test\0test\n"), "bJT1OGp1JVywCOpe95ee7Q==", 'md4 (digest_data_b64/3)');
+is( digest_data_b64u('MD4', "test\0test\0test\n"), "bJT1OGp1JVywCOpe95ee7Q", 'md4 (digest_data_b64u/3)');
is( Crypt::Digest::MD4->new->add("test\0test\0test\n")->hexdigest, "6c94f5386a75255cb008ea5ef7979eed", 'md4 (OO/3)');
@@ -47,6 +50,7 @@ is( md4_file_b64('t/data/binary-test.file'), "3Ck+F9na15qTEaFFxqlrMQ==", 'md4 (b
is( digest_file('MD4', 't/data/binary-test.file'), pack("H*","dc293e17d9dad79a9311a145c6a96b31"), 'md4 (digest_file_raw/file/1)');
is( digest_file_hex('MD4', 't/data/binary-test.file'), "dc293e17d9dad79a9311a145c6a96b31", 'md4 (digest_file_hex/file/1)');
is( digest_file_b64('MD4', 't/data/binary-test.file'), "3Ck+F9na15qTEaFFxqlrMQ==", 'md4 (digest_file_b64/file/1)');
+is( digest_file_b64u('MD4', 't/data/binary-test.file'), "3Ck-F9na15qTEaFFxqlrMQ", 'md4 (digest_file_b64u/file/1)');
is( Crypt::Digest::MD4->new->addfile('t/data/binary-test.file')->hexdigest, "dc293e17d9dad79a9311a145c6a96b31", 'md4 (OO/file/1)');
{
open(my $fh, '<', 't/data/binary-test.file');
@@ -61,6 +65,7 @@ is( md4_file_b64('t/data/text-CR.file'), "8AYK0+2AgcjVXt5EXNGRMw==", 'md4 (base6
is( digest_file('MD4', 't/data/text-CR.file'), pack("H*","f0060ad3ed8081c8d55ede445cd19133"), 'md4 (digest_file_raw/file/2)');
is( digest_file_hex('MD4', 't/data/text-CR.file'), "f0060ad3ed8081c8d55ede445cd19133", 'md4 (digest_file_hex/file/2)');
is( digest_file_b64('MD4', 't/data/text-CR.file'), "8AYK0+2AgcjVXt5EXNGRMw==", 'md4 (digest_file_b64/file/2)');
+is( digest_file_b64u('MD4', 't/data/text-CR.file'), "8AYK0-2AgcjVXt5EXNGRMw", 'md4 (digest_file_b64u/file/2)');
is( Crypt::Digest::MD4->new->addfile('t/data/text-CR.file')->hexdigest, "f0060ad3ed8081c8d55ede445cd19133", 'md4 (OO/file/2)');
{
open(my $fh, '<', 't/data/text-CR.file');
@@ -75,6 +80,7 @@ is( md4_file_b64('t/data/text-CRLF.file'), "LDAms96p7zCJ1f91AFSziw==", 'md4 (bas
is( digest_file('MD4', 't/data/text-CRLF.file'), pack("H*","2c3026b3dea9ef3089d5ff750054b38b"), 'md4 (digest_file_raw/file/3)');
is( digest_file_hex('MD4', 't/data/text-CRLF.file'), "2c3026b3dea9ef3089d5ff750054b38b", 'md4 (digest_file_hex/file/3)');
is( digest_file_b64('MD4', 't/data/text-CRLF.file'), "LDAms96p7zCJ1f91AFSziw==", 'md4 (digest_file_b64/file/3)');
+is( digest_file_b64u('MD4', 't/data/text-CRLF.file'), "LDAms96p7zCJ1f91AFSziw", 'md4 (digest_file_b64u/file/3)');
is( Crypt::Digest::MD4->new->addfile('t/data/text-CRLF.file')->hexdigest, "2c3026b3dea9ef3089d5ff750054b38b", 'md4 (OO/file/3)');
{
open(my $fh, '<', 't/data/text-CRLF.file');
@@ -89,6 +95,7 @@ is( md4_file_b64('t/data/text-LF.file'), "PIfh7T+2Nmf4ej7IIX8g7w==", 'md4 (base6
is( digest_file('MD4', 't/data/text-LF.file'), pack("H*","3c87e1ed3fb63667f87a3ec8217f20ef"), 'md4 (digest_file_raw/file/4)');
is( digest_file_hex('MD4', 't/data/text-LF.file'), "3c87e1ed3fb63667f87a3ec8217f20ef", 'md4 (digest_file_hex/file/4)');
is( digest_file_b64('MD4', 't/data/text-LF.file'), "PIfh7T+2Nmf4ej7IIX8g7w==", 'md4 (digest_file_b64/file/4)');
+is( digest_file_b64u('MD4', 't/data/text-LF.file'), "PIfh7T-2Nmf4ej7IIX8g7w", 'md4 (digest_file_b64u/file/4)');
is( Crypt::Digest::MD4->new->addfile('t/data/text-LF.file')->hexdigest, "3c87e1ed3fb63667f87a3ec8217f20ef", 'md4 (OO/file/4)');
{
open(my $fh, '<', 't/data/text-LF.file');
diff --git a/t/digest_md5.t b/t/digest_md5.t
index 2a856b67..5a06e3ed 100644
--- a/t/digest_md5.t
+++ b/t/digest_md5.t
@@ -3,10 +3,10 @@
use strict;
use warnings;
-use Test::More tests => 7*3 + 8*4 + 6;
+use Test::More tests => 8*3 + 9*4 + 6;
-use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_file digest_file_hex digest_file_b64 );
-use Crypt::Digest::MD5 qw( md5 md5_hex md5_b64 md5_file md5_file_hex md5_file_b64 );
+use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u );
+use Crypt::Digest::MD5 qw( md5 md5_hex md5_b64 md5_b64u md5_file md5_file_hex md5_file_b64 md5_file_b64u );
is( Crypt::Digest::hashsize('MD5'), 16, 'hashsize/1');
is( Crypt::Digest->hashsize('MD5'), 16, 'hashsize/2');
@@ -22,15 +22,17 @@ is( md5_b64(""), "1B2M2Y8AsgTpgAmY7PhCfg==", 'md5 (base64/1)');
is( digest_data('MD5', ""), pack("H*","d41d8cd98f00b204e9800998ecf8427e"), 'md5 (digest_data_raw/1)');
is( digest_data_hex('MD5', ""), "d41d8cd98f00b204e9800998ecf8427e", 'md5 (digest_data_hex/1)');
is( digest_data_b64('MD5', ""), "1B2M2Y8AsgTpgAmY7PhCfg==", 'md5 (digest_data_b64/1)');
+is( digest_data_b64u('MD5', ""), "1B2M2Y8AsgTpgAmY7PhCfg", 'md5 (digest_data_b64u/1)');
is( Crypt::Digest::MD5->new->add("")->hexdigest, "d41d8cd98f00b204e9800998ecf8427e", 'md5 (OO/1)');
-is( md5(123), pack("H*","202cb962ac59075b964b07152d234b70"), 'md5 (raw/2)');
-is( md5_hex(123), "202cb962ac59075b964b07152d234b70", 'md5 (hex/2)');
-is( md5_b64(123), "ICy5YqxZB1uWSwcVLSNLcA==", 'md5 (base64/2)');
-is( digest_data('MD5', 123), pack("H*","202cb962ac59075b964b07152d234b70"), 'md5 (digest_data_raw/2)');
-is( digest_data_hex('MD5', 123), "202cb962ac59075b964b07152d234b70", 'md5 (digest_data_hex/2)');
-is( digest_data_b64('MD5', 123), "ICy5YqxZB1uWSwcVLSNLcA==", 'md5 (digest_data_b64/2)');
-is( Crypt::Digest::MD5->new->add(123)->hexdigest, "202cb962ac59075b964b07152d234b70", 'md5 (OO/2)');
+is( md5("123"), pack("H*","202cb962ac59075b964b07152d234b70"), 'md5 (raw/2)');
+is( md5_hex("123"), "202cb962ac59075b964b07152d234b70", 'md5 (hex/2)');
+is( md5_b64("123"), "ICy5YqxZB1uWSwcVLSNLcA==", 'md5 (base64/2)');
+is( digest_data('MD5', "123"), pack("H*","202cb962ac59075b964b07152d234b70"), 'md5 (digest_data_raw/2)');
+is( digest_data_hex('MD5', "123"), "202cb962ac59075b964b07152d234b70", 'md5 (digest_data_hex/2)');
+is( digest_data_b64('MD5', "123"), "ICy5YqxZB1uWSwcVLSNLcA==", 'md5 (digest_data_b64/2)');
+is( digest_data_b64u('MD5', "123"), "ICy5YqxZB1uWSwcVLSNLcA", 'md5 (digest_data_b64u/2)');
+is( Crypt::Digest::MD5->new->add("123")->hexdigest, "202cb962ac59075b964b07152d234b70", 'md5 (OO/2)');
is( md5("test\0test\0test\n"), pack("H*","38b00a95b30ee620eacd9aa05259a436"), 'md5 (raw/3)');
is( md5_hex("test\0test\0test\n"), "38b00a95b30ee620eacd9aa05259a436", 'md5 (hex/3)');
@@ -38,6 +40,7 @@ is( md5_b64("test\0test\0test\n"), "OLAKlbMO5iDqzZqgUlmkNg==", 'md5 (base64/3)')
is( digest_data('MD5', "test\0test\0test\n"), pack("H*","38b00a95b30ee620eacd9aa05259a436"), 'md5 (digest_data_raw/3)');
is( digest_data_hex('MD5', "test\0test\0test\n"), "38b00a95b30ee620eacd9aa05259a436", 'md5 (digest_data_hex/3)');
is( digest_data_b64('MD5', "test\0test\0test\n"), "OLAKlbMO5iDqzZqgUlmkNg==", 'md5 (digest_data_b64/3)');
+is( digest_data_b64u('MD5', "test\0test\0test\n"), "OLAKlbMO5iDqzZqgUlmkNg", 'md5 (digest_data_b64u/3)');
is( Crypt::Digest::MD5->new->add("test\0test\0test\n")->hexdigest, "38b00a95b30ee620eacd9aa05259a436", 'md5 (OO/3)');
@@ -47,6 +50,7 @@ is( md5_file_b64('t/data/binary-test.file'), "ylb6mDpLSegcaBZ/5KLoNQ==", 'md5 (b
is( digest_file('MD5', 't/data/binary-test.file'), pack("H*","ca56fa983a4b49e81c68167fe4a2e835"), 'md5 (digest_file_raw/file/1)');
is( digest_file_hex('MD5', 't/data/binary-test.file'), "ca56fa983a4b49e81c68167fe4a2e835", 'md5 (digest_file_hex/file/1)');
is( digest_file_b64('MD5', 't/data/binary-test.file'), "ylb6mDpLSegcaBZ/5KLoNQ==", 'md5 (digest_file_b64/file/1)');
+is( digest_file_b64u('MD5', 't/data/binary-test.file'), "ylb6mDpLSegcaBZ_5KLoNQ", 'md5 (digest_file_b64u/file/1)');
is( Crypt::Digest::MD5->new->addfile('t/data/binary-test.file')->hexdigest, "ca56fa983a4b49e81c68167fe4a2e835", 'md5 (OO/file/1)');
{
open(my $fh, '<', 't/data/binary-test.file');
@@ -61,6 +65,7 @@ is( md5_file_b64('t/data/text-CR.file'), "nivrpRbxnuPSs8/L+/Bfwg==", 'md5 (base6
is( digest_file('MD5', 't/data/text-CR.file'), pack("H*","9e2beba516f19ee3d2b3cfcbfbf05fc2"), 'md5 (digest_file_raw/file/2)');
is( digest_file_hex('MD5', 't/data/text-CR.file'), "9e2beba516f19ee3d2b3cfcbfbf05fc2", 'md5 (digest_file_hex/file/2)');
is( digest_file_b64('MD5', 't/data/text-CR.file'), "nivrpRbxnuPSs8/L+/Bfwg==", 'md5 (digest_file_b64/file/2)');
+is( digest_file_b64u('MD5', 't/data/text-CR.file'), "nivrpRbxnuPSs8_L-_Bfwg", 'md5 (digest_file_b64u/file/2)');
is( Crypt::Digest::MD5->new->addfile('t/data/text-CR.file')->hexdigest, "9e2beba516f19ee3d2b3cfcbfbf05fc2", 'md5 (OO/file/2)');
{
open(my $fh, '<', 't/data/text-CR.file');
@@ -75,6 +80,7 @@ is( md5_file_b64('t/data/text-CRLF.file'), "2TmsKxf2CRuwYrtvkZD8dg==", 'md5 (bas
is( digest_file('MD5', 't/data/text-CRLF.file'), pack("H*","d939ac2b17f6091bb062bb6f9190fc76"), 'md5 (digest_file_raw/file/3)');
is( digest_file_hex('MD5', 't/data/text-CRLF.file'), "d939ac2b17f6091bb062bb6f9190fc76", 'md5 (digest_file_hex/file/3)');
is( digest_file_b64('MD5', 't/data/text-CRLF.file'), "2TmsKxf2CRuwYrtvkZD8dg==", 'md5 (digest_file_b64/file/3)');
+is( digest_file_b64u('MD5', 't/data/text-CRLF.file'), "2TmsKxf2CRuwYrtvkZD8dg", 'md5 (digest_file_b64u/file/3)');
is( Crypt::Digest::MD5->new->addfile('t/data/text-CRLF.file')->hexdigest, "d939ac2b17f6091bb062bb6f9190fc76", 'md5 (OO/file/3)');
{
open(my $fh, '<', 't/data/text-CRLF.file');
@@ -89,6 +95,7 @@ is( md5_file_b64('t/data/text-LF.file'), "LFsZltUQpsyX+tX7qgsxPw==", 'md5 (base6
is( digest_file('MD5', 't/data/text-LF.file'), pack("H*","2c5b1996d510a6cc97fad5fbaa0b313f"), 'md5 (digest_file_raw/file/4)');
is( digest_file_hex('MD5', 't/data/text-LF.file'), "2c5b1996d510a6cc97fad5fbaa0b313f", 'md5 (digest_file_hex/file/4)');
is( digest_file_b64('MD5', 't/data/text-LF.file'), "LFsZltUQpsyX+tX7qgsxPw==", 'md5 (digest_file_b64/file/4)');
+is( digest_file_b64u('MD5', 't/data/text-LF.file'), "LFsZltUQpsyX-tX7qgsxPw", 'md5 (digest_file_b64u/file/4)');
is( Crypt::Digest::MD5->new->addfile('t/data/text-LF.file')->hexdigest, "2c5b1996d510a6cc97fad5fbaa0b313f", 'md5 (OO/file/4)');
{
open(my $fh, '<', 't/data/text-LF.file');
diff --git a/t/digest_ripemd128.t b/t/digest_ripemd128.t
index 23f35699..3309261c 100644
--- a/t/digest_ripemd128.t
+++ b/t/digest_ripemd128.t
@@ -3,10 +3,10 @@
use strict;
use warnings;
-use Test::More tests => 7*3 + 8*4 + 6;
+use Test::More tests => 8*3 + 9*4 + 6;
-use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_file digest_file_hex digest_file_b64 );
-use Crypt::Digest::RIPEMD128 qw( ripemd128 ripemd128_hex ripemd128_b64 ripemd128_file ripemd128_file_hex ripemd128_file_b64 );
+use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u );
+use Crypt::Digest::RIPEMD128 qw( ripemd128 ripemd128_hex ripemd128_b64 ripemd128_b64u ripemd128_file ripemd128_file_hex ripemd128_file_b64 ripemd128_file_b64u );
is( Crypt::Digest::hashsize('RIPEMD128'), 16, 'hashsize/1');
is( Crypt::Digest->hashsize('RIPEMD128'), 16, 'hashsize/2');
@@ -22,15 +22,17 @@ is( ripemd128_b64(""), "zfJiE6FQ3D7LYQ8Y9rOLRg==", 'ripemd128 (base64/1)');
is( digest_data('RIPEMD128', ""), pack("H*","cdf26213a150dc3ecb610f18f6b38b46"), 'ripemd128 (digest_data_raw/1)');
is( digest_data_hex('RIPEMD128', ""), "cdf26213a150dc3ecb610f18f6b38b46", 'ripemd128 (digest_data_hex/1)');
is( digest_data_b64('RIPEMD128', ""), "zfJiE6FQ3D7LYQ8Y9rOLRg==", 'ripemd128 (digest_data_b64/1)');
+is( digest_data_b64u('RIPEMD128', ""), "zfJiE6FQ3D7LYQ8Y9rOLRg", 'ripemd128 (digest_data_b64u/1)');
is( Crypt::Digest::RIPEMD128->new->add("")->hexdigest, "cdf26213a150dc3ecb610f18f6b38b46", 'ripemd128 (OO/1)');
-is( ripemd128(123), pack("H*","781f357c35df1fef3138f6d29670365a"), 'ripemd128 (raw/2)');
-is( ripemd128_hex(123), "781f357c35df1fef3138f6d29670365a", 'ripemd128 (hex/2)');
-is( ripemd128_b64(123), "eB81fDXfH+8xOPbSlnA2Wg==", 'ripemd128 (base64/2)');
-is( digest_data('RIPEMD128', 123), pack("H*","781f357c35df1fef3138f6d29670365a"), 'ripemd128 (digest_data_raw/2)');
-is( digest_data_hex('RIPEMD128', 123), "781f357c35df1fef3138f6d29670365a", 'ripemd128 (digest_data_hex/2)');
-is( digest_data_b64('RIPEMD128', 123), "eB81fDXfH+8xOPbSlnA2Wg==", 'ripemd128 (digest_data_b64/2)');
-is( Crypt::Digest::RIPEMD128->new->add(123)->hexdigest, "781f357c35df1fef3138f6d29670365a", 'ripemd128 (OO/2)');
+is( ripemd128("123"), pack("H*","781f357c35df1fef3138f6d29670365a"), 'ripemd128 (raw/2)');
+is( ripemd128_hex("123"), "781f357c35df1fef3138f6d29670365a", 'ripemd128 (hex/2)');
+is( ripemd128_b64("123"), "eB81fDXfH+8xOPbSlnA2Wg==", 'ripemd128 (base64/2)');
+is( digest_data('RIPEMD128', "123"), pack("H*","781f357c35df1fef3138f6d29670365a"), 'ripemd128 (digest_data_raw/2)');
+is( digest_data_hex('RIPEMD128', "123"), "781f357c35df1fef3138f6d29670365a", 'ripemd128 (digest_data_hex/2)');
+is( digest_data_b64('RIPEMD128', "123"), "eB81fDXfH+8xOPbSlnA2Wg==", 'ripemd128 (digest_data_b64/2)');
+is( digest_data_b64u('RIPEMD128', "123"), "eB81fDXfH-8xOPbSlnA2Wg", 'ripemd128 (digest_data_b64u/2)');
+is( Crypt::Digest::RIPEMD128->new->add("123")->hexdigest, "781f357c35df1fef3138f6d29670365a", 'ripemd128 (OO/2)');
is( ripemd128("test\0test\0test\n"), pack("H*","4910f92c00d56cedde3b8174c456ccbb"), 'ripemd128 (raw/3)');
is( ripemd128_hex("test\0test\0test\n"), "4910f92c00d56cedde3b8174c456ccbb", 'ripemd128 (hex/3)');
@@ -38,6 +40,7 @@ is( ripemd128_b64("test\0test\0test\n"), "SRD5LADVbO3eO4F0xFbMuw==", 'ripemd128
is( digest_data('RIPEMD128', "test\0test\0test\n"), pack("H*","4910f92c00d56cedde3b8174c456ccbb"), 'ripemd128 (digest_data_raw/3)');
is( digest_data_hex('RIPEMD128', "test\0test\0test\n"), "4910f92c00d56cedde3b8174c456ccbb", 'ripemd128 (digest_data_hex/3)');
is( digest_data_b64('RIPEMD128', "test\0test\0test\n"), "SRD5LADVbO3eO4F0xFbMuw==", 'ripemd128 (digest_data_b64/3)');
+is( digest_data_b64u('RIPEMD128', "test\0test\0test\n"), "SRD5LADVbO3eO4F0xFbMuw", 'ripemd128 (digest_data_b64u/3)');
is( Crypt::Digest::RIPEMD128->new->add("test\0test\0test\n")->hexdigest, "4910f92c00d56cedde3b8174c456ccbb", 'ripemd128 (OO/3)');
@@ -47,6 +50,7 @@ is( ripemd128_file_b64('t/data/binary-test.file'), "VfYloN4++ndueENAOEv2cQ==", '
is( digest_file('RIPEMD128', 't/data/binary-test.file'), pack("H*","55f625a0de3efa776e784340384bf671"), 'ripemd128 (digest_file_raw/file/1)');
is( digest_file_hex('RIPEMD128', 't/data/binary-test.file'), "55f625a0de3efa776e784340384bf671", 'ripemd128 (digest_file_hex/file/1)');
is( digest_file_b64('RIPEMD128', 't/data/binary-test.file'), "VfYloN4++ndueENAOEv2cQ==", 'ripemd128 (digest_file_b64/file/1)');
+is( digest_file_b64u('RIPEMD128', 't/data/binary-test.file'), "VfYloN4--ndueENAOEv2cQ", 'ripemd128 (digest_file_b64u/file/1)');
is( Crypt::Digest::RIPEMD128->new->addfile('t/data/binary-test.file')->hexdigest, "55f625a0de3efa776e784340384bf671", 'ripemd128 (OO/file/1)');
{
open(my $fh, '<', 't/data/binary-test.file');
@@ -61,6 +65,7 @@ is( ripemd128_file_b64('t/data/text-CR.file'), "TAlaBW8v4Y4AcZoCCTgQVA==", 'ripe
is( digest_file('RIPEMD128', 't/data/text-CR.file'), pack("H*","4c095a056f2fe18e00719a0209381054"), 'ripemd128 (digest_file_raw/file/2)');
is( digest_file_hex('RIPEMD128', 't/data/text-CR.file'), "4c095a056f2fe18e00719a0209381054", 'ripemd128 (digest_file_hex/file/2)');
is( digest_file_b64('RIPEMD128', 't/data/text-CR.file'), "TAlaBW8v4Y4AcZoCCTgQVA==", 'ripemd128 (digest_file_b64/file/2)');
+is( digest_file_b64u('RIPEMD128', 't/data/text-CR.file'), "TAlaBW8v4Y4AcZoCCTgQVA", 'ripemd128 (digest_file_b64u/file/2)');
is( Crypt::Digest::RIPEMD128->new->addfile('t/data/text-CR.file')->hexdigest, "4c095a056f2fe18e00719a0209381054", 'ripemd128 (OO/file/2)');
{
open(my $fh, '<', 't/data/text-CR.file');
@@ -75,6 +80,7 @@ is( ripemd128_file_b64('t/data/text-CRLF.file'), "6zX3l4fc2Hsf4CdgkisFYQ==", 'ri
is( digest_file('RIPEMD128', 't/data/text-CRLF.file'), pack("H*","eb35f79787dcd87b1fe02760922b0561"), 'ripemd128 (digest_file_raw/file/3)');
is( digest_file_hex('RIPEMD128', 't/data/text-CRLF.file'), "eb35f79787dcd87b1fe02760922b0561", 'ripemd128 (digest_file_hex/file/3)');
is( digest_file_b64('RIPEMD128', 't/data/text-CRLF.file'), "6zX3l4fc2Hsf4CdgkisFYQ==", 'ripemd128 (digest_file_b64/file/3)');
+is( digest_file_b64u('RIPEMD128', 't/data/text-CRLF.file'), "6zX3l4fc2Hsf4CdgkisFYQ", 'ripemd128 (digest_file_b64u/file/3)');
is( Crypt::Digest::RIPEMD128->new->addfile('t/data/text-CRLF.file')->hexdigest, "eb35f79787dcd87b1fe02760922b0561", 'ripemd128 (OO/file/3)');
{
open(my $fh, '<', 't/data/text-CRLF.file');
@@ -89,6 +95,7 @@ is( ripemd128_file_b64('t/data/text-LF.file'), "BYY0QNuhRNXQ/c5zy8J1NQ==", 'ripe
is( digest_file('RIPEMD128', 't/data/text-LF.file'), pack("H*","05863440dba144d5d0fdce73cbc27535"), 'ripemd128 (digest_file_raw/file/4)');
is( digest_file_hex('RIPEMD128', 't/data/text-LF.file'), "05863440dba144d5d0fdce73cbc27535", 'ripemd128 (digest_file_hex/file/4)');
is( digest_file_b64('RIPEMD128', 't/data/text-LF.file'), "BYY0QNuhRNXQ/c5zy8J1NQ==", 'ripemd128 (digest_file_b64/file/4)');
+is( digest_file_b64u('RIPEMD128', 't/data/text-LF.file'), "BYY0QNuhRNXQ_c5zy8J1NQ", 'ripemd128 (digest_file_b64u/file/4)');
is( Crypt::Digest::RIPEMD128->new->addfile('t/data/text-LF.file')->hexdigest, "05863440dba144d5d0fdce73cbc27535", 'ripemd128 (OO/file/4)');
{
open(my $fh, '<', 't/data/text-LF.file');
diff --git a/t/digest_ripemd160.t b/t/digest_ripemd160.t
index f9c4ceba..901a3621 100644
--- a/t/digest_ripemd160.t
+++ b/t/digest_ripemd160.t
@@ -3,10 +3,10 @@
use strict;
use warnings;
-use Test::More tests => 7*3 + 8*4 + 6;
+use Test::More tests => 8*3 + 9*4 + 6;
-use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_file digest_file_hex digest_file_b64 );
-use Crypt::Digest::RIPEMD160 qw( ripemd160 ripemd160_hex ripemd160_b64 ripemd160_file ripemd160_file_hex ripemd160_file_b64 );
+use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u );
+use Crypt::Digest::RIPEMD160 qw( ripemd160 ripemd160_hex ripemd160_b64 ripemd160_b64u ripemd160_file ripemd160_file_hex ripemd160_file_b64 ripemd160_file_b64u );
is( Crypt::Digest::hashsize('RIPEMD160'), 20, 'hashsize/1');
is( Crypt::Digest->hashsize('RIPEMD160'), 20, 'hashsize/2');
@@ -22,15 +22,17 @@ is( ripemd160_b64(""), "nBGFpcXp/FRhKAiXfuj1SLIljTE=", 'ripemd160 (base64/1)');
is( digest_data('RIPEMD160', ""), pack("H*","9c1185a5c5e9fc54612808977ee8f548b2258d31"), 'ripemd160 (digest_data_raw/1)');
is( digest_data_hex('RIPEMD160', ""), "9c1185a5c5e9fc54612808977ee8f548b2258d31", 'ripemd160 (digest_data_hex/1)');
is( digest_data_b64('RIPEMD160', ""), "nBGFpcXp/FRhKAiXfuj1SLIljTE=", 'ripemd160 (digest_data_b64/1)');
+is( digest_data_b64u('RIPEMD160', ""), "nBGFpcXp_FRhKAiXfuj1SLIljTE", 'ripemd160 (digest_data_b64u/1)');
is( Crypt::Digest::RIPEMD160->new->add("")->hexdigest, "9c1185a5c5e9fc54612808977ee8f548b2258d31", 'ripemd160 (OO/1)');
-is( ripemd160(123), pack("H*","e3431a8e0adbf96fd140103dc6f63a3f8fa343ab"), 'ripemd160 (raw/2)');
-is( ripemd160_hex(123), "e3431a8e0adbf96fd140103dc6f63a3f8fa343ab", 'ripemd160 (hex/2)');
-is( ripemd160_b64(123), "40Majgrb+W/RQBA9xvY6P4+jQ6s=", 'ripemd160 (base64/2)');
-is( digest_data('RIPEMD160', 123), pack("H*","e3431a8e0adbf96fd140103dc6f63a3f8fa343ab"), 'ripemd160 (digest_data_raw/2)');
-is( digest_data_hex('RIPEMD160', 123), "e3431a8e0adbf96fd140103dc6f63a3f8fa343ab", 'ripemd160 (digest_data_hex/2)');
-is( digest_data_b64('RIPEMD160', 123), "40Majgrb+W/RQBA9xvY6P4+jQ6s=", 'ripemd160 (digest_data_b64/2)');
-is( Crypt::Digest::RIPEMD160->new->add(123)->hexdigest, "e3431a8e0adbf96fd140103dc6f63a3f8fa343ab", 'ripemd160 (OO/2)');
+is( ripemd160("123"), pack("H*","e3431a8e0adbf96fd140103dc6f63a3f8fa343ab"), 'ripemd160 (raw/2)');
+is( ripemd160_hex("123"), "e3431a8e0adbf96fd140103dc6f63a3f8fa343ab", 'ripemd160 (hex/2)');
+is( ripemd160_b64("123"), "40Majgrb+W/RQBA9xvY6P4+jQ6s=", 'ripemd160 (base64/2)');
+is( digest_data('RIPEMD160', "123"), pack("H*","e3431a8e0adbf96fd140103dc6f63a3f8fa343ab"), 'ripemd160 (digest_data_raw/2)');
+is( digest_data_hex('RIPEMD160', "123"), "e3431a8e0adbf96fd140103dc6f63a3f8fa343ab", 'ripemd160 (digest_data_hex/2)');
+is( digest_data_b64('RIPEMD160', "123"), "40Majgrb+W/RQBA9xvY6P4+jQ6s=", 'ripemd160 (digest_data_b64/2)');
+is( digest_data_b64u('RIPEMD160', "123"), "40Majgrb-W_RQBA9xvY6P4-jQ6s", 'ripemd160 (digest_data_b64u/2)');
+is( Crypt::Digest::RIPEMD160->new->add("123")->hexdigest, "e3431a8e0adbf96fd140103dc6f63a3f8fa343ab", 'ripemd160 (OO/2)');
is( ripemd160("test\0test\0test\n"), pack("H*","1d3537be9984c77527d16313decc87e376411c8c"), 'ripemd160 (raw/3)');
is( ripemd160_hex("test\0test\0test\n"), "1d3537be9984c77527d16313decc87e376411c8c", 'ripemd160 (hex/3)');
@@ -38,6 +40,7 @@ is( ripemd160_b64("test\0test\0test\n"), "HTU3vpmEx3Un0WMT3syH43ZBHIw=", 'ripemd
is( digest_data('RIPEMD160', "test\0test\0test\n"), pack("H*","1d3537be9984c77527d16313decc87e376411c8c"), 'ripemd160 (digest_data_raw/3)');
is( digest_data_hex('RIPEMD160', "test\0test\0test\n"), "1d3537be9984c77527d16313decc87e376411c8c", 'ripemd160 (digest_data_hex/3)');
is( digest_data_b64('RIPEMD160', "test\0test\0test\n"), "HTU3vpmEx3Un0WMT3syH43ZBHIw=", 'ripemd160 (digest_data_b64/3)');
+is( digest_data_b64u('RIPEMD160', "test\0test\0test\n"), "HTU3vpmEx3Un0WMT3syH43ZBHIw", 'ripemd160 (digest_data_b64u/3)');
is( Crypt::Digest::RIPEMD160->new->add("test\0test\0test\n")->hexdigest, "1d3537be9984c77527d16313decc87e376411c8c", 'ripemd160 (OO/3)');
@@ -47,6 +50,7 @@ is( ripemd160_file_b64('t/data/binary-test.file'), "C/ZjYGjvbWoq+T2M4iDoMk7NrC8=
is( digest_file('RIPEMD160', 't/data/binary-test.file'), pack("H*","0bf6636068ef6d6a2af93d8ce220e8324ecdac2f"), 'ripemd160 (digest_file_raw/file/1)');
is( digest_file_hex('RIPEMD160', 't/data/binary-test.file'), "0bf6636068ef6d6a2af93d8ce220e8324ecdac2f", 'ripemd160 (digest_file_hex/file/1)');
is( digest_file_b64('RIPEMD160', 't/data/binary-test.file'), "C/ZjYGjvbWoq+T2M4iDoMk7NrC8=", 'ripemd160 (digest_file_b64/file/1)');
+is( digest_file_b64u('RIPEMD160', 't/data/binary-test.file'), "C_ZjYGjvbWoq-T2M4iDoMk7NrC8", 'ripemd160 (digest_file_b64u/file/1)');
is( Crypt::Digest::RIPEMD160->new->addfile('t/data/binary-test.file')->hexdigest, "0bf6636068ef6d6a2af93d8ce220e8324ecdac2f", 'ripemd160 (OO/file/1)');
{
open(my $fh, '<', 't/data/binary-test.file');
@@ -61,6 +65,7 @@ is( ripemd160_file_b64('t/data/text-CR.file'), "FW4THl5eghbK2X+ogKelQnMXmFM=", '
is( digest_file('RIPEMD160', 't/data/text-CR.file'), pack("H*","156e131e5e5e8216cad97fa880a7a54273179853"), 'ripemd160 (digest_file_raw/file/2)');
is( digest_file_hex('RIPEMD160', 't/data/text-CR.file'), "156e131e5e5e8216cad97fa880a7a54273179853", 'ripemd160 (digest_file_hex/file/2)');
is( digest_file_b64('RIPEMD160', 't/data/text-CR.file'), "FW4THl5eghbK2X+ogKelQnMXmFM=", 'ripemd160 (digest_file_b64/file/2)');
+is( digest_file_b64u('RIPEMD160', 't/data/text-CR.file'), "FW4THl5eghbK2X-ogKelQnMXmFM", 'ripemd160 (digest_file_b64u/file/2)');
is( Crypt::Digest::RIPEMD160->new->addfile('t/data/text-CR.file')->hexdigest, "156e131e5e5e8216cad97fa880a7a54273179853", 'ripemd160 (OO/file/2)');
{
open(my $fh, '<', 't/data/text-CR.file');
@@ -75,6 +80,7 @@ is( ripemd160_file_b64('t/data/text-CRLF.file'), "yzdKg0Fv5Pw64ElFs6eW87VMO2M=",
is( digest_file('RIPEMD160', 't/data/text-CRLF.file'), pack("H*","cb374a83416fe4fc3ae04945b3a796f3b54c3b63"), 'ripemd160 (digest_file_raw/file/3)');
is( digest_file_hex('RIPEMD160', 't/data/text-CRLF.file'), "cb374a83416fe4fc3ae04945b3a796f3b54c3b63", 'ripemd160 (digest_file_hex/file/3)');
is( digest_file_b64('RIPEMD160', 't/data/text-CRLF.file'), "yzdKg0Fv5Pw64ElFs6eW87VMO2M=", 'ripemd160 (digest_file_b64/file/3)');
+is( digest_file_b64u('RIPEMD160', 't/data/text-CRLF.file'), "yzdKg0Fv5Pw64ElFs6eW87VMO2M", 'ripemd160 (digest_file_b64u/file/3)');
is( Crypt::Digest::RIPEMD160->new->addfile('t/data/text-CRLF.file')->hexdigest, "cb374a83416fe4fc3ae04945b3a796f3b54c3b63", 'ripemd160 (OO/file/3)');
{
open(my $fh, '<', 't/data/text-CRLF.file');
@@ -89,6 +95,7 @@ is( ripemd160_file_b64('t/data/text-LF.file'), "NJE7GGKYI2ZSD14p2KCi1uPZqBI=", '
is( digest_file('RIPEMD160', 't/data/text-LF.file'), pack("H*","34913b1862982366520f5e29d8a0a2d6e3d9a812"), 'ripemd160 (digest_file_raw/file/4)');
is( digest_file_hex('RIPEMD160', 't/data/text-LF.file'), "34913b1862982366520f5e29d8a0a2d6e3d9a812", 'ripemd160 (digest_file_hex/file/4)');
is( digest_file_b64('RIPEMD160', 't/data/text-LF.file'), "NJE7GGKYI2ZSD14p2KCi1uPZqBI=", 'ripemd160 (digest_file_b64/file/4)');
+is( digest_file_b64u('RIPEMD160', 't/data/text-LF.file'), "NJE7GGKYI2ZSD14p2KCi1uPZqBI", 'ripemd160 (digest_file_b64u/file/4)');
is( Crypt::Digest::RIPEMD160->new->addfile('t/data/text-LF.file')->hexdigest, "34913b1862982366520f5e29d8a0a2d6e3d9a812", 'ripemd160 (OO/file/4)');
{
open(my $fh, '<', 't/data/text-LF.file');
diff --git a/t/digest_ripemd256.t b/t/digest_ripemd256.t
index b5149460..47531e4f 100644
--- a/t/digest_ripemd256.t
+++ b/t/digest_ripemd256.t
@@ -3,10 +3,10 @@
use strict;
use warnings;
-use Test::More tests => 7*3 + 8*4 + 6;
+use Test::More tests => 8*3 + 9*4 + 6;
-use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_file digest_file_hex digest_file_b64 );
-use Crypt::Digest::RIPEMD256 qw( ripemd256 ripemd256_hex ripemd256_b64 ripemd256_file ripemd256_file_hex ripemd256_file_b64 );
+use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u );
+use Crypt::Digest::RIPEMD256 qw( ripemd256 ripemd256_hex ripemd256_b64 ripemd256_b64u ripemd256_file ripemd256_file_hex ripemd256_file_b64 ripemd256_file_b64u );
is( Crypt::Digest::hashsize('RIPEMD256'), 32, 'hashsize/1');
is( Crypt::Digest->hashsize('RIPEMD256'), 32, 'hashsize/2');
@@ -22,15 +22,17 @@ is( ripemd256_b64(""), "ArpMTl+OzRh3/FLWTTDjei2XdPseXQJjgK4BaOPFUi0=", 'ripemd25
is( digest_data('RIPEMD256', ""), pack("H*","02ba4c4e5f8ecd1877fc52d64d30e37a2d9774fb1e5d026380ae0168e3c5522d"), 'ripemd256 (digest_data_raw/1)');
is( digest_data_hex('RIPEMD256', ""), "02ba4c4e5f8ecd1877fc52d64d30e37a2d9774fb1e5d026380ae0168e3c5522d", 'ripemd256 (digest_data_hex/1)');
is( digest_data_b64('RIPEMD256', ""), "ArpMTl+OzRh3/FLWTTDjei2XdPseXQJjgK4BaOPFUi0=", 'ripemd256 (digest_data_b64/1)');
+is( digest_data_b64u('RIPEMD256', ""), "ArpMTl-OzRh3_FLWTTDjei2XdPseXQJjgK4BaOPFUi0", 'ripemd256 (digest_data_b64u/1)');
is( Crypt::Digest::RIPEMD256->new->add("")->hexdigest, "02ba4c4e5f8ecd1877fc52d64d30e37a2d9774fb1e5d026380ae0168e3c5522d", 'ripemd256 (OO/1)');
-is( ripemd256(123), pack("H*","8536753ad7bface2dba89fb318c95b1b42890016057d4c3a2f351cec3acbb28b"), 'ripemd256 (raw/2)');
-is( ripemd256_hex(123), "8536753ad7bface2dba89fb318c95b1b42890016057d4c3a2f351cec3acbb28b", 'ripemd256 (hex/2)');
-is( ripemd256_b64(123), "hTZ1Ote/rOLbqJ+zGMlbG0KJABYFfUw6LzUc7DrLsos=", 'ripemd256 (base64/2)');
-is( digest_data('RIPEMD256', 123), pack("H*","8536753ad7bface2dba89fb318c95b1b42890016057d4c3a2f351cec3acbb28b"), 'ripemd256 (digest_data_raw/2)');
-is( digest_data_hex('RIPEMD256', 123), "8536753ad7bface2dba89fb318c95b1b42890016057d4c3a2f351cec3acbb28b", 'ripemd256 (digest_data_hex/2)');
-is( digest_data_b64('RIPEMD256', 123), "hTZ1Ote/rOLbqJ+zGMlbG0KJABYFfUw6LzUc7DrLsos=", 'ripemd256 (digest_data_b64/2)');
-is( Crypt::Digest::RIPEMD256->new->add(123)->hexdigest, "8536753ad7bface2dba89fb318c95b1b42890016057d4c3a2f351cec3acbb28b", 'ripemd256 (OO/2)');
+is( ripemd256("123"), pack("H*","8536753ad7bface2dba89fb318c95b1b42890016057d4c3a2f351cec3acbb28b"), 'ripemd256 (raw/2)');
+is( ripemd256_hex("123"), "8536753ad7bface2dba89fb318c95b1b42890016057d4c3a2f351cec3acbb28b", 'ripemd256 (hex/2)');
+is( ripemd256_b64("123"), "hTZ1Ote/rOLbqJ+zGMlbG0KJABYFfUw6LzUc7DrLsos=", 'ripemd256 (base64/2)');
+is( digest_data('RIPEMD256', "123"), pack("H*","8536753ad7bface2dba89fb318c95b1b42890016057d4c3a2f351cec3acbb28b"), 'ripemd256 (digest_data_raw/2)');
+is( digest_data_hex('RIPEMD256', "123"), "8536753ad7bface2dba89fb318c95b1b42890016057d4c3a2f351cec3acbb28b", 'ripemd256 (digest_data_hex/2)');
+is( digest_data_b64('RIPEMD256', "123"), "hTZ1Ote/rOLbqJ+zGMlbG0KJABYFfUw6LzUc7DrLsos=", 'ripemd256 (digest_data_b64/2)');
+is( digest_data_b64u('RIPEMD256', "123"), "hTZ1Ote_rOLbqJ-zGMlbG0KJABYFfUw6LzUc7DrLsos", 'ripemd256 (digest_data_b64u/2)');
+is( Crypt::Digest::RIPEMD256->new->add("123")->hexdigest, "8536753ad7bface2dba89fb318c95b1b42890016057d4c3a2f351cec3acbb28b", 'ripemd256 (OO/2)');
is( ripemd256("test\0test\0test\n"), pack("H*","31c2bd4e721bb8fa911022bbc51ddc74943772a951f300bd4e4c9dfceddb10e5"), 'ripemd256 (raw/3)');
is( ripemd256_hex("test\0test\0test\n"), "31c2bd4e721bb8fa911022bbc51ddc74943772a951f300bd4e4c9dfceddb10e5", 'ripemd256 (hex/3)');
@@ -38,6 +40,7 @@ is( ripemd256_b64("test\0test\0test\n"), "McK9TnIbuPqRECK7xR3cdJQ3cqlR8wC9Tkyd/O
is( digest_data('RIPEMD256', "test\0test\0test\n"), pack("H*","31c2bd4e721bb8fa911022bbc51ddc74943772a951f300bd4e4c9dfceddb10e5"), 'ripemd256 (digest_data_raw/3)');
is( digest_data_hex('RIPEMD256', "test\0test\0test\n"), "31c2bd4e721bb8fa911022bbc51ddc74943772a951f300bd4e4c9dfceddb10e5", 'ripemd256 (digest_data_hex/3)');
is( digest_data_b64('RIPEMD256', "test\0test\0test\n"), "McK9TnIbuPqRECK7xR3cdJQ3cqlR8wC9Tkyd/O3bEOU=", 'ripemd256 (digest_data_b64/3)');
+is( digest_data_b64u('RIPEMD256', "test\0test\0test\n"), "McK9TnIbuPqRECK7xR3cdJQ3cqlR8wC9Tkyd_O3bEOU", 'ripemd256 (digest_data_b64u/3)');
is( Crypt::Digest::RIPEMD256->new->add("test\0test\0test\n")->hexdigest, "31c2bd4e721bb8fa911022bbc51ddc74943772a951f300bd4e4c9dfceddb10e5", 'ripemd256 (OO/3)');
@@ -47,6 +50,7 @@ is( ripemd256_file_b64('t/data/binary-test.file'), "BARcM+ZWx4DJ/pCNgZMi/QMbX8jg
is( digest_file('RIPEMD256', 't/data/binary-test.file'), pack("H*","04045c33e656c780c9fe908d819322fd031b5fc8e009c2d03bd2ba9fcc1ff8c8"), 'ripemd256 (digest_file_raw/file/1)');
is( digest_file_hex('RIPEMD256', 't/data/binary-test.file'), "04045c33e656c780c9fe908d819322fd031b5fc8e009c2d03bd2ba9fcc1ff8c8", 'ripemd256 (digest_file_hex/file/1)');
is( digest_file_b64('RIPEMD256', 't/data/binary-test.file'), "BARcM+ZWx4DJ/pCNgZMi/QMbX8jgCcLQO9K6n8wf+Mg=", 'ripemd256 (digest_file_b64/file/1)');
+is( digest_file_b64u('RIPEMD256', 't/data/binary-test.file'), "BARcM-ZWx4DJ_pCNgZMi_QMbX8jgCcLQO9K6n8wf-Mg", 'ripemd256 (digest_file_b64u/file/1)');
is( Crypt::Digest::RIPEMD256->new->addfile('t/data/binary-test.file')->hexdigest, "04045c33e656c780c9fe908d819322fd031b5fc8e009c2d03bd2ba9fcc1ff8c8", 'ripemd256 (OO/file/1)');
{
open(my $fh, '<', 't/data/binary-test.file');
@@ -61,6 +65,7 @@ is( ripemd256_file_b64('t/data/text-CR.file'), "n06TI6zRVMBzHn6fGwxK8sN4MbFFfFkc
is( digest_file('RIPEMD256', 't/data/text-CR.file'), pack("H*","9f4e9323acd154c0731e7e9f1b0c4af2c37831b1457c591cd4c19b3f79c930d4"), 'ripemd256 (digest_file_raw/file/2)');
is( digest_file_hex('RIPEMD256', 't/data/text-CR.file'), "9f4e9323acd154c0731e7e9f1b0c4af2c37831b1457c591cd4c19b3f79c930d4", 'ripemd256 (digest_file_hex/file/2)');
is( digest_file_b64('RIPEMD256', 't/data/text-CR.file'), "n06TI6zRVMBzHn6fGwxK8sN4MbFFfFkc1MGbP3nJMNQ=", 'ripemd256 (digest_file_b64/file/2)');
+is( digest_file_b64u('RIPEMD256', 't/data/text-CR.file'), "n06TI6zRVMBzHn6fGwxK8sN4MbFFfFkc1MGbP3nJMNQ", 'ripemd256 (digest_file_b64u/file/2)');
is( Crypt::Digest::RIPEMD256->new->addfile('t/data/text-CR.file')->hexdigest, "9f4e9323acd154c0731e7e9f1b0c4af2c37831b1457c591cd4c19b3f79c930d4", 'ripemd256 (OO/file/2)');
{
open(my $fh, '<', 't/data/text-CR.file');
@@ -75,6 +80,7 @@ is( ripemd256_file_b64('t/data/text-CRLF.file'), "aH7AcckK9C5VGj3wcZbp0n7FxOF0T+
is( digest_file('RIPEMD256', 't/data/text-CRLF.file'), pack("H*","687ec071c90af42e551a3df07196e9d27ec5c4e1744fe17a0e2eb27dc9109611"), 'ripemd256 (digest_file_raw/file/3)');
is( digest_file_hex('RIPEMD256', 't/data/text-CRLF.file'), "687ec071c90af42e551a3df07196e9d27ec5c4e1744fe17a0e2eb27dc9109611", 'ripemd256 (digest_file_hex/file/3)');
is( digest_file_b64('RIPEMD256', 't/data/text-CRLF.file'), "aH7AcckK9C5VGj3wcZbp0n7FxOF0T+F6Di6yfckQlhE=", 'ripemd256 (digest_file_b64/file/3)');
+is( digest_file_b64u('RIPEMD256', 't/data/text-CRLF.file'), "aH7AcckK9C5VGj3wcZbp0n7FxOF0T-F6Di6yfckQlhE", 'ripemd256 (digest_file_b64u/file/3)');
is( Crypt::Digest::RIPEMD256->new->addfile('t/data/text-CRLF.file')->hexdigest, "687ec071c90af42e551a3df07196e9d27ec5c4e1744fe17a0e2eb27dc9109611", 'ripemd256 (OO/file/3)');
{
open(my $fh, '<', 't/data/text-CRLF.file');
@@ -89,6 +95,7 @@ is( ripemd256_file_b64('t/data/text-LF.file'), "74tNfHVCaVhEA7RnLlq+RJcrNqTdtmoq
is( digest_file('RIPEMD256', 't/data/text-LF.file'), pack("H*","ef8b4d7c754269584403b4672e5abe44972b36a4ddb66a2a489e11041cbe7413"), 'ripemd256 (digest_file_raw/file/4)');
is( digest_file_hex('RIPEMD256', 't/data/text-LF.file'), "ef8b4d7c754269584403b4672e5abe44972b36a4ddb66a2a489e11041cbe7413", 'ripemd256 (digest_file_hex/file/4)');
is( digest_file_b64('RIPEMD256', 't/data/text-LF.file'), "74tNfHVCaVhEA7RnLlq+RJcrNqTdtmoqSJ4RBBy+dBM=", 'ripemd256 (digest_file_b64/file/4)');
+is( digest_file_b64u('RIPEMD256', 't/data/text-LF.file'), "74tNfHVCaVhEA7RnLlq-RJcrNqTdtmoqSJ4RBBy-dBM", 'ripemd256 (digest_file_b64u/file/4)');
is( Crypt::Digest::RIPEMD256->new->addfile('t/data/text-LF.file')->hexdigest, "ef8b4d7c754269584403b4672e5abe44972b36a4ddb66a2a489e11041cbe7413", 'ripemd256 (OO/file/4)');
{
open(my $fh, '<', 't/data/text-LF.file');
diff --git a/t/digest_ripemd320.t b/t/digest_ripemd320.t
index 42187c6c..9a6ca468 100644
--- a/t/digest_ripemd320.t
+++ b/t/digest_ripemd320.t
@@ -3,10 +3,10 @@
use strict;
use warnings;
-use Test::More tests => 7*3 + 8*4 + 6;
+use Test::More tests => 8*3 + 9*4 + 6;
-use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_file digest_file_hex digest_file_b64 );
-use Crypt::Digest::RIPEMD320 qw( ripemd320 ripemd320_hex ripemd320_b64 ripemd320_file ripemd320_file_hex ripemd320_file_b64 );
+use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u );
+use Crypt::Digest::RIPEMD320 qw( ripemd320 ripemd320_hex ripemd320_b64 ripemd320_b64u ripemd320_file ripemd320_file_hex ripemd320_file_b64 ripemd320_file_b64u );
is( Crypt::Digest::hashsize('RIPEMD320'), 40, 'hashsize/1');
is( Crypt::Digest->hashsize('RIPEMD320'), 40, 'hashsize/2');
@@ -22,15 +22,17 @@ is( ripemd320_b64(""), "ItZdVmFTbNx1wf31xt57QbnycyXrxh6FVxd9cFoOyIAVHDoyoAiZuA==
is( digest_data('RIPEMD320', ""), pack("H*","22d65d5661536cdc75c1fdf5c6de7b41b9f27325ebc61e8557177d705a0ec880151c3a32a00899b8"), 'ripemd320 (digest_data_raw/1)');
is( digest_data_hex('RIPEMD320', ""), "22d65d5661536cdc75c1fdf5c6de7b41b9f27325ebc61e8557177d705a0ec880151c3a32a00899b8", 'ripemd320 (digest_data_hex/1)');
is( digest_data_b64('RIPEMD320', ""), "ItZdVmFTbNx1wf31xt57QbnycyXrxh6FVxd9cFoOyIAVHDoyoAiZuA==", 'ripemd320 (digest_data_b64/1)');
+is( digest_data_b64u('RIPEMD320', ""), "ItZdVmFTbNx1wf31xt57QbnycyXrxh6FVxd9cFoOyIAVHDoyoAiZuA", 'ripemd320 (digest_data_b64u/1)');
is( Crypt::Digest::RIPEMD320->new->add("")->hexdigest, "22d65d5661536cdc75c1fdf5c6de7b41b9f27325ebc61e8557177d705a0ec880151c3a32a00899b8", 'ripemd320 (OO/1)');
-is( ripemd320(123), pack("H*","bfa11b73ad4e6421a8ba5a1223d9c9f58a5ad456be98bee5bfcd19a3ecdc6140ce4c700be860fda9"), 'ripemd320 (raw/2)');
-is( ripemd320_hex(123), "bfa11b73ad4e6421a8ba5a1223d9c9f58a5ad456be98bee5bfcd19a3ecdc6140ce4c700be860fda9", 'ripemd320 (hex/2)');
-is( ripemd320_b64(123), "v6Ebc61OZCGouloSI9nJ9Ypa1Fa+mL7lv80Zo+zcYUDOTHAL6GD9qQ==", 'ripemd320 (base64/2)');
-is( digest_data('RIPEMD320', 123), pack("H*","bfa11b73ad4e6421a8ba5a1223d9c9f58a5ad456be98bee5bfcd19a3ecdc6140ce4c700be860fda9"), 'ripemd320 (digest_data_raw/2)');
-is( digest_data_hex('RIPEMD320', 123), "bfa11b73ad4e6421a8ba5a1223d9c9f58a5ad456be98bee5bfcd19a3ecdc6140ce4c700be860fda9", 'ripemd320 (digest_data_hex/2)');
-is( digest_data_b64('RIPEMD320', 123), "v6Ebc61OZCGouloSI9nJ9Ypa1Fa+mL7lv80Zo+zcYUDOTHAL6GD9qQ==", 'ripemd320 (digest_data_b64/2)');
-is( Crypt::Digest::RIPEMD320->new->add(123)->hexdigest, "bfa11b73ad4e6421a8ba5a1223d9c9f58a5ad456be98bee5bfcd19a3ecdc6140ce4c700be860fda9", 'ripemd320 (OO/2)');
+is( ripemd320("123"), pack("H*","bfa11b73ad4e6421a8ba5a1223d9c9f58a5ad456be98bee5bfcd19a3ecdc6140ce4c700be860fda9"), 'ripemd320 (raw/2)');
+is( ripemd320_hex("123"), "bfa11b73ad4e6421a8ba5a1223d9c9f58a5ad456be98bee5bfcd19a3ecdc6140ce4c700be860fda9", 'ripemd320 (hex/2)');
+is( ripemd320_b64("123"), "v6Ebc61OZCGouloSI9nJ9Ypa1Fa+mL7lv80Zo+zcYUDOTHAL6GD9qQ==", 'ripemd320 (base64/2)');
+is( digest_data('RIPEMD320', "123"), pack("H*","bfa11b73ad4e6421a8ba5a1223d9c9f58a5ad456be98bee5bfcd19a3ecdc6140ce4c700be860fda9"), 'ripemd320 (digest_data_raw/2)');
+is( digest_data_hex('RIPEMD320', "123"), "bfa11b73ad4e6421a8ba5a1223d9c9f58a5ad456be98bee5bfcd19a3ecdc6140ce4c700be860fda9", 'ripemd320 (digest_data_hex/2)');
+is( digest_data_b64('RIPEMD320', "123"), "v6Ebc61OZCGouloSI9nJ9Ypa1Fa+mL7lv80Zo+zcYUDOTHAL6GD9qQ==", 'ripemd320 (digest_data_b64/2)');
+is( digest_data_b64u('RIPEMD320', "123"), "v6Ebc61OZCGouloSI9nJ9Ypa1Fa-mL7lv80Zo-zcYUDOTHAL6GD9qQ", 'ripemd320 (digest_data_b64u/2)');
+is( Crypt::Digest::RIPEMD320->new->add("123")->hexdigest, "bfa11b73ad4e6421a8ba5a1223d9c9f58a5ad456be98bee5bfcd19a3ecdc6140ce4c700be860fda9", 'ripemd320 (OO/2)');
is( ripemd320("test\0test\0test\n"), pack("H*","efdfb0c3c74bdf938a4845638eb3622e2bdba11a68a4831b8517cb6b827e46a6026419b27003a044"), 'ripemd320 (raw/3)');
is( ripemd320_hex("test\0test\0test\n"), "efdfb0c3c74bdf938a4845638eb3622e2bdba11a68a4831b8517cb6b827e46a6026419b27003a044", 'ripemd320 (hex/3)');
@@ -38,6 +40,7 @@ is( ripemd320_b64("test\0test\0test\n"), "79+ww8dL35OKSEVjjrNiLivboRpopIMbhRfLa4
is( digest_data('RIPEMD320', "test\0test\0test\n"), pack("H*","efdfb0c3c74bdf938a4845638eb3622e2bdba11a68a4831b8517cb6b827e46a6026419b27003a044"), 'ripemd320 (digest_data_raw/3)');
is( digest_data_hex('RIPEMD320', "test\0test\0test\n"), "efdfb0c3c74bdf938a4845638eb3622e2bdba11a68a4831b8517cb6b827e46a6026419b27003a044", 'ripemd320 (digest_data_hex/3)');
is( digest_data_b64('RIPEMD320', "test\0test\0test\n"), "79+ww8dL35OKSEVjjrNiLivboRpopIMbhRfLa4J+RqYCZBmycAOgRA==", 'ripemd320 (digest_data_b64/3)');
+is( digest_data_b64u('RIPEMD320', "test\0test\0test\n"), "79-ww8dL35OKSEVjjrNiLivboRpopIMbhRfLa4J-RqYCZBmycAOgRA", 'ripemd320 (digest_data_b64u/3)');
is( Crypt::Digest::RIPEMD320->new->add("test\0test\0test\n")->hexdigest, "efdfb0c3c74bdf938a4845638eb3622e2bdba11a68a4831b8517cb6b827e46a6026419b27003a044", 'ripemd320 (OO/3)');
@@ -47,6 +50,7 @@ is( ripemd320_file_b64('t/data/binary-test.file'), "EVtO4pp6eBMj813h2WkNHDQPFiRj
is( digest_file('RIPEMD320', 't/data/binary-test.file'), pack("H*","115b4ee29a7a781323f35de1d9690d1c340f162463726e1b3206c139c700d65c92dc20497026a198"), 'ripemd320 (digest_file_raw/file/1)');
is( digest_file_hex('RIPEMD320', 't/data/binary-test.file'), "115b4ee29a7a781323f35de1d9690d1c340f162463726e1b3206c139c700d65c92dc20497026a198", 'ripemd320 (digest_file_hex/file/1)');
is( digest_file_b64('RIPEMD320', 't/data/binary-test.file'), "EVtO4pp6eBMj813h2WkNHDQPFiRjcm4bMgbBOccA1lyS3CBJcCahmA==", 'ripemd320 (digest_file_b64/file/1)');
+is( digest_file_b64u('RIPEMD320', 't/data/binary-test.file'), "EVtO4pp6eBMj813h2WkNHDQPFiRjcm4bMgbBOccA1lyS3CBJcCahmA", 'ripemd320 (digest_file_b64u/file/1)');
is( Crypt::Digest::RIPEMD320->new->addfile('t/data/binary-test.file')->hexdigest, "115b4ee29a7a781323f35de1d9690d1c340f162463726e1b3206c139c700d65c92dc20497026a198", 'ripemd320 (OO/file/1)');
{
open(my $fh, '<', 't/data/binary-test.file');
@@ -61,6 +65,7 @@ is( ripemd320_file_b64('t/data/text-CR.file'), "R6/qrXyWXi1LLlefM7B509mvw8yRCxVA
is( digest_file('RIPEMD320', 't/data/text-CR.file'), pack("H*","47afeaad7c965e2d4b2e579f33b079d3d9afc3cc910b154002fdf7b44f06ca6ebc746ade992b2645"), 'ripemd320 (digest_file_raw/file/2)');
is( digest_file_hex('RIPEMD320', 't/data/text-CR.file'), "47afeaad7c965e2d4b2e579f33b079d3d9afc3cc910b154002fdf7b44f06ca6ebc746ade992b2645", 'ripemd320 (digest_file_hex/file/2)');
is( digest_file_b64('RIPEMD320', 't/data/text-CR.file'), "R6/qrXyWXi1LLlefM7B509mvw8yRCxVAAv33tE8Gym68dGremSsmRQ==", 'ripemd320 (digest_file_b64/file/2)');
+is( digest_file_b64u('RIPEMD320', 't/data/text-CR.file'), "R6_qrXyWXi1LLlefM7B509mvw8yRCxVAAv33tE8Gym68dGremSsmRQ", 'ripemd320 (digest_file_b64u/file/2)');
is( Crypt::Digest::RIPEMD320->new->addfile('t/data/text-CR.file')->hexdigest, "47afeaad7c965e2d4b2e579f33b079d3d9afc3cc910b154002fdf7b44f06ca6ebc746ade992b2645", 'ripemd320 (OO/file/2)');
{
open(my $fh, '<', 't/data/text-CR.file');
@@ -75,6 +80,7 @@ is( ripemd320_file_b64('t/data/text-CRLF.file'), "1ADS6iZ+o53TKzbbGYq6JGwg4gqlwx
is( digest_file('RIPEMD320', 't/data/text-CRLF.file'), pack("H*","d400d2ea267ea39dd32b36db198aba246c20e20aa5c314d56d60efc582a10484925497ff428e6b26"), 'ripemd320 (digest_file_raw/file/3)');
is( digest_file_hex('RIPEMD320', 't/data/text-CRLF.file'), "d400d2ea267ea39dd32b36db198aba246c20e20aa5c314d56d60efc582a10484925497ff428e6b26", 'ripemd320 (digest_file_hex/file/3)');
is( digest_file_b64('RIPEMD320', 't/data/text-CRLF.file'), "1ADS6iZ+o53TKzbbGYq6JGwg4gqlwxTVbWDvxYKhBISSVJf/Qo5rJg==", 'ripemd320 (digest_file_b64/file/3)');
+is( digest_file_b64u('RIPEMD320', 't/data/text-CRLF.file'), "1ADS6iZ-o53TKzbbGYq6JGwg4gqlwxTVbWDvxYKhBISSVJf_Qo5rJg", 'ripemd320 (digest_file_b64u/file/3)');
is( Crypt::Digest::RIPEMD320->new->addfile('t/data/text-CRLF.file')->hexdigest, "d400d2ea267ea39dd32b36db198aba246c20e20aa5c314d56d60efc582a10484925497ff428e6b26", 'ripemd320 (OO/file/3)');
{
open(my $fh, '<', 't/data/text-CRLF.file');
@@ -89,6 +95,7 @@ is( ripemd320_file_b64('t/data/text-LF.file'), "71VpDS3dBKZ3Y7hxpszmIOsoRFg6RDMT
is( digest_file('RIPEMD320', 't/data/text-LF.file'), pack("H*","ef55690d2ddd04a67763b871a6cce620eb2844583a4433137959cf4b8d7cbacb95d820f74e748055"), 'ripemd320 (digest_file_raw/file/4)');
is( digest_file_hex('RIPEMD320', 't/data/text-LF.file'), "ef55690d2ddd04a67763b871a6cce620eb2844583a4433137959cf4b8d7cbacb95d820f74e748055", 'ripemd320 (digest_file_hex/file/4)');
is( digest_file_b64('RIPEMD320', 't/data/text-LF.file'), "71VpDS3dBKZ3Y7hxpszmIOsoRFg6RDMTeVnPS418usuV2CD3TnSAVQ==", 'ripemd320 (digest_file_b64/file/4)');
+is( digest_file_b64u('RIPEMD320', 't/data/text-LF.file'), "71VpDS3dBKZ3Y7hxpszmIOsoRFg6RDMTeVnPS418usuV2CD3TnSAVQ", 'ripemd320 (digest_file_b64u/file/4)');
is( Crypt::Digest::RIPEMD320->new->addfile('t/data/text-LF.file')->hexdigest, "ef55690d2ddd04a67763b871a6cce620eb2844583a4433137959cf4b8d7cbacb95d820f74e748055", 'ripemd320 (OO/file/4)');
{
open(my $fh, '<', 't/data/text-LF.file');
diff --git a/t/digest_sha1.t b/t/digest_sha1.t
index ec1894ad..12e91994 100644
--- a/t/digest_sha1.t
+++ b/t/digest_sha1.t
@@ -3,10 +3,10 @@
use strict;
use warnings;
-use Test::More tests => 7*3 + 8*4 + 6;
+use Test::More tests => 8*3 + 9*4 + 6;
-use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_file digest_file_hex digest_file_b64 );
-use Crypt::Digest::SHA1 qw( sha1 sha1_hex sha1_b64 sha1_file sha1_file_hex sha1_file_b64 );
+use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u );
+use Crypt::Digest::SHA1 qw( sha1 sha1_hex sha1_b64 sha1_b64u sha1_file sha1_file_hex sha1_file_b64 sha1_file_b64u );
is( Crypt::Digest::hashsize('SHA1'), 20, 'hashsize/1');
is( Crypt::Digest->hashsize('SHA1'), 20, 'hashsize/2');
@@ -22,15 +22,17 @@ is( sha1_b64(""), "2jmj7l5rSw0yVb/vlWAYkK/YBwk=", 'sha1 (base64/1)');
is( digest_data('SHA1', ""), pack("H*","da39a3ee5e6b4b0d3255bfef95601890afd80709"), 'sha1 (digest_data_raw/1)');
is( digest_data_hex('SHA1', ""), "da39a3ee5e6b4b0d3255bfef95601890afd80709", 'sha1 (digest_data_hex/1)');
is( digest_data_b64('SHA1', ""), "2jmj7l5rSw0yVb/vlWAYkK/YBwk=", 'sha1 (digest_data_b64/1)');
+is( digest_data_b64u('SHA1', ""), "2jmj7l5rSw0yVb_vlWAYkK_YBwk", 'sha1 (digest_data_b64u/1)');
is( Crypt::Digest::SHA1->new->add("")->hexdigest, "da39a3ee5e6b4b0d3255bfef95601890afd80709", 'sha1 (OO/1)');
-is( sha1(123), pack("H*","40bd001563085fc35165329ea1ff5c5ecbdbbeef"), 'sha1 (raw/2)');
-is( sha1_hex(123), "40bd001563085fc35165329ea1ff5c5ecbdbbeef", 'sha1 (hex/2)');
-is( sha1_b64(123), "QL0AFWMIX8NRZTKeof9cXsvbvu8=", 'sha1 (base64/2)');
-is( digest_data('SHA1', 123), pack("H*","40bd001563085fc35165329ea1ff5c5ecbdbbeef"), 'sha1 (digest_data_raw/2)');
-is( digest_data_hex('SHA1', 123), "40bd001563085fc35165329ea1ff5c5ecbdbbeef", 'sha1 (digest_data_hex/2)');
-is( digest_data_b64('SHA1', 123), "QL0AFWMIX8NRZTKeof9cXsvbvu8=", 'sha1 (digest_data_b64/2)');
-is( Crypt::Digest::SHA1->new->add(123)->hexdigest, "40bd001563085fc35165329ea1ff5c5ecbdbbeef", 'sha1 (OO/2)');
+is( sha1("123"), pack("H*","40bd001563085fc35165329ea1ff5c5ecbdbbeef"), 'sha1 (raw/2)');
+is( sha1_hex("123"), "40bd001563085fc35165329ea1ff5c5ecbdbbeef", 'sha1 (hex/2)');
+is( sha1_b64("123"), "QL0AFWMIX8NRZTKeof9cXsvbvu8=", 'sha1 (base64/2)');
+is( digest_data('SHA1', "123"), pack("H*","40bd001563085fc35165329ea1ff5c5ecbdbbeef"), 'sha1 (digest_data_raw/2)');
+is( digest_data_hex('SHA1', "123"), "40bd001563085fc35165329ea1ff5c5ecbdbbeef", 'sha1 (digest_data_hex/2)');
+is( digest_data_b64('SHA1', "123"), "QL0AFWMIX8NRZTKeof9cXsvbvu8=", 'sha1 (digest_data_b64/2)');
+is( digest_data_b64u('SHA1', "123"), "QL0AFWMIX8NRZTKeof9cXsvbvu8", 'sha1 (digest_data_b64u/2)');
+is( Crypt::Digest::SHA1->new->add("123")->hexdigest, "40bd001563085fc35165329ea1ff5c5ecbdbbeef", 'sha1 (OO/2)');
is( sha1("test\0test\0test\n"), pack("H*","ea50a3b39d7337f9232e1a89d97919465592f1e2"), 'sha1 (raw/3)');
is( sha1_hex("test\0test\0test\n"), "ea50a3b39d7337f9232e1a89d97919465592f1e2", 'sha1 (hex/3)');
@@ -38,6 +40,7 @@ is( sha1_b64("test\0test\0test\n"), "6lCjs51zN/kjLhqJ2XkZRlWS8eI=", 'sha1 (base6
is( digest_data('SHA1', "test\0test\0test\n"), pack("H*","ea50a3b39d7337f9232e1a89d97919465592f1e2"), 'sha1 (digest_data_raw/3)');
is( digest_data_hex('SHA1', "test\0test\0test\n"), "ea50a3b39d7337f9232e1a89d97919465592f1e2", 'sha1 (digest_data_hex/3)');
is( digest_data_b64('SHA1', "test\0test\0test\n"), "6lCjs51zN/kjLhqJ2XkZRlWS8eI=", 'sha1 (digest_data_b64/3)');
+is( digest_data_b64u('SHA1', "test\0test\0test\n"), "6lCjs51zN_kjLhqJ2XkZRlWS8eI", 'sha1 (digest_data_b64u/3)');
is( Crypt::Digest::SHA1->new->add("test\0test\0test\n")->hexdigest, "ea50a3b39d7337f9232e1a89d97919465592f1e2", 'sha1 (OO/3)');
@@ -47,6 +50,7 @@ is( sha1_file_b64('t/data/binary-test.file'), "j94EO3h2YoY6g/DFXyUXymuUf9w=", 's
is( digest_file('SHA1', 't/data/binary-test.file'), pack("H*","8fde043b787662863a83f0c55f2517ca6b947fdc"), 'sha1 (digest_file_raw/file/1)');
is( digest_file_hex('SHA1', 't/data/binary-test.file'), "8fde043b787662863a83f0c55f2517ca6b947fdc", 'sha1 (digest_file_hex/file/1)');
is( digest_file_b64('SHA1', 't/data/binary-test.file'), "j94EO3h2YoY6g/DFXyUXymuUf9w=", 'sha1 (digest_file_b64/file/1)');
+is( digest_file_b64u('SHA1', 't/data/binary-test.file'), "j94EO3h2YoY6g_DFXyUXymuUf9w", 'sha1 (digest_file_b64u/file/1)');
is( Crypt::Digest::SHA1->new->addfile('t/data/binary-test.file')->hexdigest, "8fde043b787662863a83f0c55f2517ca6b947fdc", 'sha1 (OO/file/1)');
{
open(my $fh, '<', 't/data/binary-test.file');
@@ -61,6 +65,7 @@ is( sha1_file_b64('t/data/text-CR.file'), "20Qwl4YZe6Y2S5x1Wba51P6kl/c=", 'sha1
is( digest_file('SHA1', 't/data/text-CR.file'), pack("H*","db44309786197ba6364b9c7559b6b9d4fea497f7"), 'sha1 (digest_file_raw/file/2)');
is( digest_file_hex('SHA1', 't/data/text-CR.file'), "db44309786197ba6364b9c7559b6b9d4fea497f7", 'sha1 (digest_file_hex/file/2)');
is( digest_file_b64('SHA1', 't/data/text-CR.file'), "20Qwl4YZe6Y2S5x1Wba51P6kl/c=", 'sha1 (digest_file_b64/file/2)');
+is( digest_file_b64u('SHA1', 't/data/text-CR.file'), "20Qwl4YZe6Y2S5x1Wba51P6kl_c", 'sha1 (digest_file_b64u/file/2)');
is( Crypt::Digest::SHA1->new->addfile('t/data/text-CR.file')->hexdigest, "db44309786197ba6364b9c7559b6b9d4fea497f7", 'sha1 (OO/file/2)');
{
open(my $fh, '<', 't/data/text-CR.file');
@@ -75,6 +80,7 @@ is( sha1_file_b64('t/data/text-CRLF.file'), "7Ut/4G1uqBKpmPL6D0DhDFOhfrs=", 'sha
is( digest_file('SHA1', 't/data/text-CRLF.file'), pack("H*","ed4b7fe06d6ea812a998f2fa0f40e10c53a17ebb"), 'sha1 (digest_file_raw/file/3)');
is( digest_file_hex('SHA1', 't/data/text-CRLF.file'), "ed4b7fe06d6ea812a998f2fa0f40e10c53a17ebb", 'sha1 (digest_file_hex/file/3)');
is( digest_file_b64('SHA1', 't/data/text-CRLF.file'), "7Ut/4G1uqBKpmPL6D0DhDFOhfrs=", 'sha1 (digest_file_b64/file/3)');
+is( digest_file_b64u('SHA1', 't/data/text-CRLF.file'), "7Ut_4G1uqBKpmPL6D0DhDFOhfrs", 'sha1 (digest_file_b64u/file/3)');
is( Crypt::Digest::SHA1->new->addfile('t/data/text-CRLF.file')->hexdigest, "ed4b7fe06d6ea812a998f2fa0f40e10c53a17ebb", 'sha1 (OO/file/3)');
{
open(my $fh, '<', 't/data/text-CRLF.file');
@@ -89,6 +95,7 @@ is( sha1_file_b64('t/data/text-LF.file'), "wS+03srPRhe26UR3cNbvVsUH1M4=", 'sha1
is( digest_file('SHA1', 't/data/text-LF.file'), pack("H*","c12fb4decacf4617b6e9447770d6ef56c507d4ce"), 'sha1 (digest_file_raw/file/4)');
is( digest_file_hex('SHA1', 't/data/text-LF.file'), "c12fb4decacf4617b6e9447770d6ef56c507d4ce", 'sha1 (digest_file_hex/file/4)');
is( digest_file_b64('SHA1', 't/data/text-LF.file'), "wS+03srPRhe26UR3cNbvVsUH1M4=", 'sha1 (digest_file_b64/file/4)');
+is( digest_file_b64u('SHA1', 't/data/text-LF.file'), "wS-03srPRhe26UR3cNbvVsUH1M4", 'sha1 (digest_file_b64u/file/4)');
is( Crypt::Digest::SHA1->new->addfile('t/data/text-LF.file')->hexdigest, "c12fb4decacf4617b6e9447770d6ef56c507d4ce", 'sha1 (OO/file/4)');
{
open(my $fh, '<', 't/data/text-LF.file');
diff --git a/t/digest_sha224.t b/t/digest_sha224.t
index 1c98d60b..e9390b42 100644
--- a/t/digest_sha224.t
+++ b/t/digest_sha224.t
@@ -3,10 +3,10 @@
use strict;
use warnings;
-use Test::More tests => 7*3 + 8*4 + 6;
+use Test::More tests => 8*3 + 9*4 + 6;
-use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_file digest_file_hex digest_file_b64 );
-use Crypt::Digest::SHA224 qw( sha224 sha224_hex sha224_b64 sha224_file sha224_file_hex sha224_file_b64 );
+use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u );
+use Crypt::Digest::SHA224 qw( sha224 sha224_hex sha224_b64 sha224_b64u sha224_file sha224_file_hex sha224_file_b64 sha224_file_b64u );
is( Crypt::Digest::hashsize('SHA224'), 28, 'hashsize/1');
is( Crypt::Digest->hashsize('SHA224'), 28, 'hashsize/2');
@@ -22,15 +22,17 @@ is( sha224_b64(""), "0UoCjCo6K8lHYQK7KII0xBWisB+CjqYqxbPkLw==", 'sha224 (base64/
is( digest_data('SHA224', ""), pack("H*","d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f"), 'sha224 (digest_data_raw/1)');
is( digest_data_hex('SHA224', ""), "d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f", 'sha224 (digest_data_hex/1)');
is( digest_data_b64('SHA224', ""), "0UoCjCo6K8lHYQK7KII0xBWisB+CjqYqxbPkLw==", 'sha224 (digest_data_b64/1)');
+is( digest_data_b64u('SHA224', ""), "0UoCjCo6K8lHYQK7KII0xBWisB-CjqYqxbPkLw", 'sha224 (digest_data_b64u/1)');
is( Crypt::Digest::SHA224->new->add("")->hexdigest, "d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f", 'sha224 (OO/1)');
-is( sha224(123), pack("H*","78d8045d684abd2eece923758f3cd781489df3a48e1278982466017f"), 'sha224 (raw/2)');
-is( sha224_hex(123), "78d8045d684abd2eece923758f3cd781489df3a48e1278982466017f", 'sha224 (hex/2)');
-is( sha224_b64(123), "eNgEXWhKvS7s6SN1jzzXgUid86SOEniYJGYBfw==", 'sha224 (base64/2)');
-is( digest_data('SHA224', 123), pack("H*","78d8045d684abd2eece923758f3cd781489df3a48e1278982466017f"), 'sha224 (digest_data_raw/2)');
-is( digest_data_hex('SHA224', 123), "78d8045d684abd2eece923758f3cd781489df3a48e1278982466017f", 'sha224 (digest_data_hex/2)');
-is( digest_data_b64('SHA224', 123), "eNgEXWhKvS7s6SN1jzzXgUid86SOEniYJGYBfw==", 'sha224 (digest_data_b64/2)');
-is( Crypt::Digest::SHA224->new->add(123)->hexdigest, "78d8045d684abd2eece923758f3cd781489df3a48e1278982466017f", 'sha224 (OO/2)');
+is( sha224("123"), pack("H*","78d8045d684abd2eece923758f3cd781489df3a48e1278982466017f"), 'sha224 (raw/2)');
+is( sha224_hex("123"), "78d8045d684abd2eece923758f3cd781489df3a48e1278982466017f", 'sha224 (hex/2)');
+is( sha224_b64("123"), "eNgEXWhKvS7s6SN1jzzXgUid86SOEniYJGYBfw==", 'sha224 (base64/2)');
+is( digest_data('SHA224', "123"), pack("H*","78d8045d684abd2eece923758f3cd781489df3a48e1278982466017f"), 'sha224 (digest_data_raw/2)');
+is( digest_data_hex('SHA224', "123"), "78d8045d684abd2eece923758f3cd781489df3a48e1278982466017f", 'sha224 (digest_data_hex/2)');
+is( digest_data_b64('SHA224', "123"), "eNgEXWhKvS7s6SN1jzzXgUid86SOEniYJGYBfw==", 'sha224 (digest_data_b64/2)');
+is( digest_data_b64u('SHA224', "123"), "eNgEXWhKvS7s6SN1jzzXgUid86SOEniYJGYBfw", 'sha224 (digest_data_b64u/2)');
+is( Crypt::Digest::SHA224->new->add("123")->hexdigest, "78d8045d684abd2eece923758f3cd781489df3a48e1278982466017f", 'sha224 (OO/2)');
is( sha224("test\0test\0test\n"), pack("H*","f4304fb326d85e3b19eefc4ecd772d2fa8d5e20cf9b3c30689bf5d1a"), 'sha224 (raw/3)');
is( sha224_hex("test\0test\0test\n"), "f4304fb326d85e3b19eefc4ecd772d2fa8d5e20cf9b3c30689bf5d1a", 'sha224 (hex/3)');
@@ -38,6 +40,7 @@ is( sha224_b64("test\0test\0test\n"), "9DBPsybYXjsZ7vxOzXctL6jV4gz5s8MGib9dGg=="
is( digest_data('SHA224', "test\0test\0test\n"), pack("H*","f4304fb326d85e3b19eefc4ecd772d2fa8d5e20cf9b3c30689bf5d1a"), 'sha224 (digest_data_raw/3)');
is( digest_data_hex('SHA224', "test\0test\0test\n"), "f4304fb326d85e3b19eefc4ecd772d2fa8d5e20cf9b3c30689bf5d1a", 'sha224 (digest_data_hex/3)');
is( digest_data_b64('SHA224', "test\0test\0test\n"), "9DBPsybYXjsZ7vxOzXctL6jV4gz5s8MGib9dGg==", 'sha224 (digest_data_b64/3)');
+is( digest_data_b64u('SHA224', "test\0test\0test\n"), "9DBPsybYXjsZ7vxOzXctL6jV4gz5s8MGib9dGg", 'sha224 (digest_data_b64u/3)');
is( Crypt::Digest::SHA224->new->add("test\0test\0test\n")->hexdigest, "f4304fb326d85e3b19eefc4ecd772d2fa8d5e20cf9b3c30689bf5d1a", 'sha224 (OO/3)');
@@ -47,6 +50,7 @@ is( sha224_file_b64('t/data/binary-test.file'), "1vtlOoU6MzyHvD59vHn/1iRY+zAw8u9
is( digest_file('SHA224', 't/data/binary-test.file'), pack("H*","d6fb653a853a333c87bc3e7dbc79ffd62458fb3030f2ef484b252b93"), 'sha224 (digest_file_raw/file/1)');
is( digest_file_hex('SHA224', 't/data/binary-test.file'), "d6fb653a853a333c87bc3e7dbc79ffd62458fb3030f2ef484b252b93", 'sha224 (digest_file_hex/file/1)');
is( digest_file_b64('SHA224', 't/data/binary-test.file'), "1vtlOoU6MzyHvD59vHn/1iRY+zAw8u9ISyUrkw==", 'sha224 (digest_file_b64/file/1)');
+is( digest_file_b64u('SHA224', 't/data/binary-test.file'), "1vtlOoU6MzyHvD59vHn_1iRY-zAw8u9ISyUrkw", 'sha224 (digest_file_b64u/file/1)');
is( Crypt::Digest::SHA224->new->addfile('t/data/binary-test.file')->hexdigest, "d6fb653a853a333c87bc3e7dbc79ffd62458fb3030f2ef484b252b93", 'sha224 (OO/file/1)');
{
open(my $fh, '<', 't/data/binary-test.file');
@@ -61,6 +65,7 @@ is( sha224_file_b64('t/data/text-CR.file'), "gLI9GFbY5UAgiDcwKcUPylFRiqYqCKTrxYC
is( digest_file('SHA224', 't/data/text-CR.file'), pack("H*","80b23d1856d8e5402088373029c50fca51518aa62a08a4ebc5808399"), 'sha224 (digest_file_raw/file/2)');
is( digest_file_hex('SHA224', 't/data/text-CR.file'), "80b23d1856d8e5402088373029c50fca51518aa62a08a4ebc5808399", 'sha224 (digest_file_hex/file/2)');
is( digest_file_b64('SHA224', 't/data/text-CR.file'), "gLI9GFbY5UAgiDcwKcUPylFRiqYqCKTrxYCDmQ==", 'sha224 (digest_file_b64/file/2)');
+is( digest_file_b64u('SHA224', 't/data/text-CR.file'), "gLI9GFbY5UAgiDcwKcUPylFRiqYqCKTrxYCDmQ", 'sha224 (digest_file_b64u/file/2)');
is( Crypt::Digest::SHA224->new->addfile('t/data/text-CR.file')->hexdigest, "80b23d1856d8e5402088373029c50fca51518aa62a08a4ebc5808399", 'sha224 (OO/file/2)');
{
open(my $fh, '<', 't/data/text-CR.file');
@@ -75,6 +80,7 @@ is( sha224_file_b64('t/data/text-CRLF.file'), "EGzpDhKXDipKFOaQxdUZoUTr7KubUpLzH
is( digest_file('SHA224', 't/data/text-CRLF.file'), pack("H*","106ce90e12970e2a4a14e690c5d519a144ebecab9b5292f31faf3d6e"), 'sha224 (digest_file_raw/file/3)');
is( digest_file_hex('SHA224', 't/data/text-CRLF.file'), "106ce90e12970e2a4a14e690c5d519a144ebecab9b5292f31faf3d6e", 'sha224 (digest_file_hex/file/3)');
is( digest_file_b64('SHA224', 't/data/text-CRLF.file'), "EGzpDhKXDipKFOaQxdUZoUTr7KubUpLzH689bg==", 'sha224 (digest_file_b64/file/3)');
+is( digest_file_b64u('SHA224', 't/data/text-CRLF.file'), "EGzpDhKXDipKFOaQxdUZoUTr7KubUpLzH689bg", 'sha224 (digest_file_b64u/file/3)');
is( Crypt::Digest::SHA224->new->addfile('t/data/text-CRLF.file')->hexdigest, "106ce90e12970e2a4a14e690c5d519a144ebecab9b5292f31faf3d6e", 'sha224 (OO/file/3)');
{
open(my $fh, '<', 't/data/text-CRLF.file');
@@ -89,6 +95,7 @@ is( sha224_file_b64('t/data/text-LF.file'), "uFQUAxY0TY9j+QreYZkYvd+ApLRtoZ849Vo
is( digest_file('SHA224', 't/data/text-LF.file'), pack("H*","b854140316344d8f63f90ade619918bddf80a4b46da19f38f55a3d22"), 'sha224 (digest_file_raw/file/4)');
is( digest_file_hex('SHA224', 't/data/text-LF.file'), "b854140316344d8f63f90ade619918bddf80a4b46da19f38f55a3d22", 'sha224 (digest_file_hex/file/4)');
is( digest_file_b64('SHA224', 't/data/text-LF.file'), "uFQUAxY0TY9j+QreYZkYvd+ApLRtoZ849Vo9Ig==", 'sha224 (digest_file_b64/file/4)');
+is( digest_file_b64u('SHA224', 't/data/text-LF.file'), "uFQUAxY0TY9j-QreYZkYvd-ApLRtoZ849Vo9Ig", 'sha224 (digest_file_b64u/file/4)');
is( Crypt::Digest::SHA224->new->addfile('t/data/text-LF.file')->hexdigest, "b854140316344d8f63f90ade619918bddf80a4b46da19f38f55a3d22", 'sha224 (OO/file/4)');
{
open(my $fh, '<', 't/data/text-LF.file');
diff --git a/t/digest_sha256.t b/t/digest_sha256.t
index 7c3b7d8c..5396c4cd 100644
--- a/t/digest_sha256.t
+++ b/t/digest_sha256.t
@@ -3,10 +3,10 @@
use strict;
use warnings;
-use Test::More tests => 7*3 + 8*4 + 6;
+use Test::More tests => 8*3 + 9*4 + 6;
-use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_file digest_file_hex digest_file_b64 );
-use Crypt::Digest::SHA256 qw( sha256 sha256_hex sha256_b64 sha256_file sha256_file_hex sha256_file_b64 );
+use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u );
+use Crypt::Digest::SHA256 qw( sha256 sha256_hex sha256_b64 sha256_b64u sha256_file sha256_file_hex sha256_file_b64 sha256_file_b64u );
is( Crypt::Digest::hashsize('SHA256'), 32, 'hashsize/1');
is( Crypt::Digest->hashsize('SHA256'), 32, 'hashsize/2');
@@ -22,15 +22,17 @@ is( sha256_b64(""), "47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=", 'sha256 (bas
is( digest_data('SHA256', ""), pack("H*","e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"), 'sha256 (digest_data_raw/1)');
is( digest_data_hex('SHA256', ""), "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", 'sha256 (digest_data_hex/1)');
is( digest_data_b64('SHA256', ""), "47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=", 'sha256 (digest_data_b64/1)');
+is( digest_data_b64u('SHA256', ""), "47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU", 'sha256 (digest_data_b64u/1)');
is( Crypt::Digest::SHA256->new->add("")->hexdigest, "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", 'sha256 (OO/1)');
-is( sha256(123), pack("H*","a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3"), 'sha256 (raw/2)');
-is( sha256_hex(123), "a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3", 'sha256 (hex/2)');
-is( sha256_b64(123), "pmWkWSBCL51Bfkhn79xPuKBKHz//H6B+mY6G9/eieuM=", 'sha256 (base64/2)');
-is( digest_data('SHA256', 123), pack("H*","a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3"), 'sha256 (digest_data_raw/2)');
-is( digest_data_hex('SHA256', 123), "a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3", 'sha256 (digest_data_hex/2)');
-is( digest_data_b64('SHA256', 123), "pmWkWSBCL51Bfkhn79xPuKBKHz//H6B+mY6G9/eieuM=", 'sha256 (digest_data_b64/2)');
-is( Crypt::Digest::SHA256->new->add(123)->hexdigest, "a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3", 'sha256 (OO/2)');
+is( sha256("123"), pack("H*","a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3"), 'sha256 (raw/2)');
+is( sha256_hex("123"), "a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3", 'sha256 (hex/2)');
+is( sha256_b64("123"), "pmWkWSBCL51Bfkhn79xPuKBKHz//H6B+mY6G9/eieuM=", 'sha256 (base64/2)');
+is( digest_data('SHA256', "123"), pack("H*","a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3"), 'sha256 (digest_data_raw/2)');
+is( digest_data_hex('SHA256', "123"), "a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3", 'sha256 (digest_data_hex/2)');
+is( digest_data_b64('SHA256', "123"), "pmWkWSBCL51Bfkhn79xPuKBKHz//H6B+mY6G9/eieuM=", 'sha256 (digest_data_b64/2)');
+is( digest_data_b64u('SHA256', "123"), "pmWkWSBCL51Bfkhn79xPuKBKHz__H6B-mY6G9_eieuM", 'sha256 (digest_data_b64u/2)');
+is( Crypt::Digest::SHA256->new->add("123")->hexdigest, "a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3", 'sha256 (OO/2)');
is( sha256("test\0test\0test\n"), pack("H*","6dedffd4eec5795dec92554802efd8b4a7abc7092f774597abc895c9bc528522"), 'sha256 (raw/3)');
is( sha256_hex("test\0test\0test\n"), "6dedffd4eec5795dec92554802efd8b4a7abc7092f774597abc895c9bc528522", 'sha256 (hex/3)');
@@ -38,6 +40,7 @@ is( sha256_b64("test\0test\0test\n"), "be3/1O7FeV3sklVIAu/YtKerxwkvd0WXq8iVybxSh
is( digest_data('SHA256', "test\0test\0test\n"), pack("H*","6dedffd4eec5795dec92554802efd8b4a7abc7092f774597abc895c9bc528522"), 'sha256 (digest_data_raw/3)');
is( digest_data_hex('SHA256', "test\0test\0test\n"), "6dedffd4eec5795dec92554802efd8b4a7abc7092f774597abc895c9bc528522", 'sha256 (digest_data_hex/3)');
is( digest_data_b64('SHA256', "test\0test\0test\n"), "be3/1O7FeV3sklVIAu/YtKerxwkvd0WXq8iVybxShSI=", 'sha256 (digest_data_b64/3)');
+is( digest_data_b64u('SHA256', "test\0test\0test\n"), "be3_1O7FeV3sklVIAu_YtKerxwkvd0WXq8iVybxShSI", 'sha256 (digest_data_b64u/3)');
is( Crypt::Digest::SHA256->new->add("test\0test\0test\n")->hexdigest, "6dedffd4eec5795dec92554802efd8b4a7abc7092f774597abc895c9bc528522", 'sha256 (OO/3)');
@@ -47,6 +50,7 @@ is( sha256_file_b64('t/data/binary-test.file'), "7vwxcry0Wo6ZIz9fM/rqMS5QiUiF2Wd
is( digest_file('SHA256', 't/data/binary-test.file'), pack("H*","eefc3172bcb45a8e99233f5f33faea312e50894885d9677d9ef530f734a3b343"), 'sha256 (digest_file_raw/file/1)');
is( digest_file_hex('SHA256', 't/data/binary-test.file'), "eefc3172bcb45a8e99233f5f33faea312e50894885d9677d9ef530f734a3b343", 'sha256 (digest_file_hex/file/1)');
is( digest_file_b64('SHA256', 't/data/binary-test.file'), "7vwxcry0Wo6ZIz9fM/rqMS5QiUiF2Wd9nvUw9zSjs0M=", 'sha256 (digest_file_b64/file/1)');
+is( digest_file_b64u('SHA256', 't/data/binary-test.file'), "7vwxcry0Wo6ZIz9fM_rqMS5QiUiF2Wd9nvUw9zSjs0M", 'sha256 (digest_file_b64u/file/1)');
is( Crypt::Digest::SHA256->new->addfile('t/data/binary-test.file')->hexdigest, "eefc3172bcb45a8e99233f5f33faea312e50894885d9677d9ef530f734a3b343", 'sha256 (OO/file/1)');
{
open(my $fh, '<', 't/data/binary-test.file');
@@ -61,6 +65,7 @@ is( sha256_file_b64('t/data/text-CR.file'), "AORtUIQgSnlIGN8G30XnzESJ/XraR2LJWLP
is( digest_file('SHA256', 't/data/text-CR.file'), pack("H*","00e46d5084204a794818df06df45e7cc4489fd7ada4762c958b3c19c86409193"), 'sha256 (digest_file_raw/file/2)');
is( digest_file_hex('SHA256', 't/data/text-CR.file'), "00e46d5084204a794818df06df45e7cc4489fd7ada4762c958b3c19c86409193", 'sha256 (digest_file_hex/file/2)');
is( digest_file_b64('SHA256', 't/data/text-CR.file'), "AORtUIQgSnlIGN8G30XnzESJ/XraR2LJWLPBnIZAkZM=", 'sha256 (digest_file_b64/file/2)');
+is( digest_file_b64u('SHA256', 't/data/text-CR.file'), "AORtUIQgSnlIGN8G30XnzESJ_XraR2LJWLPBnIZAkZM", 'sha256 (digest_file_b64u/file/2)');
is( Crypt::Digest::SHA256->new->addfile('t/data/text-CR.file')->hexdigest, "00e46d5084204a794818df06df45e7cc4489fd7ada4762c958b3c19c86409193", 'sha256 (OO/file/2)');
{
open(my $fh, '<', 't/data/text-CR.file');
@@ -75,6 +80,7 @@ is( sha256_file_b64('t/data/text-CRLF.file'), "LCgDDZvXZtauAj40s6qEJFmT+YQ2zTbbD
is( digest_file('SHA256', 't/data/text-CRLF.file'), pack("H*","2c28030d9bd766d6ae023e34b3aa84245993f98436cd36db0f0ab2294ffe7b6f"), 'sha256 (digest_file_raw/file/3)');
is( digest_file_hex('SHA256', 't/data/text-CRLF.file'), "2c28030d9bd766d6ae023e34b3aa84245993f98436cd36db0f0ab2294ffe7b6f", 'sha256 (digest_file_hex/file/3)');
is( digest_file_b64('SHA256', 't/data/text-CRLF.file'), "LCgDDZvXZtauAj40s6qEJFmT+YQ2zTbbDwqyKU/+e28=", 'sha256 (digest_file_b64/file/3)');
+is( digest_file_b64u('SHA256', 't/data/text-CRLF.file'), "LCgDDZvXZtauAj40s6qEJFmT-YQ2zTbbDwqyKU_-e28", 'sha256 (digest_file_b64u/file/3)');
is( Crypt::Digest::SHA256->new->addfile('t/data/text-CRLF.file')->hexdigest, "2c28030d9bd766d6ae023e34b3aa84245993f98436cd36db0f0ab2294ffe7b6f", 'sha256 (OO/file/3)');
{
open(my $fh, '<', 't/data/text-CRLF.file');
@@ -89,6 +95,7 @@ is( sha256_file_b64('t/data/text-LF.file'), "+Cgkg+bEhMldJlgQVqQGZQyUtMx2SeBb6wZ
is( digest_file('SHA256', 't/data/text-LF.file'), pack("H*","f8282483e6c484c95d26581056a406650c94b4cc7649e05beb0660aa578f345b"), 'sha256 (digest_file_raw/file/4)');
is( digest_file_hex('SHA256', 't/data/text-LF.file'), "f8282483e6c484c95d26581056a406650c94b4cc7649e05beb0660aa578f345b", 'sha256 (digest_file_hex/file/4)');
is( digest_file_b64('SHA256', 't/data/text-LF.file'), "+Cgkg+bEhMldJlgQVqQGZQyUtMx2SeBb6wZgqlePNFs=", 'sha256 (digest_file_b64/file/4)');
+is( digest_file_b64u('SHA256', 't/data/text-LF.file'), "-Cgkg-bEhMldJlgQVqQGZQyUtMx2SeBb6wZgqlePNFs", 'sha256 (digest_file_b64u/file/4)');
is( Crypt::Digest::SHA256->new->addfile('t/data/text-LF.file')->hexdigest, "f8282483e6c484c95d26581056a406650c94b4cc7649e05beb0660aa578f345b", 'sha256 (OO/file/4)');
{
open(my $fh, '<', 't/data/text-LF.file');
diff --git a/t/digest_sha384.t b/t/digest_sha384.t
index 8b03ce20..194d802d 100644
--- a/t/digest_sha384.t
+++ b/t/digest_sha384.t
@@ -3,10 +3,10 @@
use strict;
use warnings;
-use Test::More tests => 7*3 + 8*4 + 6;
+use Test::More tests => 8*3 + 9*4 + 6;
-use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_file digest_file_hex digest_file_b64 );
-use Crypt::Digest::SHA384 qw( sha384 sha384_hex sha384_b64 sha384_file sha384_file_hex sha384_file_b64 );
+use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u );
+use Crypt::Digest::SHA384 qw( sha384 sha384_hex sha384_b64 sha384_b64u sha384_file sha384_file_hex sha384_file_b64 sha384_file_b64u );
is( Crypt::Digest::hashsize('SHA384'), 48, 'hashsize/1');
is( Crypt::Digest->hashsize('SHA384'), 48, 'hashsize/2');
@@ -22,15 +22,17 @@ is( sha384_b64(""), "OLBgp1GsljhM2TJ+sbHjaiH9txEUvgdDTAzHv2P24donTt6/529l+9Ua0vF
is( digest_data('SHA384', ""), pack("H*","38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b"), 'sha384 (digest_data_raw/1)');
is( digest_data_hex('SHA384', ""), "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b", 'sha384 (digest_data_hex/1)');
is( digest_data_b64('SHA384', ""), "OLBgp1GsljhM2TJ+sbHjaiH9txEUvgdDTAzHv2P24donTt6/529l+9Ua0vFImLlb", 'sha384 (digest_data_b64/1)');
+is( digest_data_b64u('SHA384', ""), "OLBgp1GsljhM2TJ-sbHjaiH9txEUvgdDTAzHv2P24donTt6_529l-9Ua0vFImLlb", 'sha384 (digest_data_b64u/1)');
is( Crypt::Digest::SHA384->new->add("")->hexdigest, "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b", 'sha384 (OO/1)');
-is( sha384(123), pack("H*","9a0a82f0c0cf31470d7affede3406cc9aa8410671520b727044eda15b4c25532a9b5cd8aaf9cec4919d76255b6bfb00f"), 'sha384 (raw/2)');
-is( sha384_hex(123), "9a0a82f0c0cf31470d7affede3406cc9aa8410671520b727044eda15b4c25532a9b5cd8aaf9cec4919d76255b6bfb00f", 'sha384 (hex/2)');
-is( sha384_b64(123), "mgqC8MDPMUcNev/t40BsyaqEEGcVILcnBE7aFbTCVTKptc2Kr5zsSRnXYlW2v7AP", 'sha384 (base64/2)');
-is( digest_data('SHA384', 123), pack("H*","9a0a82f0c0cf31470d7affede3406cc9aa8410671520b727044eda15b4c25532a9b5cd8aaf9cec4919d76255b6bfb00f"), 'sha384 (digest_data_raw/2)');
-is( digest_data_hex('SHA384', 123), "9a0a82f0c0cf31470d7affede3406cc9aa8410671520b727044eda15b4c25532a9b5cd8aaf9cec4919d76255b6bfb00f", 'sha384 (digest_data_hex/2)');
-is( digest_data_b64('SHA384', 123), "mgqC8MDPMUcNev/t40BsyaqEEGcVILcnBE7aFbTCVTKptc2Kr5zsSRnXYlW2v7AP", 'sha384 (digest_data_b64/2)');
-is( Crypt::Digest::SHA384->new->add(123)->hexdigest, "9a0a82f0c0cf31470d7affede3406cc9aa8410671520b727044eda15b4c25532a9b5cd8aaf9cec4919d76255b6bfb00f", 'sha384 (OO/2)');
+is( sha384("123"), pack("H*","9a0a82f0c0cf31470d7affede3406cc9aa8410671520b727044eda15b4c25532a9b5cd8aaf9cec4919d76255b6bfb00f"), 'sha384 (raw/2)');
+is( sha384_hex("123"), "9a0a82f0c0cf31470d7affede3406cc9aa8410671520b727044eda15b4c25532a9b5cd8aaf9cec4919d76255b6bfb00f", 'sha384 (hex/2)');
+is( sha384_b64("123"), "mgqC8MDPMUcNev/t40BsyaqEEGcVILcnBE7aFbTCVTKptc2Kr5zsSRnXYlW2v7AP", 'sha384 (base64/2)');
+is( digest_data('SHA384', "123"), pack("H*","9a0a82f0c0cf31470d7affede3406cc9aa8410671520b727044eda15b4c25532a9b5cd8aaf9cec4919d76255b6bfb00f"), 'sha384 (digest_data_raw/2)');
+is( digest_data_hex('SHA384', "123"), "9a0a82f0c0cf31470d7affede3406cc9aa8410671520b727044eda15b4c25532a9b5cd8aaf9cec4919d76255b6bfb00f", 'sha384 (digest_data_hex/2)');
+is( digest_data_b64('SHA384', "123"), "mgqC8MDPMUcNev/t40BsyaqEEGcVILcnBE7aFbTCVTKptc2Kr5zsSRnXYlW2v7AP", 'sha384 (digest_data_b64/2)');
+is( digest_data_b64u('SHA384', "123"), "mgqC8MDPMUcNev_t40BsyaqEEGcVILcnBE7aFbTCVTKptc2Kr5zsSRnXYlW2v7AP", 'sha384 (digest_data_b64u/2)');
+is( Crypt::Digest::SHA384->new->add("123")->hexdigest, "9a0a82f0c0cf31470d7affede3406cc9aa8410671520b727044eda15b4c25532a9b5cd8aaf9cec4919d76255b6bfb00f", 'sha384 (OO/2)');
is( sha384("test\0test\0test\n"), pack("H*","3339da627d4b92fd5af59ce0bdabdbdfea3895d2e698322ee49a37b5bd47245fa015d716921ff689dd9e8c02ba02cea8"), 'sha384 (raw/3)');
is( sha384_hex("test\0test\0test\n"), "3339da627d4b92fd5af59ce0bdabdbdfea3895d2e698322ee49a37b5bd47245fa015d716921ff689dd9e8c02ba02cea8", 'sha384 (hex/3)');
@@ -38,6 +40,7 @@ is( sha384_b64("test\0test\0test\n"), "MznaYn1Lkv1a9Zzgvavb3+o4ldLmmDIu5Jo3tb1HJ
is( digest_data('SHA384', "test\0test\0test\n"), pack("H*","3339da627d4b92fd5af59ce0bdabdbdfea3895d2e698322ee49a37b5bd47245fa015d716921ff689dd9e8c02ba02cea8"), 'sha384 (digest_data_raw/3)');
is( digest_data_hex('SHA384', "test\0test\0test\n"), "3339da627d4b92fd5af59ce0bdabdbdfea3895d2e698322ee49a37b5bd47245fa015d716921ff689dd9e8c02ba02cea8", 'sha384 (digest_data_hex/3)');
is( digest_data_b64('SHA384', "test\0test\0test\n"), "MznaYn1Lkv1a9Zzgvavb3+o4ldLmmDIu5Jo3tb1HJF+gFdcWkh/2id2ejAK6As6o", 'sha384 (digest_data_b64/3)');
+is( digest_data_b64u('SHA384', "test\0test\0test\n"), "MznaYn1Lkv1a9Zzgvavb3-o4ldLmmDIu5Jo3tb1HJF-gFdcWkh_2id2ejAK6As6o", 'sha384 (digest_data_b64u/3)');
is( Crypt::Digest::SHA384->new->add("test\0test\0test\n")->hexdigest, "3339da627d4b92fd5af59ce0bdabdbdfea3895d2e698322ee49a37b5bd47245fa015d716921ff689dd9e8c02ba02cea8", 'sha384 (OO/3)');
@@ -47,6 +50,7 @@ is( sha384_file_b64('t/data/binary-test.file'), "rsVq1y2H9ibyw/3sqTioP/T1GExOq93
is( digest_file('SHA384', 't/data/binary-test.file'), pack("H*","aec56ad72d87f626f2c3fdeca938a83ff4f5184c4eabddcc64ceeec3130d0626c5880ec1a6a7fd1a8c88c7995a45fc49"), 'sha384 (digest_file_raw/file/1)');
is( digest_file_hex('SHA384', 't/data/binary-test.file'), "aec56ad72d87f626f2c3fdeca938a83ff4f5184c4eabddcc64ceeec3130d0626c5880ec1a6a7fd1a8c88c7995a45fc49", 'sha384 (digest_file_hex/file/1)');
is( digest_file_b64('SHA384', 't/data/binary-test.file'), "rsVq1y2H9ibyw/3sqTioP/T1GExOq93MZM7uwxMNBibFiA7Bpqf9GoyIx5laRfxJ", 'sha384 (digest_file_b64/file/1)');
+is( digest_file_b64u('SHA384', 't/data/binary-test.file'), "rsVq1y2H9ibyw_3sqTioP_T1GExOq93MZM7uwxMNBibFiA7Bpqf9GoyIx5laRfxJ", 'sha384 (digest_file_b64u/file/1)');
is( Crypt::Digest::SHA384->new->addfile('t/data/binary-test.file')->hexdigest, "aec56ad72d87f626f2c3fdeca938a83ff4f5184c4eabddcc64ceeec3130d0626c5880ec1a6a7fd1a8c88c7995a45fc49", 'sha384 (OO/file/1)');
{
open(my $fh, '<', 't/data/binary-test.file');
@@ -61,6 +65,7 @@ is( sha384_file_b64('t/data/text-CR.file'), "/RQIdlwLQtPYNulF4h7pL+F7x/aLI8z72q8
is( digest_file('SHA384', 't/data/text-CR.file'), pack("H*","fd1408765c0b42d3d836e945e21ee92fe17bc7f68b23ccfbdaaf3ffd6f6e81732bd8340d1418b18abd2745ef1a0544e6"), 'sha384 (digest_file_raw/file/2)');
is( digest_file_hex('SHA384', 't/data/text-CR.file'), "fd1408765c0b42d3d836e945e21ee92fe17bc7f68b23ccfbdaaf3ffd6f6e81732bd8340d1418b18abd2745ef1a0544e6", 'sha384 (digest_file_hex/file/2)');
is( digest_file_b64('SHA384', 't/data/text-CR.file'), "/RQIdlwLQtPYNulF4h7pL+F7x/aLI8z72q8//W9ugXMr2DQNFBixir0nRe8aBUTm", 'sha384 (digest_file_b64/file/2)');
+is( digest_file_b64u('SHA384', 't/data/text-CR.file'), "_RQIdlwLQtPYNulF4h7pL-F7x_aLI8z72q8__W9ugXMr2DQNFBixir0nRe8aBUTm", 'sha384 (digest_file_b64u/file/2)');
is( Crypt::Digest::SHA384->new->addfile('t/data/text-CR.file')->hexdigest, "fd1408765c0b42d3d836e945e21ee92fe17bc7f68b23ccfbdaaf3ffd6f6e81732bd8340d1418b18abd2745ef1a0544e6", 'sha384 (OO/file/2)');
{
open(my $fh, '<', 't/data/text-CR.file');
@@ -75,6 +80,7 @@ is( sha384_file_b64('t/data/text-CRLF.file'), "8NZDoiwvJf2jbz+DSwW1ySAcUTmzdMSlg
is( digest_file('SHA384', 't/data/text-CRLF.file'), pack("H*","f0d643a22c2f25fda36f3f834b05b5c9201c5139b374c4a581328ce52dd9bababcc7017f96b74eff8f66c097c9156373"), 'sha384 (digest_file_raw/file/3)');
is( digest_file_hex('SHA384', 't/data/text-CRLF.file'), "f0d643a22c2f25fda36f3f834b05b5c9201c5139b374c4a581328ce52dd9bababcc7017f96b74eff8f66c097c9156373", 'sha384 (digest_file_hex/file/3)');
is( digest_file_b64('SHA384', 't/data/text-CRLF.file'), "8NZDoiwvJf2jbz+DSwW1ySAcUTmzdMSlgTKM5S3Zurq8xwF/lrdO/49mwJfJFWNz", 'sha384 (digest_file_b64/file/3)');
+is( digest_file_b64u('SHA384', 't/data/text-CRLF.file'), "8NZDoiwvJf2jbz-DSwW1ySAcUTmzdMSlgTKM5S3Zurq8xwF_lrdO_49mwJfJFWNz", 'sha384 (digest_file_b64u/file/3)');
is( Crypt::Digest::SHA384->new->addfile('t/data/text-CRLF.file')->hexdigest, "f0d643a22c2f25fda36f3f834b05b5c9201c5139b374c4a581328ce52dd9bababcc7017f96b74eff8f66c097c9156373", 'sha384 (OO/file/3)');
{
open(my $fh, '<', 't/data/text-CRLF.file');
@@ -89,6 +95,7 @@ is( sha384_file_b64('t/data/text-LF.file'), "BC6PNhyfvbG/X5vCVJUdymZWYZbsry33hQx
is( digest_file('SHA384', 't/data/text-LF.file'), pack("H*","042e8f361c9fbdb1bf5f9bc254951dca66566196ecaf2df7850c5438338e2c06ea718d8cf3415b77ad56280ba5a3ca1e"), 'sha384 (digest_file_raw/file/4)');
is( digest_file_hex('SHA384', 't/data/text-LF.file'), "042e8f361c9fbdb1bf5f9bc254951dca66566196ecaf2df7850c5438338e2c06ea718d8cf3415b77ad56280ba5a3ca1e", 'sha384 (digest_file_hex/file/4)');
is( digest_file_b64('SHA384', 't/data/text-LF.file'), "BC6PNhyfvbG/X5vCVJUdymZWYZbsry33hQxUODOOLAbqcY2M80Fbd61WKAulo8oe", 'sha384 (digest_file_b64/file/4)');
+is( digest_file_b64u('SHA384', 't/data/text-LF.file'), "BC6PNhyfvbG_X5vCVJUdymZWYZbsry33hQxUODOOLAbqcY2M80Fbd61WKAulo8oe", 'sha384 (digest_file_b64u/file/4)');
is( Crypt::Digest::SHA384->new->addfile('t/data/text-LF.file')->hexdigest, "042e8f361c9fbdb1bf5f9bc254951dca66566196ecaf2df7850c5438338e2c06ea718d8cf3415b77ad56280ba5a3ca1e", 'sha384 (OO/file/4)');
{
open(my $fh, '<', 't/data/text-LF.file');
diff --git a/t/digest_sha512.t b/t/digest_sha512.t
index 398cab08..11609ba9 100644
--- a/t/digest_sha512.t
+++ b/t/digest_sha512.t
@@ -3,10 +3,10 @@
use strict;
use warnings;
-use Test::More tests => 7*3 + 8*4 + 6;
+use Test::More tests => 8*3 + 9*4 + 6;
-use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_file digest_file_hex digest_file_b64 );
-use Crypt::Digest::SHA512 qw( sha512 sha512_hex sha512_b64 sha512_file sha512_file_hex sha512_file_b64 );
+use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u );
+use Crypt::Digest::SHA512 qw( sha512 sha512_hex sha512_b64 sha512_b64u sha512_file sha512_file_hex sha512_file_b64 sha512_file_b64u );
is( Crypt::Digest::hashsize('SHA512'), 64, 'hashsize/1');
is( Crypt::Digest->hashsize('SHA512'), 64, 'hashsize/2');
@@ -22,15 +22,17 @@ is( sha512_b64(""), "z4PhNX7vuL3xVChQ1m2AB9Yg5AULVxXcg/SpIdNs6c5H0NE8XYXysP+DGNK
is( digest_data('SHA512', ""), pack("H*","cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e"), 'sha512 (digest_data_raw/1)');
is( digest_data_hex('SHA512', ""), "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e", 'sha512 (digest_data_hex/1)');
is( digest_data_b64('SHA512', ""), "z4PhNX7vuL3xVChQ1m2AB9Yg5AULVxXcg/SpIdNs6c5H0NE8XYXysP+DGNKHfuwvY7kxvUdBeoGlODJ6+SfaPg==", 'sha512 (digest_data_b64/1)');
+is( digest_data_b64u('SHA512', ""), "z4PhNX7vuL3xVChQ1m2AB9Yg5AULVxXcg_SpIdNs6c5H0NE8XYXysP-DGNKHfuwvY7kxvUdBeoGlODJ6-SfaPg", 'sha512 (digest_data_b64u/1)');
is( Crypt::Digest::SHA512->new->add("")->hexdigest, "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e", 'sha512 (OO/1)');
-is( sha512(123), pack("H*","3c9909afec25354d551dae21590bb26e38d53f2173b8d3dc3eee4c047e7ab1c1eb8b85103e3be7ba613b31bb5c9c36214dc9f14a42fd7a2fdb84856bca5c44c2"), 'sha512 (raw/2)');
-is( sha512_hex(123), "3c9909afec25354d551dae21590bb26e38d53f2173b8d3dc3eee4c047e7ab1c1eb8b85103e3be7ba613b31bb5c9c36214dc9f14a42fd7a2fdb84856bca5c44c2", 'sha512 (hex/2)');
-is( sha512_b64(123), "PJkJr+wlNU1VHa4hWQuybjjVPyFzuNPcPu5MBH56scHri4UQPjvnumE7MbtcnDYhTcnxSkL9ei/bhIVrylxEwg==", 'sha512 (base64/2)');
-is( digest_data('SHA512', 123), pack("H*","3c9909afec25354d551dae21590bb26e38d53f2173b8d3dc3eee4c047e7ab1c1eb8b85103e3be7ba613b31bb5c9c36214dc9f14a42fd7a2fdb84856bca5c44c2"), 'sha512 (digest_data_raw/2)');
-is( digest_data_hex('SHA512', 123), "3c9909afec25354d551dae21590bb26e38d53f2173b8d3dc3eee4c047e7ab1c1eb8b85103e3be7ba613b31bb5c9c36214dc9f14a42fd7a2fdb84856bca5c44c2", 'sha512 (digest_data_hex/2)');
-is( digest_data_b64('SHA512', 123), "PJkJr+wlNU1VHa4hWQuybjjVPyFzuNPcPu5MBH56scHri4UQPjvnumE7MbtcnDYhTcnxSkL9ei/bhIVrylxEwg==", 'sha512 (digest_data_b64/2)');
-is( Crypt::Digest::SHA512->new->add(123)->hexdigest, "3c9909afec25354d551dae21590bb26e38d53f2173b8d3dc3eee4c047e7ab1c1eb8b85103e3be7ba613b31bb5c9c36214dc9f14a42fd7a2fdb84856bca5c44c2", 'sha512 (OO/2)');
+is( sha512("123"), pack("H*","3c9909afec25354d551dae21590bb26e38d53f2173b8d3dc3eee4c047e7ab1c1eb8b85103e3be7ba613b31bb5c9c36214dc9f14a42fd7a2fdb84856bca5c44c2"), 'sha512 (raw/2)');
+is( sha512_hex("123"), "3c9909afec25354d551dae21590bb26e38d53f2173b8d3dc3eee4c047e7ab1c1eb8b85103e3be7ba613b31bb5c9c36214dc9f14a42fd7a2fdb84856bca5c44c2", 'sha512 (hex/2)');
+is( sha512_b64("123"), "PJkJr+wlNU1VHa4hWQuybjjVPyFzuNPcPu5MBH56scHri4UQPjvnumE7MbtcnDYhTcnxSkL9ei/bhIVrylxEwg==", 'sha512 (base64/2)');
+is( digest_data('SHA512', "123"), pack("H*","3c9909afec25354d551dae21590bb26e38d53f2173b8d3dc3eee4c047e7ab1c1eb8b85103e3be7ba613b31bb5c9c36214dc9f14a42fd7a2fdb84856bca5c44c2"), 'sha512 (digest_data_raw/2)');
+is( digest_data_hex('SHA512', "123"), "3c9909afec25354d551dae21590bb26e38d53f2173b8d3dc3eee4c047e7ab1c1eb8b85103e3be7ba613b31bb5c9c36214dc9f14a42fd7a2fdb84856bca5c44c2", 'sha512 (digest_data_hex/2)');
+is( digest_data_b64('SHA512', "123"), "PJkJr+wlNU1VHa4hWQuybjjVPyFzuNPcPu5MBH56scHri4UQPjvnumE7MbtcnDYhTcnxSkL9ei/bhIVrylxEwg==", 'sha512 (digest_data_b64/2)');
+is( digest_data_b64u('SHA512', "123"), "PJkJr-wlNU1VHa4hWQuybjjVPyFzuNPcPu5MBH56scHri4UQPjvnumE7MbtcnDYhTcnxSkL9ei_bhIVrylxEwg", 'sha512 (digest_data_b64u/2)');
+is( Crypt::Digest::SHA512->new->add("123")->hexdigest, "3c9909afec25354d551dae21590bb26e38d53f2173b8d3dc3eee4c047e7ab1c1eb8b85103e3be7ba613b31bb5c9c36214dc9f14a42fd7a2fdb84856bca5c44c2", 'sha512 (OO/2)');
is( sha512("test\0test\0test\n"), pack("H*","23f26f65ca7b6ba3d254f1e218586d43d5349e1a9c33168a9c3a97d70cd7bc924b28d3ccc41df7939b29ea6807e04d34beed2a89c7c38c2276a47a4c45755699"), 'sha512 (raw/3)');
is( sha512_hex("test\0test\0test\n"), "23f26f65ca7b6ba3d254f1e218586d43d5349e1a9c33168a9c3a97d70cd7bc924b28d3ccc41df7939b29ea6807e04d34beed2a89c7c38c2276a47a4c45755699", 'sha512 (hex/3)');
@@ -38,6 +40,7 @@ is( sha512_b64("test\0test\0test\n"), "I/JvZcp7a6PSVPHiGFhtQ9U0nhqcMxaKnDqX1wzXv
is( digest_data('SHA512', "test\0test\0test\n"), pack("H*","23f26f65ca7b6ba3d254f1e218586d43d5349e1a9c33168a9c3a97d70cd7bc924b28d3ccc41df7939b29ea6807e04d34beed2a89c7c38c2276a47a4c45755699"), 'sha512 (digest_data_raw/3)');
is( digest_data_hex('SHA512', "test\0test\0test\n"), "23f26f65ca7b6ba3d254f1e218586d43d5349e1a9c33168a9c3a97d70cd7bc924b28d3ccc41df7939b29ea6807e04d34beed2a89c7c38c2276a47a4c45755699", 'sha512 (digest_data_hex/3)');
is( digest_data_b64('SHA512', "test\0test\0test\n"), "I/JvZcp7a6PSVPHiGFhtQ9U0nhqcMxaKnDqX1wzXvJJLKNPMxB33k5sp6mgH4E00vu0qicfDjCJ2pHpMRXVWmQ==", 'sha512 (digest_data_b64/3)');
+is( digest_data_b64u('SHA512', "test\0test\0test\n"), "I_JvZcp7a6PSVPHiGFhtQ9U0nhqcMxaKnDqX1wzXvJJLKNPMxB33k5sp6mgH4E00vu0qicfDjCJ2pHpMRXVWmQ", 'sha512 (digest_data_b64u/3)');
is( Crypt::Digest::SHA512->new->add("test\0test\0test\n")->hexdigest, "23f26f65ca7b6ba3d254f1e218586d43d5349e1a9c33168a9c3a97d70cd7bc924b28d3ccc41df7939b29ea6807e04d34beed2a89c7c38c2276a47a4c45755699", 'sha512 (OO/3)');
@@ -47,6 +50,7 @@ is( sha512_file_b64('t/data/binary-test.file'), "9jFlKYLwBVYyTR+5B42Bjv7eD2o+BCx
is( digest_file('SHA512', 't/data/binary-test.file'), pack("H*","f631652982f00556324d1fb9078d818efede0f6a3e042c736979543e2b0e4d44e29238fd0d441d4b2c2d16f8597df4912ed752f09438b1dd64efc723204d337a"), 'sha512 (digest_file_raw/file/1)');
is( digest_file_hex('SHA512', 't/data/binary-test.file'), "f631652982f00556324d1fb9078d818efede0f6a3e042c736979543e2b0e4d44e29238fd0d441d4b2c2d16f8597df4912ed752f09438b1dd64efc723204d337a", 'sha512 (digest_file_hex/file/1)');
is( digest_file_b64('SHA512', 't/data/binary-test.file'), "9jFlKYLwBVYyTR+5B42Bjv7eD2o+BCxzaXlUPisOTUTikjj9DUQdSywtFvhZffSRLtdS8JQ4sd1k78cjIE0zeg==", 'sha512 (digest_file_b64/file/1)');
+is( digest_file_b64u('SHA512', 't/data/binary-test.file'), "9jFlKYLwBVYyTR-5B42Bjv7eD2o-BCxzaXlUPisOTUTikjj9DUQdSywtFvhZffSRLtdS8JQ4sd1k78cjIE0zeg", 'sha512 (digest_file_b64u/file/1)');
is( Crypt::Digest::SHA512->new->addfile('t/data/binary-test.file')->hexdigest, "f631652982f00556324d1fb9078d818efede0f6a3e042c736979543e2b0e4d44e29238fd0d441d4b2c2d16f8597df4912ed752f09438b1dd64efc723204d337a", 'sha512 (OO/file/1)');
{
open(my $fh, '<', 't/data/binary-test.file');
@@ -61,6 +65,7 @@ is( sha512_file_b64('t/data/text-CR.file'), "z+p6GsNWgwpOk4+QjinefvzqsrhR9wcipGQ
is( digest_file('SHA512', 't/data/text-CR.file'), pack("H*","cfea7a1ac356830a4e938f908e29de7efceab2b851f70722a464084ac83148de60f19b0e99de581b2fbb3da97b14cd05f06431d7fa12fe38369f3ffa10944a06"), 'sha512 (digest_file_raw/file/2)');
is( digest_file_hex('SHA512', 't/data/text-CR.file'), "cfea7a1ac356830a4e938f908e29de7efceab2b851f70722a464084ac83148de60f19b0e99de581b2fbb3da97b14cd05f06431d7fa12fe38369f3ffa10944a06", 'sha512 (digest_file_hex/file/2)');
is( digest_file_b64('SHA512', 't/data/text-CR.file'), "z+p6GsNWgwpOk4+QjinefvzqsrhR9wcipGQISsgxSN5g8ZsOmd5YGy+7Pal7FM0F8GQx1/oS/jg2nz/6EJRKBg==", 'sha512 (digest_file_b64/file/2)');
+is( digest_file_b64u('SHA512', 't/data/text-CR.file'), "z-p6GsNWgwpOk4-QjinefvzqsrhR9wcipGQISsgxSN5g8ZsOmd5YGy-7Pal7FM0F8GQx1_oS_jg2nz_6EJRKBg", 'sha512 (digest_file_b64u/file/2)');
is( Crypt::Digest::SHA512->new->addfile('t/data/text-CR.file')->hexdigest, "cfea7a1ac356830a4e938f908e29de7efceab2b851f70722a464084ac83148de60f19b0e99de581b2fbb3da97b14cd05f06431d7fa12fe38369f3ffa10944a06", 'sha512 (OO/file/2)');
{
open(my $fh, '<', 't/data/text-CR.file');
@@ -75,6 +80,7 @@ is( sha512_file_b64('t/data/text-CRLF.file'), "FY8l0BXgKV3Bl44KXd+YH2+Z5i61x7fF7
is( digest_file('SHA512', 't/data/text-CRLF.file'), pack("H*","158f25d015e0295dc1978e0a5ddf981f6f99e62eb5c7b7c5ee9ec63f1e2869d26885e760da913ef608974954ae78ea9fbbeea8ce392162198b0fdcdda989a923"), 'sha512 (digest_file_raw/file/3)');
is( digest_file_hex('SHA512', 't/data/text-CRLF.file'), "158f25d015e0295dc1978e0a5ddf981f6f99e62eb5c7b7c5ee9ec63f1e2869d26885e760da913ef608974954ae78ea9fbbeea8ce392162198b0fdcdda989a923", 'sha512 (digest_file_hex/file/3)');
is( digest_file_b64('SHA512', 't/data/text-CRLF.file'), "FY8l0BXgKV3Bl44KXd+YH2+Z5i61x7fF7p7GPx4oadJohedg2pE+9giXSVSueOqfu+6ozjkhYhmLD9zdqYmpIw==", 'sha512 (digest_file_b64/file/3)');
+is( digest_file_b64u('SHA512', 't/data/text-CRLF.file'), "FY8l0BXgKV3Bl44KXd-YH2-Z5i61x7fF7p7GPx4oadJohedg2pE-9giXSVSueOqfu-6ozjkhYhmLD9zdqYmpIw", 'sha512 (digest_file_b64u/file/3)');
is( Crypt::Digest::SHA512->new->addfile('t/data/text-CRLF.file')->hexdigest, "158f25d015e0295dc1978e0a5ddf981f6f99e62eb5c7b7c5ee9ec63f1e2869d26885e760da913ef608974954ae78ea9fbbeea8ce392162198b0fdcdda989a923", 'sha512 (OO/file/3)');
{
open(my $fh, '<', 't/data/text-CRLF.file');
@@ -89,6 +95,7 @@ is( sha512_file_b64('t/data/text-LF.file'), "4Sf8EjBZ8FVNwZF67QdqnIidFx3Jzb39cFZ
is( digest_file('SHA512', 't/data/text-LF.file'), pack("H*","e127fc123059f0554dc1917aed076a9c889d171dc9cdbdfd705641fa368fde66af86e0f8d14a7d3e72571d2bfd25a060ef70e4a84c1d3bb1d0d7524ca8bfaa7a"), 'sha512 (digest_file_raw/file/4)');
is( digest_file_hex('SHA512', 't/data/text-LF.file'), "e127fc123059f0554dc1917aed076a9c889d171dc9cdbdfd705641fa368fde66af86e0f8d14a7d3e72571d2bfd25a060ef70e4a84c1d3bb1d0d7524ca8bfaa7a", 'sha512 (digest_file_hex/file/4)');
is( digest_file_b64('SHA512', 't/data/text-LF.file'), "4Sf8EjBZ8FVNwZF67QdqnIidFx3Jzb39cFZB+jaP3mavhuD40Up9PnJXHSv9JaBg73DkqEwdO7HQ11JMqL+qeg==", 'sha512 (digest_file_b64/file/4)');
+is( digest_file_b64u('SHA512', 't/data/text-LF.file'), "4Sf8EjBZ8FVNwZF67QdqnIidFx3Jzb39cFZB-jaP3mavhuD40Up9PnJXHSv9JaBg73DkqEwdO7HQ11JMqL-qeg", 'sha512 (digest_file_b64u/file/4)');
is( Crypt::Digest::SHA512->new->addfile('t/data/text-LF.file')->hexdigest, "e127fc123059f0554dc1917aed076a9c889d171dc9cdbdfd705641fa368fde66af86e0f8d14a7d3e72571d2bfd25a060ef70e4a84c1d3bb1d0d7524ca8bfaa7a", 'sha512 (OO/file/4)');
{
open(my $fh, '<', 't/data/text-LF.file');
diff --git a/t/digest_tiger192.t b/t/digest_tiger192.t
index bf7a4271..4689b2da 100644
--- a/t/digest_tiger192.t
+++ b/t/digest_tiger192.t
@@ -3,10 +3,10 @@
use strict;
use warnings;
-use Test::More tests => 7*3 + 8*4 + 6;
+use Test::More tests => 8*3 + 9*4 + 6;
-use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_file digest_file_hex digest_file_b64 );
-use Crypt::Digest::Tiger192 qw( tiger192 tiger192_hex tiger192_b64 tiger192_file tiger192_file_hex tiger192_file_b64 );
+use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u );
+use Crypt::Digest::Tiger192 qw( tiger192 tiger192_hex tiger192_b64 tiger192_b64u tiger192_file tiger192_file_hex tiger192_file_b64 tiger192_file_b64u );
is( Crypt::Digest::hashsize('Tiger192'), 24, 'hashsize/1');
is( Crypt::Digest->hashsize('Tiger192'), 24, 'hashsize/2');
@@ -22,15 +22,17 @@ is( tiger192_b64(""), "MpOsYwwT8CRfkruxdm4WFnpOWEkt3nPz", 'tiger192 (base64/1)')
is( digest_data('Tiger192', ""), pack("H*","3293ac630c13f0245f92bbb1766e16167a4e58492dde73f3"), 'tiger192 (digest_data_raw/1)');
is( digest_data_hex('Tiger192', ""), "3293ac630c13f0245f92bbb1766e16167a4e58492dde73f3", 'tiger192 (digest_data_hex/1)');
is( digest_data_b64('Tiger192', ""), "MpOsYwwT8CRfkruxdm4WFnpOWEkt3nPz", 'tiger192 (digest_data_b64/1)');
+is( digest_data_b64u('Tiger192', ""), "MpOsYwwT8CRfkruxdm4WFnpOWEkt3nPz", 'tiger192 (digest_data_b64u/1)');
is( Crypt::Digest::Tiger192->new->add("")->hexdigest, "3293ac630c13f0245f92bbb1766e16167a4e58492dde73f3", 'tiger192 (OO/1)');
-is( tiger192(123), pack("H*","a86807bb96a714fe9b22425893e698334cd71e36b0eef2be"), 'tiger192 (raw/2)');
-is( tiger192_hex(123), "a86807bb96a714fe9b22425893e698334cd71e36b0eef2be", 'tiger192 (hex/2)');
-is( tiger192_b64(123), "qGgHu5anFP6bIkJYk+aYM0zXHjaw7vK+", 'tiger192 (base64/2)');
-is( digest_data('Tiger192', 123), pack("H*","a86807bb96a714fe9b22425893e698334cd71e36b0eef2be"), 'tiger192 (digest_data_raw/2)');
-is( digest_data_hex('Tiger192', 123), "a86807bb96a714fe9b22425893e698334cd71e36b0eef2be", 'tiger192 (digest_data_hex/2)');
-is( digest_data_b64('Tiger192', 123), "qGgHu5anFP6bIkJYk+aYM0zXHjaw7vK+", 'tiger192 (digest_data_b64/2)');
-is( Crypt::Digest::Tiger192->new->add(123)->hexdigest, "a86807bb96a714fe9b22425893e698334cd71e36b0eef2be", 'tiger192 (OO/2)');
+is( tiger192("123"), pack("H*","a86807bb96a714fe9b22425893e698334cd71e36b0eef2be"), 'tiger192 (raw/2)');
+is( tiger192_hex("123"), "a86807bb96a714fe9b22425893e698334cd71e36b0eef2be", 'tiger192 (hex/2)');
+is( tiger192_b64("123"), "qGgHu5anFP6bIkJYk+aYM0zXHjaw7vK+", 'tiger192 (base64/2)');
+is( digest_data('Tiger192', "123"), pack("H*","a86807bb96a714fe9b22425893e698334cd71e36b0eef2be"), 'tiger192 (digest_data_raw/2)');
+is( digest_data_hex('Tiger192', "123"), "a86807bb96a714fe9b22425893e698334cd71e36b0eef2be", 'tiger192 (digest_data_hex/2)');
+is( digest_data_b64('Tiger192', "123"), "qGgHu5anFP6bIkJYk+aYM0zXHjaw7vK+", 'tiger192 (digest_data_b64/2)');
+is( digest_data_b64u('Tiger192', "123"), "qGgHu5anFP6bIkJYk-aYM0zXHjaw7vK-", 'tiger192 (digest_data_b64u/2)');
+is( Crypt::Digest::Tiger192->new->add("123")->hexdigest, "a86807bb96a714fe9b22425893e698334cd71e36b0eef2be", 'tiger192 (OO/2)');
is( tiger192("test\0test\0test\n"), pack("H*","4d8ed1a51a0f2bcb0f74ae5dee0c7b0a804d98ba9e9a74a1"), 'tiger192 (raw/3)');
is( tiger192_hex("test\0test\0test\n"), "4d8ed1a51a0f2bcb0f74ae5dee0c7b0a804d98ba9e9a74a1", 'tiger192 (hex/3)');
@@ -38,6 +40,7 @@ is( tiger192_b64("test\0test\0test\n"), "TY7RpRoPK8sPdK5d7gx7CoBNmLqemnSh", 'tig
is( digest_data('Tiger192', "test\0test\0test\n"), pack("H*","4d8ed1a51a0f2bcb0f74ae5dee0c7b0a804d98ba9e9a74a1"), 'tiger192 (digest_data_raw/3)');
is( digest_data_hex('Tiger192', "test\0test\0test\n"), "4d8ed1a51a0f2bcb0f74ae5dee0c7b0a804d98ba9e9a74a1", 'tiger192 (digest_data_hex/3)');
is( digest_data_b64('Tiger192', "test\0test\0test\n"), "TY7RpRoPK8sPdK5d7gx7CoBNmLqemnSh", 'tiger192 (digest_data_b64/3)');
+is( digest_data_b64u('Tiger192', "test\0test\0test\n"), "TY7RpRoPK8sPdK5d7gx7CoBNmLqemnSh", 'tiger192 (digest_data_b64u/3)');
is( Crypt::Digest::Tiger192->new->add("test\0test\0test\n")->hexdigest, "4d8ed1a51a0f2bcb0f74ae5dee0c7b0a804d98ba9e9a74a1", 'tiger192 (OO/3)');
@@ -47,6 +50,7 @@ is( tiger192_file_b64('t/data/binary-test.file'), "h//5EspUl971Whp7XHBa0DelNmBDL
is( digest_file('Tiger192', 't/data/binary-test.file'), pack("H*","87fff912ca5497def55a1a7b5c705ad037a53660432e1d63"), 'tiger192 (digest_file_raw/file/1)');
is( digest_file_hex('Tiger192', 't/data/binary-test.file'), "87fff912ca5497def55a1a7b5c705ad037a53660432e1d63", 'tiger192 (digest_file_hex/file/1)');
is( digest_file_b64('Tiger192', 't/data/binary-test.file'), "h//5EspUl971Whp7XHBa0DelNmBDLh1j", 'tiger192 (digest_file_b64/file/1)');
+is( digest_file_b64u('Tiger192', 't/data/binary-test.file'), "h__5EspUl971Whp7XHBa0DelNmBDLh1j", 'tiger192 (digest_file_b64u/file/1)');
is( Crypt::Digest::Tiger192->new->addfile('t/data/binary-test.file')->hexdigest, "87fff912ca5497def55a1a7b5c705ad037a53660432e1d63", 'tiger192 (OO/file/1)');
{
open(my $fh, '<', 't/data/binary-test.file');
@@ -61,6 +65,7 @@ is( tiger192_file_b64('t/data/text-CR.file'), "Oueh7WRz6ASfoS3xclbo8kV41o6dzkR6"
is( digest_file('Tiger192', 't/data/text-CR.file'), pack("H*","3ae7a1ed6473e8049fa12df17256e8f24578d68e9dce447a"), 'tiger192 (digest_file_raw/file/2)');
is( digest_file_hex('Tiger192', 't/data/text-CR.file'), "3ae7a1ed6473e8049fa12df17256e8f24578d68e9dce447a", 'tiger192 (digest_file_hex/file/2)');
is( digest_file_b64('Tiger192', 't/data/text-CR.file'), "Oueh7WRz6ASfoS3xclbo8kV41o6dzkR6", 'tiger192 (digest_file_b64/file/2)');
+is( digest_file_b64u('Tiger192', 't/data/text-CR.file'), "Oueh7WRz6ASfoS3xclbo8kV41o6dzkR6", 'tiger192 (digest_file_b64u/file/2)');
is( Crypt::Digest::Tiger192->new->addfile('t/data/text-CR.file')->hexdigest, "3ae7a1ed6473e8049fa12df17256e8f24578d68e9dce447a", 'tiger192 (OO/file/2)');
{
open(my $fh, '<', 't/data/text-CR.file');
@@ -75,6 +80,7 @@ is( tiger192_file_b64('t/data/text-CRLF.file'), "HTPTkvEA3OhU7B5rcb9YtXJCcanr/Hu
is( digest_file('Tiger192', 't/data/text-CRLF.file'), pack("H*","1d33d392f100dce854ec1e6b71bf58b5724271a9ebfc7b83"), 'tiger192 (digest_file_raw/file/3)');
is( digest_file_hex('Tiger192', 't/data/text-CRLF.file'), "1d33d392f100dce854ec1e6b71bf58b5724271a9ebfc7b83", 'tiger192 (digest_file_hex/file/3)');
is( digest_file_b64('Tiger192', 't/data/text-CRLF.file'), "HTPTkvEA3OhU7B5rcb9YtXJCcanr/HuD", 'tiger192 (digest_file_b64/file/3)');
+is( digest_file_b64u('Tiger192', 't/data/text-CRLF.file'), "HTPTkvEA3OhU7B5rcb9YtXJCcanr_HuD", 'tiger192 (digest_file_b64u/file/3)');
is( Crypt::Digest::Tiger192->new->addfile('t/data/text-CRLF.file')->hexdigest, "1d33d392f100dce854ec1e6b71bf58b5724271a9ebfc7b83", 'tiger192 (OO/file/3)');
{
open(my $fh, '<', 't/data/text-CRLF.file');
@@ -89,6 +95,7 @@ is( tiger192_file_b64('t/data/text-LF.file'), "T0tKhXeDOSa+yVtvWdm+JIQRFgWTN1ug"
is( digest_file('Tiger192', 't/data/text-LF.file'), pack("H*","4f4b4a8577833926bec95b6f59d9be248411160593375ba0"), 'tiger192 (digest_file_raw/file/4)');
is( digest_file_hex('Tiger192', 't/data/text-LF.file'), "4f4b4a8577833926bec95b6f59d9be248411160593375ba0", 'tiger192 (digest_file_hex/file/4)');
is( digest_file_b64('Tiger192', 't/data/text-LF.file'), "T0tKhXeDOSa+yVtvWdm+JIQRFgWTN1ug", 'tiger192 (digest_file_b64/file/4)');
+is( digest_file_b64u('Tiger192', 't/data/text-LF.file'), "T0tKhXeDOSa-yVtvWdm-JIQRFgWTN1ug", 'tiger192 (digest_file_b64u/file/4)');
is( Crypt::Digest::Tiger192->new->addfile('t/data/text-LF.file')->hexdigest, "4f4b4a8577833926bec95b6f59d9be248411160593375ba0", 'tiger192 (OO/file/4)');
{
open(my $fh, '<', 't/data/text-LF.file');
diff --git a/t/digest_whirlpool.t b/t/digest_whirlpool.t
index a6339d36..9bb40db5 100644
--- a/t/digest_whirlpool.t
+++ b/t/digest_whirlpool.t
@@ -3,10 +3,10 @@
use strict;
use warnings;
-use Test::More tests => 7*3 + 8*4 + 6;
+use Test::More tests => 8*3 + 9*4 + 6;
-use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_file digest_file_hex digest_file_b64 );
-use Crypt::Digest::Whirlpool qw( whirlpool whirlpool_hex whirlpool_b64 whirlpool_file whirlpool_file_hex whirlpool_file_b64 );
+use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u );
+use Crypt::Digest::Whirlpool qw( whirlpool whirlpool_hex whirlpool_b64 whirlpool_b64u whirlpool_file whirlpool_file_hex whirlpool_file_b64 whirlpool_file_b64u );
is( Crypt::Digest::hashsize('Whirlpool'), 64, 'hashsize/1');
is( Crypt::Digest->hashsize('Whirlpool'), 64, 'hashsize/2');
@@ -22,15 +22,17 @@ is( whirlpool_b64(""), "Gfph11UipGabROOcHS4XJsUwIyEw1Af4mv7glkmX96c+g75piyiP68+I
is( digest_data('Whirlpool', ""), pack("H*","19fa61d75522a4669b44e39c1d2e1726c530232130d407f89afee0964997f7a73e83be698b288febcf88e3e03c4f0757ea8964e59b63d93708b138cc42a66eb3"), 'whirlpool (digest_data_raw/1)');
is( digest_data_hex('Whirlpool', ""), "19fa61d75522a4669b44e39c1d2e1726c530232130d407f89afee0964997f7a73e83be698b288febcf88e3e03c4f0757ea8964e59b63d93708b138cc42a66eb3", 'whirlpool (digest_data_hex/1)');
is( digest_data_b64('Whirlpool', ""), "Gfph11UipGabROOcHS4XJsUwIyEw1Af4mv7glkmX96c+g75piyiP68+I4+A8TwdX6olk5Ztj2TcIsTjMQqZusw==", 'whirlpool (digest_data_b64/1)');
+is( digest_data_b64u('Whirlpool', ""), "Gfph11UipGabROOcHS4XJsUwIyEw1Af4mv7glkmX96c-g75piyiP68-I4-A8TwdX6olk5Ztj2TcIsTjMQqZusw", 'whirlpool (digest_data_b64u/1)');
is( Crypt::Digest::Whirlpool->new->add("")->hexdigest, "19fa61d75522a4669b44e39c1d2e1726c530232130d407f89afee0964997f7a73e83be698b288febcf88e3e03c4f0757ea8964e59b63d93708b138cc42a66eb3", 'whirlpool (OO/1)');
-is( whirlpool(123), pack("H*","344907e89b981caf221d05f597eb57a6af408f15f4dd7895bbd1b96a2938ec24a7dcf23acb94ece0b6d7b0640358bc56bdb448194b9305311aff038a834a079f"), 'whirlpool (raw/2)');
-is( whirlpool_hex(123), "344907e89b981caf221d05f597eb57a6af408f15f4dd7895bbd1b96a2938ec24a7dcf23acb94ece0b6d7b0640358bc56bdb448194b9305311aff038a834a079f", 'whirlpool (hex/2)');
-is( whirlpool_b64(123), "NEkH6JuYHK8iHQX1l+tXpq9AjxX03XiVu9G5aik47CSn3PI6y5Ts4LbXsGQDWLxWvbRIGUuTBTEa/wOKg0oHnw==", 'whirlpool (base64/2)');
-is( digest_data('Whirlpool', 123), pack("H*","344907e89b981caf221d05f597eb57a6af408f15f4dd7895bbd1b96a2938ec24a7dcf23acb94ece0b6d7b0640358bc56bdb448194b9305311aff038a834a079f"), 'whirlpool (digest_data_raw/2)');
-is( digest_data_hex('Whirlpool', 123), "344907e89b981caf221d05f597eb57a6af408f15f4dd7895bbd1b96a2938ec24a7dcf23acb94ece0b6d7b0640358bc56bdb448194b9305311aff038a834a079f", 'whirlpool (digest_data_hex/2)');
-is( digest_data_b64('Whirlpool', 123), "NEkH6JuYHK8iHQX1l+tXpq9AjxX03XiVu9G5aik47CSn3PI6y5Ts4LbXsGQDWLxWvbRIGUuTBTEa/wOKg0oHnw==", 'whirlpool (digest_data_b64/2)');
-is( Crypt::Digest::Whirlpool->new->add(123)->hexdigest, "344907e89b981caf221d05f597eb57a6af408f15f4dd7895bbd1b96a2938ec24a7dcf23acb94ece0b6d7b0640358bc56bdb448194b9305311aff038a834a079f", 'whirlpool (OO/2)');
+is( whirlpool("123"), pack("H*","344907e89b981caf221d05f597eb57a6af408f15f4dd7895bbd1b96a2938ec24a7dcf23acb94ece0b6d7b0640358bc56bdb448194b9305311aff038a834a079f"), 'whirlpool (raw/2)');
+is( whirlpool_hex("123"), "344907e89b981caf221d05f597eb57a6af408f15f4dd7895bbd1b96a2938ec24a7dcf23acb94ece0b6d7b0640358bc56bdb448194b9305311aff038a834a079f", 'whirlpool (hex/2)');
+is( whirlpool_b64("123"), "NEkH6JuYHK8iHQX1l+tXpq9AjxX03XiVu9G5aik47CSn3PI6y5Ts4LbXsGQDWLxWvbRIGUuTBTEa/wOKg0oHnw==", 'whirlpool (base64/2)');
+is( digest_data('Whirlpool', "123"), pack("H*","344907e89b981caf221d05f597eb57a6af408f15f4dd7895bbd1b96a2938ec24a7dcf23acb94ece0b6d7b0640358bc56bdb448194b9305311aff038a834a079f"), 'whirlpool (digest_data_raw/2)');
+is( digest_data_hex('Whirlpool', "123"), "344907e89b981caf221d05f597eb57a6af408f15f4dd7895bbd1b96a2938ec24a7dcf23acb94ece0b6d7b0640358bc56bdb448194b9305311aff038a834a079f", 'whirlpool (digest_data_hex/2)');
+is( digest_data_b64('Whirlpool', "123"), "NEkH6JuYHK8iHQX1l+tXpq9AjxX03XiVu9G5aik47CSn3PI6y5Ts4LbXsGQDWLxWvbRIGUuTBTEa/wOKg0oHnw==", 'whirlpool (digest_data_b64/2)');
+is( digest_data_b64u('Whirlpool', "123"), "NEkH6JuYHK8iHQX1l-tXpq9AjxX03XiVu9G5aik47CSn3PI6y5Ts4LbXsGQDWLxWvbRIGUuTBTEa_wOKg0oHnw", 'whirlpool (digest_data_b64u/2)');
+is( Crypt::Digest::Whirlpool->new->add("123")->hexdigest, "344907e89b981caf221d05f597eb57a6af408f15f4dd7895bbd1b96a2938ec24a7dcf23acb94ece0b6d7b0640358bc56bdb448194b9305311aff038a834a079f", 'whirlpool (OO/2)');
is( whirlpool("test\0test\0test\n"), pack("H*","3dbd3f37a844611382f9fc757b3ba299d1c250fa1f2fdd69f06b113f28e1c3756f5cc551996932dd8802f335db6789002f06e3ff11eb19c8715113e588bc39c7"), 'whirlpool (raw/3)');
is( whirlpool_hex("test\0test\0test\n"), "3dbd3f37a844611382f9fc757b3ba299d1c250fa1f2fdd69f06b113f28e1c3756f5cc551996932dd8802f335db6789002f06e3ff11eb19c8715113e588bc39c7", 'whirlpool (hex/3)');
@@ -38,6 +40,7 @@ is( whirlpool_b64("test\0test\0test\n"), "Pb0/N6hEYROC+fx1ezuimdHCUPofL91p8GsRPy
is( digest_data('Whirlpool', "test\0test\0test\n"), pack("H*","3dbd3f37a844611382f9fc757b3ba299d1c250fa1f2fdd69f06b113f28e1c3756f5cc551996932dd8802f335db6789002f06e3ff11eb19c8715113e588bc39c7"), 'whirlpool (digest_data_raw/3)');
is( digest_data_hex('Whirlpool', "test\0test\0test\n"), "3dbd3f37a844611382f9fc757b3ba299d1c250fa1f2fdd69f06b113f28e1c3756f5cc551996932dd8802f335db6789002f06e3ff11eb19c8715113e588bc39c7", 'whirlpool (digest_data_hex/3)');
is( digest_data_b64('Whirlpool', "test\0test\0test\n"), "Pb0/N6hEYROC+fx1ezuimdHCUPofL91p8GsRPyjhw3VvXMVRmWky3YgC8zXbZ4kALwbj/xHrGchxURPliLw5xw==", 'whirlpool (digest_data_b64/3)');
+is( digest_data_b64u('Whirlpool', "test\0test\0test\n"), "Pb0_N6hEYROC-fx1ezuimdHCUPofL91p8GsRPyjhw3VvXMVRmWky3YgC8zXbZ4kALwbj_xHrGchxURPliLw5xw", 'whirlpool (digest_data_b64u/3)');
is( Crypt::Digest::Whirlpool->new->add("test\0test\0test\n")->hexdigest, "3dbd3f37a844611382f9fc757b3ba299d1c250fa1f2fdd69f06b113f28e1c3756f5cc551996932dd8802f335db6789002f06e3ff11eb19c8715113e588bc39c7", 'whirlpool (OO/3)');
@@ -47,6 +50,7 @@ is( whirlpool_file_b64('t/data/binary-test.file'), "qEs15wI3HXqWxTMnR9UhCkJVEtLW
is( digest_file('Whirlpool', 't/data/binary-test.file'), pack("H*","a84b35e702371d7a96c5332747d5210a425512d2d6c5ec5eb8851718d3939faf0b84d3c1c6b1071e6c6e54efc96ea7b3a46f9019554fabb0d4a2924ffa5dff8d"), 'whirlpool (digest_file_raw/file/1)');
is( digest_file_hex('Whirlpool', 't/data/binary-test.file'), "a84b35e702371d7a96c5332747d5210a425512d2d6c5ec5eb8851718d3939faf0b84d3c1c6b1071e6c6e54efc96ea7b3a46f9019554fabb0d4a2924ffa5dff8d", 'whirlpool (digest_file_hex/file/1)');
is( digest_file_b64('Whirlpool', 't/data/binary-test.file'), "qEs15wI3HXqWxTMnR9UhCkJVEtLWxexeuIUXGNOTn68LhNPBxrEHHmxuVO/JbqezpG+QGVVPq7DUopJP+l3/jQ==", 'whirlpool (digest_file_b64/file/1)');
+is( digest_file_b64u('Whirlpool', 't/data/binary-test.file'), "qEs15wI3HXqWxTMnR9UhCkJVEtLWxexeuIUXGNOTn68LhNPBxrEHHmxuVO_JbqezpG-QGVVPq7DUopJP-l3_jQ", 'whirlpool (digest_file_b64u/file/1)');
is( Crypt::Digest::Whirlpool->new->addfile('t/data/binary-test.file')->hexdigest, "a84b35e702371d7a96c5332747d5210a425512d2d6c5ec5eb8851718d3939faf0b84d3c1c6b1071e6c6e54efc96ea7b3a46f9019554fabb0d4a2924ffa5dff8d", 'whirlpool (OO/file/1)');
{
open(my $fh, '<', 't/data/binary-test.file');
@@ -61,6 +65,7 @@ is( whirlpool_file_b64('t/data/text-CR.file'), "KEb3+Mcx/HfAhQN7cb7Akb33cvR1nAZ2
is( digest_file('Whirlpool', 't/data/text-CR.file'), pack("H*","2846f7f8c731fc77c085037b71bec091bdf772f4759c06760bea914ef6f1e0cfb24548828650bb7487d6a1e96ade543268bd01e90daec95dbe9ef817dc668bd0"), 'whirlpool (digest_file_raw/file/2)');
is( digest_file_hex('Whirlpool', 't/data/text-CR.file'), "2846f7f8c731fc77c085037b71bec091bdf772f4759c06760bea914ef6f1e0cfb24548828650bb7487d6a1e96ade543268bd01e90daec95dbe9ef817dc668bd0", 'whirlpool (digest_file_hex/file/2)');
is( digest_file_b64('Whirlpool', 't/data/text-CR.file'), "KEb3+Mcx/HfAhQN7cb7Akb33cvR1nAZ2C+qRTvbx4M+yRUiChlC7dIfWoelq3lQyaL0B6Q2uyV2+nvgX3GaL0A==", 'whirlpool (digest_file_b64/file/2)');
+is( digest_file_b64u('Whirlpool', 't/data/text-CR.file'), "KEb3-Mcx_HfAhQN7cb7Akb33cvR1nAZ2C-qRTvbx4M-yRUiChlC7dIfWoelq3lQyaL0B6Q2uyV2-nvgX3GaL0A", 'whirlpool (digest_file_b64u/file/2)');
is( Crypt::Digest::Whirlpool->new->addfile('t/data/text-CR.file')->hexdigest, "2846f7f8c731fc77c085037b71bec091bdf772f4759c06760bea914ef6f1e0cfb24548828650bb7487d6a1e96ade543268bd01e90daec95dbe9ef817dc668bd0", 'whirlpool (OO/file/2)');
{
open(my $fh, '<', 't/data/text-CR.file');
@@ -75,6 +80,7 @@ is( whirlpool_file_b64('t/data/text-CRLF.file'), "XQnIy/5/aPXjdKrDV+4O5rOsy+eUsb
is( digest_file('Whirlpool', 't/data/text-CRLF.file'), pack("H*","5d09c8cbfe7f68f5e374aac357ee0ee6b3accbe794b1b826b8a72a4f6771f86cdb65604325e09c547f6eeb71a25e94d336186ec045255c152d52fb57d394d9cf"), 'whirlpool (digest_file_raw/file/3)');
is( digest_file_hex('Whirlpool', 't/data/text-CRLF.file'), "5d09c8cbfe7f68f5e374aac357ee0ee6b3accbe794b1b826b8a72a4f6771f86cdb65604325e09c547f6eeb71a25e94d336186ec045255c152d52fb57d394d9cf", 'whirlpool (digest_file_hex/file/3)');
is( digest_file_b64('Whirlpool', 't/data/text-CRLF.file'), "XQnIy/5/aPXjdKrDV+4O5rOsy+eUsbgmuKcqT2dx+GzbZWBDJeCcVH9u63GiXpTTNhhuwEUlXBUtUvtX05TZzw==", 'whirlpool (digest_file_b64/file/3)');
+is( digest_file_b64u('Whirlpool', 't/data/text-CRLF.file'), "XQnIy_5_aPXjdKrDV-4O5rOsy-eUsbgmuKcqT2dx-GzbZWBDJeCcVH9u63GiXpTTNhhuwEUlXBUtUvtX05TZzw", 'whirlpool (digest_file_b64u/file/3)');
is( Crypt::Digest::Whirlpool->new->addfile('t/data/text-CRLF.file')->hexdigest, "5d09c8cbfe7f68f5e374aac357ee0ee6b3accbe794b1b826b8a72a4f6771f86cdb65604325e09c547f6eeb71a25e94d336186ec045255c152d52fb57d394d9cf", 'whirlpool (OO/file/3)');
{
open(my $fh, '<', 't/data/text-CRLF.file');
@@ -89,6 +95,7 @@ is( whirlpool_file_b64('t/data/text-LF.file'), "BbL14ogzpzTcjcdj4SAw+3jbrF/ZcJvD
is( digest_file('Whirlpool', 't/data/text-LF.file'), pack("H*","05b2f5e28833a734dc8dc763e12030fb78dbac5fd9709bc30315ea81507d3b338697c1c58474abeb41f110444381000bffda176a0fa0b12b1b65ccfd9f6d19b0"), 'whirlpool (digest_file_raw/file/4)');
is( digest_file_hex('Whirlpool', 't/data/text-LF.file'), "05b2f5e28833a734dc8dc763e12030fb78dbac5fd9709bc30315ea81507d3b338697c1c58474abeb41f110444381000bffda176a0fa0b12b1b65ccfd9f6d19b0", 'whirlpool (digest_file_hex/file/4)');
is( digest_file_b64('Whirlpool', 't/data/text-LF.file'), "BbL14ogzpzTcjcdj4SAw+3jbrF/ZcJvDAxXqgVB9OzOGl8HFhHSr60HxEERDgQAL/9oXag+gsSsbZcz9n20ZsA==", 'whirlpool (digest_file_b64/file/4)');
+is( digest_file_b64u('Whirlpool', 't/data/text-LF.file'), "BbL14ogzpzTcjcdj4SAw-3jbrF_ZcJvDAxXqgVB9OzOGl8HFhHSr60HxEERDgQAL_9oXag-gsSsbZcz9n20ZsA", 'whirlpool (digest_file_b64u/file/4)');
is( Crypt::Digest::Whirlpool->new->addfile('t/data/text-LF.file')->hexdigest, "05b2f5e28833a734dc8dc763e12030fb78dbac5fd9709bc30315ea81507d3b338697c1c58474abeb41f110444381000bffda176a0fa0b12b1b65ccfd9f6d19b0", 'whirlpool (OO/file/4)');
{
open(my $fh, '<', 't/data/text-LF.file');
diff --git a/t/mac_f9.t b/t/mac_f9.t
index 41e7f9cf..340268b3 100644
--- a/t/mac_f9.t
+++ b/t/mac_f9.t
@@ -5,67 +5,79 @@ use warnings;
use Test::More;
-use Crypt::Mac::F9 qw( f9 f9_hex f9_b64 );
+use Crypt::Mac::F9 qw( f9 f9_hex f9_b64 f9_b64u );
is( unpack('H*', Crypt::Mac::F9->new('AES','1234567890123456')->add("")->mac), 'd7d52d77795c5057977939f22fcce305', 'F9/oo+raw/1');
is( Crypt::Mac::F9->new('AES','1234567890123456')->add("")->hexmac, 'd7d52d77795c5057977939f22fcce305', 'F9/oo+hex/1');
is( unpack('H*', f9('AES','1234567890123456',"")), 'd7d52d77795c5057977939f22fcce305', 'F9/func+raw/1');
is( f9_hex('AES','1234567890123456',""), 'd7d52d77795c5057977939f22fcce305', 'F9/func+hex/1');
is( f9_b64('AES','1234567890123456',""), '19Utd3lcUFeXeTnyL8zjBQ==', 'F9/func+b64/1');
+is( f9_b64u('AES','1234567890123456',""), '19Utd3lcUFeXeTnyL8zjBQ', 'F9/func+b64u/1');
is( unpack('H*', Crypt::Mac::F9->new('AES','12345678901234561234567890123456')->add("")->mac), 'd8186a166fafc2aa245f15155bcb889f', 'F9/oo+raw/2');
is( Crypt::Mac::F9->new('AES','12345678901234561234567890123456')->add("")->hexmac, 'd8186a166fafc2aa245f15155bcb889f', 'F9/oo+hex/2');
is( unpack('H*', f9('AES','12345678901234561234567890123456',"")), 'd8186a166fafc2aa245f15155bcb889f', 'F9/func+raw/2');
is( f9_hex('AES','12345678901234561234567890123456',""), 'd8186a166fafc2aa245f15155bcb889f', 'F9/func+hex/2');
is( f9_b64('AES','12345678901234561234567890123456',""), '2BhqFm+vwqokXxUVW8uInw==', 'F9/func+b64/2');
+is( f9_b64u('AES','12345678901234561234567890123456',""), '2BhqFm-vwqokXxUVW8uInw', 'F9/func+b64u/2');
is( unpack('H*', Crypt::Mac::F9->new('Blowfish','1234567890123456')->add("")->mac), '063daede33be0e37', 'F9/oo+raw/3');
is( Crypt::Mac::F9->new('Blowfish','1234567890123456')->add("")->hexmac, '063daede33be0e37', 'F9/oo+hex/3');
is( unpack('H*', f9('Blowfish','1234567890123456',"")), '063daede33be0e37', 'F9/func+raw/3');
is( f9_hex('Blowfish','1234567890123456',""), '063daede33be0e37', 'F9/func+hex/3');
is( f9_b64('Blowfish','1234567890123456',""), 'Bj2u3jO+Djc=', 'F9/func+b64/3');
+is( f9_b64u('Blowfish','1234567890123456',""), 'Bj2u3jO-Djc', 'F9/func+b64u/3');
is( unpack('H*', Crypt::Mac::F9->new('Blowfish','12345678901234561234567890123456')->add("")->mac), '063daede33be0e37', 'F9/oo+raw/4');
is( Crypt::Mac::F9->new('Blowfish','12345678901234561234567890123456')->add("")->hexmac, '063daede33be0e37', 'F9/oo+hex/4');
is( unpack('H*', f9('Blowfish','12345678901234561234567890123456',"")), '063daede33be0e37', 'F9/func+raw/4');
is( f9_hex('Blowfish','12345678901234561234567890123456',""), '063daede33be0e37', 'F9/func+hex/4');
is( f9_b64('Blowfish','12345678901234561234567890123456',""), 'Bj2u3jO+Djc=', 'F9/func+b64/4');
-is( unpack('H*', Crypt::Mac::F9->new('AES','1234567890123456')->add(123)->mac), 'b3ec60e084566cd17423b3636d395f30', 'F9/oo+raw/5');
-is( Crypt::Mac::F9->new('AES','1234567890123456')->add(123)->hexmac, 'b3ec60e084566cd17423b3636d395f30', 'F9/oo+hex/5');
-is( unpack('H*', f9('AES','1234567890123456',123)), 'b3ec60e084566cd17423b3636d395f30', 'F9/func+raw/5');
-is( f9_hex('AES','1234567890123456',123), 'b3ec60e084566cd17423b3636d395f30', 'F9/func+hex/5');
-is( f9_b64('AES','1234567890123456',123), 's+xg4IRWbNF0I7NjbTlfMA==', 'F9/func+b64/5');
-is( unpack('H*', Crypt::Mac::F9->new('AES','12345678901234561234567890123456')->add(123)->mac), 'ea9a400b9a8dceaec669c1dea926d567', 'F9/oo+raw/6');
-is( Crypt::Mac::F9->new('AES','12345678901234561234567890123456')->add(123)->hexmac, 'ea9a400b9a8dceaec669c1dea926d567', 'F9/oo+hex/6');
-is( unpack('H*', f9('AES','12345678901234561234567890123456',123)), 'ea9a400b9a8dceaec669c1dea926d567', 'F9/func+raw/6');
-is( f9_hex('AES','12345678901234561234567890123456',123), 'ea9a400b9a8dceaec669c1dea926d567', 'F9/func+hex/6');
-is( f9_b64('AES','12345678901234561234567890123456',123), '6ppAC5qNzq7GacHeqSbVZw==', 'F9/func+b64/6');
-is( unpack('H*', Crypt::Mac::F9->new('Blowfish','1234567890123456')->add(123)->mac), '1fdb454cb94a332b', 'F9/oo+raw/7');
-is( Crypt::Mac::F9->new('Blowfish','1234567890123456')->add(123)->hexmac, '1fdb454cb94a332b', 'F9/oo+hex/7');
-is( unpack('H*', f9('Blowfish','1234567890123456',123)), '1fdb454cb94a332b', 'F9/func+raw/7');
-is( f9_hex('Blowfish','1234567890123456',123), '1fdb454cb94a332b', 'F9/func+hex/7');
-is( f9_b64('Blowfish','1234567890123456',123), 'H9tFTLlKMys=', 'F9/func+b64/7');
-is( unpack('H*', Crypt::Mac::F9->new('Blowfish','12345678901234561234567890123456')->add(123)->mac), '1fdb454cb94a332b', 'F9/oo+raw/8');
-is( Crypt::Mac::F9->new('Blowfish','12345678901234561234567890123456')->add(123)->hexmac, '1fdb454cb94a332b', 'F9/oo+hex/8');
-is( unpack('H*', f9('Blowfish','12345678901234561234567890123456',123)), '1fdb454cb94a332b', 'F9/func+raw/8');
-is( f9_hex('Blowfish','12345678901234561234567890123456',123), '1fdb454cb94a332b', 'F9/func+hex/8');
-is( f9_b64('Blowfish','12345678901234561234567890123456',123), 'H9tFTLlKMys=', 'F9/func+b64/8');
+is( f9_b64u('Blowfish','12345678901234561234567890123456',""), 'Bj2u3jO-Djc', 'F9/func+b64u/4');
+is( unpack('H*', Crypt::Mac::F9->new('AES','1234567890123456')->add("123")->mac), 'b3ec60e084566cd17423b3636d395f30', 'F9/oo+raw/5');
+is( Crypt::Mac::F9->new('AES','1234567890123456')->add("123")->hexmac, 'b3ec60e084566cd17423b3636d395f30', 'F9/oo+hex/5');
+is( unpack('H*', f9('AES','1234567890123456',"123")), 'b3ec60e084566cd17423b3636d395f30', 'F9/func+raw/5');
+is( f9_hex('AES','1234567890123456',"123"), 'b3ec60e084566cd17423b3636d395f30', 'F9/func+hex/5');
+is( f9_b64('AES','1234567890123456',"123"), 's+xg4IRWbNF0I7NjbTlfMA==', 'F9/func+b64/5');
+is( f9_b64u('AES','1234567890123456',"123"), 's-xg4IRWbNF0I7NjbTlfMA', 'F9/func+b64u/5');
+is( unpack('H*', Crypt::Mac::F9->new('AES','12345678901234561234567890123456')->add("123")->mac), 'ea9a400b9a8dceaec669c1dea926d567', 'F9/oo+raw/6');
+is( Crypt::Mac::F9->new('AES','12345678901234561234567890123456')->add("123")->hexmac, 'ea9a400b9a8dceaec669c1dea926d567', 'F9/oo+hex/6');
+is( unpack('H*', f9('AES','12345678901234561234567890123456',"123")), 'ea9a400b9a8dceaec669c1dea926d567', 'F9/func+raw/6');
+is( f9_hex('AES','12345678901234561234567890123456',"123"), 'ea9a400b9a8dceaec669c1dea926d567', 'F9/func+hex/6');
+is( f9_b64('AES','12345678901234561234567890123456',"123"), '6ppAC5qNzq7GacHeqSbVZw==', 'F9/func+b64/6');
+is( f9_b64u('AES','12345678901234561234567890123456',"123"), '6ppAC5qNzq7GacHeqSbVZw', 'F9/func+b64u/6');
+is( unpack('H*', Crypt::Mac::F9->new('Blowfish','1234567890123456')->add("123")->mac), '1fdb454cb94a332b', 'F9/oo+raw/7');
+is( Crypt::Mac::F9->new('Blowfish','1234567890123456')->add("123")->hexmac, '1fdb454cb94a332b', 'F9/oo+hex/7');
+is( unpack('H*', f9('Blowfish','1234567890123456',"123")), '1fdb454cb94a332b', 'F9/func+raw/7');
+is( f9_hex('Blowfish','1234567890123456',"123"), '1fdb454cb94a332b', 'F9/func+hex/7');
+is( f9_b64('Blowfish','1234567890123456',"123"), 'H9tFTLlKMys=', 'F9/func+b64/7');
+is( f9_b64u('Blowfish','1234567890123456',"123"), 'H9tFTLlKMys', 'F9/func+b64u/7');
+is( unpack('H*', Crypt::Mac::F9->new('Blowfish','12345678901234561234567890123456')->add("123")->mac), '1fdb454cb94a332b', 'F9/oo+raw/8');
+is( Crypt::Mac::F9->new('Blowfish','12345678901234561234567890123456')->add("123")->hexmac, '1fdb454cb94a332b', 'F9/oo+hex/8');
+is( unpack('H*', f9('Blowfish','12345678901234561234567890123456',"123")), '1fdb454cb94a332b', 'F9/func+raw/8');
+is( f9_hex('Blowfish','12345678901234561234567890123456',"123"), '1fdb454cb94a332b', 'F9/func+hex/8');
+is( f9_b64('Blowfish','12345678901234561234567890123456',"123"), 'H9tFTLlKMys=', 'F9/func+b64/8');
+is( f9_b64u('Blowfish','12345678901234561234567890123456',"123"), 'H9tFTLlKMys', 'F9/func+b64u/8');
is( unpack('H*', Crypt::Mac::F9->new('AES','1234567890123456')->add("test\0test\0test\n")->mac), '9fa4876ee09966ff8c1ae43b05e0b155', 'F9/oo+raw/9');
is( Crypt::Mac::F9->new('AES','1234567890123456')->add("test\0test\0test\n")->hexmac, '9fa4876ee09966ff8c1ae43b05e0b155', 'F9/oo+hex/9');
is( unpack('H*', f9('AES','1234567890123456',"test\0test\0test\n")), '9fa4876ee09966ff8c1ae43b05e0b155', 'F9/func+raw/9');
is( f9_hex('AES','1234567890123456',"test\0test\0test\n"), '9fa4876ee09966ff8c1ae43b05e0b155', 'F9/func+hex/9');
is( f9_b64('AES','1234567890123456',"test\0test\0test\n"), 'n6SHbuCZZv+MGuQ7BeCxVQ==', 'F9/func+b64/9');
+is( f9_b64u('AES','1234567890123456',"test\0test\0test\n"), 'n6SHbuCZZv-MGuQ7BeCxVQ', 'F9/func+b64u/9');
is( unpack('H*', Crypt::Mac::F9->new('AES','12345678901234561234567890123456')->add("test\0test\0test\n")->mac), '6934865f133c0092e4941b45cca38c5f', 'F9/oo+raw/10');
is( Crypt::Mac::F9->new('AES','12345678901234561234567890123456')->add("test\0test\0test\n")->hexmac, '6934865f133c0092e4941b45cca38c5f', 'F9/oo+hex/10');
is( unpack('H*', f9('AES','12345678901234561234567890123456',"test\0test\0test\n")), '6934865f133c0092e4941b45cca38c5f', 'F9/func+raw/10');
is( f9_hex('AES','12345678901234561234567890123456',"test\0test\0test\n"), '6934865f133c0092e4941b45cca38c5f', 'F9/func+hex/10');
is( f9_b64('AES','12345678901234561234567890123456',"test\0test\0test\n"), 'aTSGXxM8AJLklBtFzKOMXw==', 'F9/func+b64/10');
+is( f9_b64u('AES','12345678901234561234567890123456',"test\0test\0test\n"), 'aTSGXxM8AJLklBtFzKOMXw', 'F9/func+b64u/10');
is( unpack('H*', Crypt::Mac::F9->new('Blowfish','1234567890123456')->add("test\0test\0test\n")->mac), 'fa83d84023c43a81', 'F9/oo+raw/11');
is( Crypt::Mac::F9->new('Blowfish','1234567890123456')->add("test\0test\0test\n")->hexmac, 'fa83d84023c43a81', 'F9/oo+hex/11');
is( unpack('H*', f9('Blowfish','1234567890123456',"test\0test\0test\n")), 'fa83d84023c43a81', 'F9/func+raw/11');
is( f9_hex('Blowfish','1234567890123456',"test\0test\0test\n"), 'fa83d84023c43a81', 'F9/func+hex/11');
is( f9_b64('Blowfish','1234567890123456',"test\0test\0test\n"), '+oPYQCPEOoE=', 'F9/func+b64/11');
+is( f9_b64u('Blowfish','1234567890123456',"test\0test\0test\n"), '-oPYQCPEOoE', 'F9/func+b64u/11');
is( unpack('H*', Crypt::Mac::F9->new('Blowfish','12345678901234561234567890123456')->add("test\0test\0test\n")->mac), 'fa83d84023c43a81', 'F9/oo+raw/12');
is( Crypt::Mac::F9->new('Blowfish','12345678901234561234567890123456')->add("test\0test\0test\n")->hexmac, 'fa83d84023c43a81', 'F9/oo+hex/12');
is( unpack('H*', f9('Blowfish','12345678901234561234567890123456',"test\0test\0test\n")), 'fa83d84023c43a81', 'F9/func+raw/12');
is( f9_hex('Blowfish','12345678901234561234567890123456',"test\0test\0test\n"), 'fa83d84023c43a81', 'F9/func+hex/12');
is( f9_b64('Blowfish','12345678901234561234567890123456',"test\0test\0test\n"), '+oPYQCPEOoE=', 'F9/func+b64/12');
+is( f9_b64u('Blowfish','12345678901234561234567890123456',"test\0test\0test\n"), '-oPYQCPEOoE', 'F9/func+b64u/12');
done_testing();
diff --git a/t/mac_hmac.t b/t/mac_hmac.t
index da8c9acb..9a2065d9 100644
--- a/t/mac_hmac.t
+++ b/t/mac_hmac.t
@@ -5,67 +5,79 @@ use warnings;
use Test::More;
-use Crypt::Mac::HMAC qw( hmac hmac_hex hmac_b64 );
+use Crypt::Mac::HMAC qw( hmac hmac_hex hmac_b64 hmac_b64u );
is( unpack('H*', Crypt::Mac::HMAC->new('SHA1','secretkey')->add("")->mac), '3353ae0208558692a0cce27396e07165ea76f969', 'HMAC/oo+raw/1');
is( Crypt::Mac::HMAC->new('SHA1','secretkey')->add("")->hexmac, '3353ae0208558692a0cce27396e07165ea76f969', 'HMAC/oo+hex/1');
is( unpack('H*', hmac('SHA1','secretkey',"")), '3353ae0208558692a0cce27396e07165ea76f969', 'HMAC/func+raw/1');
is( hmac_hex('SHA1','secretkey',""), '3353ae0208558692a0cce27396e07165ea76f969', 'HMAC/func+hex/1');
is( hmac_b64('SHA1','secretkey',""), 'M1OuAghVhpKgzOJzluBxZep2+Wk=', 'HMAC/func+b64/1');
+is( hmac_b64u('SHA1','secretkey',""), 'M1OuAghVhpKgzOJzluBxZep2-Wk', 'HMAC/func+b64u/1');
is( unpack('H*', Crypt::Mac::HMAC->new('SHA512','secretkey')->add("")->mac), '683f73ef2765ef315191ac32b1b4438bf5c2c6d0de8999574eeb522f902f02e1ef7f413cd615f07738a9d8be8250e0abfb78368dd487c03639f56ece28ca8c6c', 'HMAC/oo+raw/2');
is( Crypt::Mac::HMAC->new('SHA512','secretkey')->add("")->hexmac, '683f73ef2765ef315191ac32b1b4438bf5c2c6d0de8999574eeb522f902f02e1ef7f413cd615f07738a9d8be8250e0abfb78368dd487c03639f56ece28ca8c6c', 'HMAC/oo+hex/2');
is( unpack('H*', hmac('SHA512','secretkey',"")), '683f73ef2765ef315191ac32b1b4438bf5c2c6d0de8999574eeb522f902f02e1ef7f413cd615f07738a9d8be8250e0abfb78368dd487c03639f56ece28ca8c6c', 'HMAC/func+raw/2');
is( hmac_hex('SHA512','secretkey',""), '683f73ef2765ef315191ac32b1b4438bf5c2c6d0de8999574eeb522f902f02e1ef7f413cd615f07738a9d8be8250e0abfb78368dd487c03639f56ece28ca8c6c', 'HMAC/func+hex/2');
is( hmac_b64('SHA512','secretkey',""), 'aD9z7ydl7zFRkawysbRDi/XCxtDeiZlXTutSL5AvAuHvf0E81hXwdzip2L6CUOCr+3g2jdSHwDY59W7OKMqMbA==', 'HMAC/func+b64/2');
+is( hmac_b64u('SHA512','secretkey',""), 'aD9z7ydl7zFRkawysbRDi_XCxtDeiZlXTutSL5AvAuHvf0E81hXwdzip2L6CUOCr-3g2jdSHwDY59W7OKMqMbA', 'HMAC/func+b64u/2');
is( unpack('H*', Crypt::Mac::HMAC->new('Tiger192','secretkey')->add("")->mac), 'f8a326890e07530aaf7eb1b60c4e10bfa4c875550ba8683e', 'HMAC/oo+raw/3');
is( Crypt::Mac::HMAC->new('Tiger192','secretkey')->add("")->hexmac, 'f8a326890e07530aaf7eb1b60c4e10bfa4c875550ba8683e', 'HMAC/oo+hex/3');
is( unpack('H*', hmac('Tiger192','secretkey',"")), 'f8a326890e07530aaf7eb1b60c4e10bfa4c875550ba8683e', 'HMAC/func+raw/3');
is( hmac_hex('Tiger192','secretkey',""), 'f8a326890e07530aaf7eb1b60c4e10bfa4c875550ba8683e', 'HMAC/func+hex/3');
is( hmac_b64('Tiger192','secretkey',""), '+KMmiQ4HUwqvfrG2DE4Qv6TIdVULqGg+', 'HMAC/func+b64/3');
+is( hmac_b64u('Tiger192','secretkey',""), '-KMmiQ4HUwqvfrG2DE4Qv6TIdVULqGg-', 'HMAC/func+b64u/3');
is( unpack('H*', Crypt::Mac::HMAC->new('Whirlpool','secretkey')->add("")->mac), '742456ee0548c7fe7e81fb86a05b291d0fa37bc95f1ce562a8a4f4e7bd37a5862a16647963ec3b934355cff410f0d0d8b98fa531f56547a85c1eb1ab25b22a5e', 'HMAC/oo+raw/4');
is( Crypt::Mac::HMAC->new('Whirlpool','secretkey')->add("")->hexmac, '742456ee0548c7fe7e81fb86a05b291d0fa37bc95f1ce562a8a4f4e7bd37a5862a16647963ec3b934355cff410f0d0d8b98fa531f56547a85c1eb1ab25b22a5e', 'HMAC/oo+hex/4');
is( unpack('H*', hmac('Whirlpool','secretkey',"")), '742456ee0548c7fe7e81fb86a05b291d0fa37bc95f1ce562a8a4f4e7bd37a5862a16647963ec3b934355cff410f0d0d8b98fa531f56547a85c1eb1ab25b22a5e', 'HMAC/func+raw/4');
is( hmac_hex('Whirlpool','secretkey',""), '742456ee0548c7fe7e81fb86a05b291d0fa37bc95f1ce562a8a4f4e7bd37a5862a16647963ec3b934355cff410f0d0d8b98fa531f56547a85c1eb1ab25b22a5e', 'HMAC/func+hex/4');
is( hmac_b64('Whirlpool','secretkey',""), 'dCRW7gVIx/5+gfuGoFspHQ+je8lfHOViqKT05703pYYqFmR5Y+w7k0NVz/QQ8NDYuY+lMfVlR6hcHrGrJbIqXg==', 'HMAC/func+b64/4');
-is( unpack('H*', Crypt::Mac::HMAC->new('SHA1','secretkey')->add(123)->mac), 'd1e8eaf9de1843fda2fa8e63bb6cc8a61a706fd6', 'HMAC/oo+raw/5');
-is( Crypt::Mac::HMAC->new('SHA1','secretkey')->add(123)->hexmac, 'd1e8eaf9de1843fda2fa8e63bb6cc8a61a706fd6', 'HMAC/oo+hex/5');
-is( unpack('H*', hmac('SHA1','secretkey',123)), 'd1e8eaf9de1843fda2fa8e63bb6cc8a61a706fd6', 'HMAC/func+raw/5');
-is( hmac_hex('SHA1','secretkey',123), 'd1e8eaf9de1843fda2fa8e63bb6cc8a61a706fd6', 'HMAC/func+hex/5');
-is( hmac_b64('SHA1','secretkey',123), '0ejq+d4YQ/2i+o5ju2zIphpwb9Y=', 'HMAC/func+b64/5');
-is( unpack('H*', Crypt::Mac::HMAC->new('SHA512','secretkey')->add(123)->mac), 'b0dc661fb66a42a2a3af93087da36317b088684b026030215986793f17b1ae748ec9d3234ac63d41976d6c7f7c2d8465a4ffd0fe7baa56460b4664882b8175e4', 'HMAC/oo+raw/6');
-is( Crypt::Mac::HMAC->new('SHA512','secretkey')->add(123)->hexmac, 'b0dc661fb66a42a2a3af93087da36317b088684b026030215986793f17b1ae748ec9d3234ac63d41976d6c7f7c2d8465a4ffd0fe7baa56460b4664882b8175e4', 'HMAC/oo+hex/6');
-is( unpack('H*', hmac('SHA512','secretkey',123)), 'b0dc661fb66a42a2a3af93087da36317b088684b026030215986793f17b1ae748ec9d3234ac63d41976d6c7f7c2d8465a4ffd0fe7baa56460b4664882b8175e4', 'HMAC/func+raw/6');
-is( hmac_hex('SHA512','secretkey',123), 'b0dc661fb66a42a2a3af93087da36317b088684b026030215986793f17b1ae748ec9d3234ac63d41976d6c7f7c2d8465a4ffd0fe7baa56460b4664882b8175e4', 'HMAC/func+hex/6');
-is( hmac_b64('SHA512','secretkey',123), 'sNxmH7ZqQqKjr5MIfaNjF7CIaEsCYDAhWYZ5PxexrnSOydMjSsY9QZdtbH98LYRlpP/Q/nuqVkYLRmSIK4F15A==', 'HMAC/func+b64/6');
-is( unpack('H*', Crypt::Mac::HMAC->new('Tiger192','secretkey')->add(123)->mac), '2625b3d7df40fbdcb87987e8cb50b4e815fcf91eac104c81', 'HMAC/oo+raw/7');
-is( Crypt::Mac::HMAC->new('Tiger192','secretkey')->add(123)->hexmac, '2625b3d7df40fbdcb87987e8cb50b4e815fcf91eac104c81', 'HMAC/oo+hex/7');
-is( unpack('H*', hmac('Tiger192','secretkey',123)), '2625b3d7df40fbdcb87987e8cb50b4e815fcf91eac104c81', 'HMAC/func+raw/7');
-is( hmac_hex('Tiger192','secretkey',123), '2625b3d7df40fbdcb87987e8cb50b4e815fcf91eac104c81', 'HMAC/func+hex/7');
-is( hmac_b64('Tiger192','secretkey',123), 'JiWz199A+9y4eYfoy1C06BX8+R6sEEyB', 'HMAC/func+b64/7');
-is( unpack('H*', Crypt::Mac::HMAC->new('Whirlpool','secretkey')->add(123)->mac), '26ffebc6d041002a375f5808095ee49aa0517070a750c40f4fd5e0c3adc8cdf8a8723cb8e1e37704ccc566bbb7613a46e23915428d97133fb31ef8cd264c4d60', 'HMAC/oo+raw/8');
-is( Crypt::Mac::HMAC->new('Whirlpool','secretkey')->add(123)->hexmac, '26ffebc6d041002a375f5808095ee49aa0517070a750c40f4fd5e0c3adc8cdf8a8723cb8e1e37704ccc566bbb7613a46e23915428d97133fb31ef8cd264c4d60', 'HMAC/oo+hex/8');
-is( unpack('H*', hmac('Whirlpool','secretkey',123)), '26ffebc6d041002a375f5808095ee49aa0517070a750c40f4fd5e0c3adc8cdf8a8723cb8e1e37704ccc566bbb7613a46e23915428d97133fb31ef8cd264c4d60', 'HMAC/func+raw/8');
-is( hmac_hex('Whirlpool','secretkey',123), '26ffebc6d041002a375f5808095ee49aa0517070a750c40f4fd5e0c3adc8cdf8a8723cb8e1e37704ccc566bbb7613a46e23915428d97133fb31ef8cd264c4d60', 'HMAC/func+hex/8');
-is( hmac_b64('Whirlpool','secretkey',123), 'Jv/rxtBBACo3X1gICV7kmqBRcHCnUMQPT9Xgw63Izfiocjy44eN3BMzFZru3YTpG4jkVQo2XEz+zHvjNJkxNYA==', 'HMAC/func+b64/8');
+is( hmac_b64u('Whirlpool','secretkey',""), 'dCRW7gVIx_5-gfuGoFspHQ-je8lfHOViqKT05703pYYqFmR5Y-w7k0NVz_QQ8NDYuY-lMfVlR6hcHrGrJbIqXg', 'HMAC/func+b64u/4');
+is( unpack('H*', Crypt::Mac::HMAC->new('SHA1','secretkey')->add("123")->mac), 'd1e8eaf9de1843fda2fa8e63bb6cc8a61a706fd6', 'HMAC/oo+raw/5');
+is( Crypt::Mac::HMAC->new('SHA1','secretkey')->add("123")->hexmac, 'd1e8eaf9de1843fda2fa8e63bb6cc8a61a706fd6', 'HMAC/oo+hex/5');
+is( unpack('H*', hmac('SHA1','secretkey',"123")), 'd1e8eaf9de1843fda2fa8e63bb6cc8a61a706fd6', 'HMAC/func+raw/5');
+is( hmac_hex('SHA1','secretkey',"123"), 'd1e8eaf9de1843fda2fa8e63bb6cc8a61a706fd6', 'HMAC/func+hex/5');
+is( hmac_b64('SHA1','secretkey',"123"), '0ejq+d4YQ/2i+o5ju2zIphpwb9Y=', 'HMAC/func+b64/5');
+is( hmac_b64u('SHA1','secretkey',"123"), '0ejq-d4YQ_2i-o5ju2zIphpwb9Y', 'HMAC/func+b64u/5');
+is( unpack('H*', Crypt::Mac::HMAC->new('SHA512','secretkey')->add("123")->mac), 'b0dc661fb66a42a2a3af93087da36317b088684b026030215986793f17b1ae748ec9d3234ac63d41976d6c7f7c2d8465a4ffd0fe7baa56460b4664882b8175e4', 'HMAC/oo+raw/6');
+is( Crypt::Mac::HMAC->new('SHA512','secretkey')->add("123")->hexmac, 'b0dc661fb66a42a2a3af93087da36317b088684b026030215986793f17b1ae748ec9d3234ac63d41976d6c7f7c2d8465a4ffd0fe7baa56460b4664882b8175e4', 'HMAC/oo+hex/6');
+is( unpack('H*', hmac('SHA512','secretkey',"123")), 'b0dc661fb66a42a2a3af93087da36317b088684b026030215986793f17b1ae748ec9d3234ac63d41976d6c7f7c2d8465a4ffd0fe7baa56460b4664882b8175e4', 'HMAC/func+raw/6');
+is( hmac_hex('SHA512','secretkey',"123"), 'b0dc661fb66a42a2a3af93087da36317b088684b026030215986793f17b1ae748ec9d3234ac63d41976d6c7f7c2d8465a4ffd0fe7baa56460b4664882b8175e4', 'HMAC/func+hex/6');
+is( hmac_b64('SHA512','secretkey',"123"), 'sNxmH7ZqQqKjr5MIfaNjF7CIaEsCYDAhWYZ5PxexrnSOydMjSsY9QZdtbH98LYRlpP/Q/nuqVkYLRmSIK4F15A==', 'HMAC/func+b64/6');
+is( hmac_b64u('SHA512','secretkey',"123"), 'sNxmH7ZqQqKjr5MIfaNjF7CIaEsCYDAhWYZ5PxexrnSOydMjSsY9QZdtbH98LYRlpP_Q_nuqVkYLRmSIK4F15A', 'HMAC/func+b64u/6');
+is( unpack('H*', Crypt::Mac::HMAC->new('Tiger192','secretkey')->add("123")->mac), '2625b3d7df40fbdcb87987e8cb50b4e815fcf91eac104c81', 'HMAC/oo+raw/7');
+is( Crypt::Mac::HMAC->new('Tiger192','secretkey')->add("123")->hexmac, '2625b3d7df40fbdcb87987e8cb50b4e815fcf91eac104c81', 'HMAC/oo+hex/7');
+is( unpack('H*', hmac('Tiger192','secretkey',"123")), '2625b3d7df40fbdcb87987e8cb50b4e815fcf91eac104c81', 'HMAC/func+raw/7');
+is( hmac_hex('Tiger192','secretkey',"123"), '2625b3d7df40fbdcb87987e8cb50b4e815fcf91eac104c81', 'HMAC/func+hex/7');
+is( hmac_b64('Tiger192','secretkey',"123"), 'JiWz199A+9y4eYfoy1C06BX8+R6sEEyB', 'HMAC/func+b64/7');
+is( hmac_b64u('Tiger192','secretkey',"123"), 'JiWz199A-9y4eYfoy1C06BX8-R6sEEyB', 'HMAC/func+b64u/7');
+is( unpack('H*', Crypt::Mac::HMAC->new('Whirlpool','secretkey')->add("123")->mac), '26ffebc6d041002a375f5808095ee49aa0517070a750c40f4fd5e0c3adc8cdf8a8723cb8e1e37704ccc566bbb7613a46e23915428d97133fb31ef8cd264c4d60', 'HMAC/oo+raw/8');
+is( Crypt::Mac::HMAC->new('Whirlpool','secretkey')->add("123")->hexmac, '26ffebc6d041002a375f5808095ee49aa0517070a750c40f4fd5e0c3adc8cdf8a8723cb8e1e37704ccc566bbb7613a46e23915428d97133fb31ef8cd264c4d60', 'HMAC/oo+hex/8');
+is( unpack('H*', hmac('Whirlpool','secretkey',"123")), '26ffebc6d041002a375f5808095ee49aa0517070a750c40f4fd5e0c3adc8cdf8a8723cb8e1e37704ccc566bbb7613a46e23915428d97133fb31ef8cd264c4d60', 'HMAC/func+raw/8');
+is( hmac_hex('Whirlpool','secretkey',"123"), '26ffebc6d041002a375f5808095ee49aa0517070a750c40f4fd5e0c3adc8cdf8a8723cb8e1e37704ccc566bbb7613a46e23915428d97133fb31ef8cd264c4d60', 'HMAC/func+hex/8');
+is( hmac_b64('Whirlpool','secretkey',"123"), 'Jv/rxtBBACo3X1gICV7kmqBRcHCnUMQPT9Xgw63Izfiocjy44eN3BMzFZru3YTpG4jkVQo2XEz+zHvjNJkxNYA==', 'HMAC/func+b64/8');
+is( hmac_b64u('Whirlpool','secretkey',"123"), 'Jv_rxtBBACo3X1gICV7kmqBRcHCnUMQPT9Xgw63Izfiocjy44eN3BMzFZru3YTpG4jkVQo2XEz-zHvjNJkxNYA', 'HMAC/func+b64u/8');
is( unpack('H*', Crypt::Mac::HMAC->new('SHA1','secretkey')->add("test\0test\0test\n")->mac), '909a8e4f5688eac58c095db91cd1ad0d7e95bb08', 'HMAC/oo+raw/9');
is( Crypt::Mac::HMAC->new('SHA1','secretkey')->add("test\0test\0test\n")->hexmac, '909a8e4f5688eac58c095db91cd1ad0d7e95bb08', 'HMAC/oo+hex/9');
is( unpack('H*', hmac('SHA1','secretkey',"test\0test\0test\n")), '909a8e4f5688eac58c095db91cd1ad0d7e95bb08', 'HMAC/func+raw/9');
is( hmac_hex('SHA1','secretkey',"test\0test\0test\n"), '909a8e4f5688eac58c095db91cd1ad0d7e95bb08', 'HMAC/func+hex/9');
is( hmac_b64('SHA1','secretkey',"test\0test\0test\n"), 'kJqOT1aI6sWMCV25HNGtDX6Vuwg=', 'HMAC/func+b64/9');
+is( hmac_b64u('SHA1','secretkey',"test\0test\0test\n"), 'kJqOT1aI6sWMCV25HNGtDX6Vuwg', 'HMAC/func+b64u/9');
is( unpack('H*', Crypt::Mac::HMAC->new('SHA512','secretkey')->add("test\0test\0test\n")->mac), '97b775cb90e756d586e535ea6f90f9baea45514b9399eed71a1e9da262a753df0f54bce89d97e07b14b524d191c45aec469a66699636bf5f2a5edfc127aed342', 'HMAC/oo+raw/10');
is( Crypt::Mac::HMAC->new('SHA512','secretkey')->add("test\0test\0test\n")->hexmac, '97b775cb90e756d586e535ea6f90f9baea45514b9399eed71a1e9da262a753df0f54bce89d97e07b14b524d191c45aec469a66699636bf5f2a5edfc127aed342', 'HMAC/oo+hex/10');
is( unpack('H*', hmac('SHA512','secretkey',"test\0test\0test\n")), '97b775cb90e756d586e535ea6f90f9baea45514b9399eed71a1e9da262a753df0f54bce89d97e07b14b524d191c45aec469a66699636bf5f2a5edfc127aed342', 'HMAC/func+raw/10');
is( hmac_hex('SHA512','secretkey',"test\0test\0test\n"), '97b775cb90e756d586e535ea6f90f9baea45514b9399eed71a1e9da262a753df0f54bce89d97e07b14b524d191c45aec469a66699636bf5f2a5edfc127aed342', 'HMAC/func+hex/10');
is( hmac_b64('SHA512','secretkey',"test\0test\0test\n"), 'l7d1y5DnVtWG5TXqb5D5uupFUUuTme7XGh6domKnU98PVLzonZfgexS1JNGRxFrsRppmaZY2v18qXt/BJ67TQg==', 'HMAC/func+b64/10');
+is( hmac_b64u('SHA512','secretkey',"test\0test\0test\n"), 'l7d1y5DnVtWG5TXqb5D5uupFUUuTme7XGh6domKnU98PVLzonZfgexS1JNGRxFrsRppmaZY2v18qXt_BJ67TQg', 'HMAC/func+b64u/10');
is( unpack('H*', Crypt::Mac::HMAC->new('Tiger192','secretkey')->add("test\0test\0test\n")->mac), 'c22b1eba9138c1dba72d43426a3d3e4db14c90b6232d4781', 'HMAC/oo+raw/11');
is( Crypt::Mac::HMAC->new('Tiger192','secretkey')->add("test\0test\0test\n")->hexmac, 'c22b1eba9138c1dba72d43426a3d3e4db14c90b6232d4781', 'HMAC/oo+hex/11');
is( unpack('H*', hmac('Tiger192','secretkey',"test\0test\0test\n")), 'c22b1eba9138c1dba72d43426a3d3e4db14c90b6232d4781', 'HMAC/func+raw/11');
is( hmac_hex('Tiger192','secretkey',"test\0test\0test\n"), 'c22b1eba9138c1dba72d43426a3d3e4db14c90b6232d4781', 'HMAC/func+hex/11');
is( hmac_b64('Tiger192','secretkey',"test\0test\0test\n"), 'wiseupE4wdunLUNCaj0+TbFMkLYjLUeB', 'HMAC/func+b64/11');
+is( hmac_b64u('Tiger192','secretkey',"test\0test\0test\n"), 'wiseupE4wdunLUNCaj0-TbFMkLYjLUeB', 'HMAC/func+b64u/11');
is( unpack('H*', Crypt::Mac::HMAC->new('Whirlpool','secretkey')->add("test\0test\0test\n")->mac), 'dab6a22e05b46ce641e022e6ea2b42646a25b994ed15fed09145e3906d159efba37b899c344f589b3ad5868cd631a8eb304d21dedf47e364c791ccfa665681f7', 'HMAC/oo+raw/12');
is( Crypt::Mac::HMAC->new('Whirlpool','secretkey')->add("test\0test\0test\n")->hexmac, 'dab6a22e05b46ce641e022e6ea2b42646a25b994ed15fed09145e3906d159efba37b899c344f589b3ad5868cd631a8eb304d21dedf47e364c791ccfa665681f7', 'HMAC/oo+hex/12');
is( unpack('H*', hmac('Whirlpool','secretkey',"test\0test\0test\n")), 'dab6a22e05b46ce641e022e6ea2b42646a25b994ed15fed09145e3906d159efba37b899c344f589b3ad5868cd631a8eb304d21dedf47e364c791ccfa665681f7', 'HMAC/func+raw/12');
is( hmac_hex('Whirlpool','secretkey',"test\0test\0test\n"), 'dab6a22e05b46ce641e022e6ea2b42646a25b994ed15fed09145e3906d159efba37b899c344f589b3ad5868cd631a8eb304d21dedf47e364c791ccfa665681f7', 'HMAC/func+hex/12');
is( hmac_b64('Whirlpool','secretkey',"test\0test\0test\n"), '2raiLgW0bOZB4CLm6itCZGoluZTtFf7QkUXjkG0Vnvuje4mcNE9YmzrVhozWMajrME0h3t9H42THkcz6ZlaB9w==', 'HMAC/func+b64/12');
+is( hmac_b64u('Whirlpool','secretkey',"test\0test\0test\n"), '2raiLgW0bOZB4CLm6itCZGoluZTtFf7QkUXjkG0Vnvuje4mcNE9YmzrVhozWMajrME0h3t9H42THkcz6ZlaB9w', 'HMAC/func+b64u/12');
done_testing();
diff --git a/t/mac_omac.t b/t/mac_omac.t
index 977bf481..16fad107 100644
--- a/t/mac_omac.t
+++ b/t/mac_omac.t
@@ -5,67 +5,79 @@ use warnings;
use Test::More;
-use Crypt::Mac::OMAC qw( omac omac_hex omac_b64 );
+use Crypt::Mac::OMAC qw( omac omac_hex omac_b64 omac_b64u );
is( unpack('H*', Crypt::Mac::OMAC->new('AES','1234567890123456')->add("")->mac), '0858f76009f57ad2c6fd771d1b93a21e', 'OMAC/oo+raw/1');
is( Crypt::Mac::OMAC->new('AES','1234567890123456')->add("")->hexmac, '0858f76009f57ad2c6fd771d1b93a21e', 'OMAC/oo+hex/1');
is( unpack('H*', omac('AES','1234567890123456',"")), '0858f76009f57ad2c6fd771d1b93a21e', 'OMAC/func+raw/1');
is( omac_hex('AES','1234567890123456',""), '0858f76009f57ad2c6fd771d1b93a21e', 'OMAC/func+hex/1');
is( omac_b64('AES','1234567890123456',""), 'CFj3YAn1etLG/XcdG5OiHg==', 'OMAC/func+b64/1');
+is( omac_b64u('AES','1234567890123456',""), 'CFj3YAn1etLG_XcdG5OiHg', 'OMAC/func+b64u/1');
is( unpack('H*', Crypt::Mac::OMAC->new('AES','12345678901234561234567890123456')->add("")->mac), '659fa9f016ce9b4a2bf9f5ec4486732b', 'OMAC/oo+raw/2');
is( Crypt::Mac::OMAC->new('AES','12345678901234561234567890123456')->add("")->hexmac, '659fa9f016ce9b4a2bf9f5ec4486732b', 'OMAC/oo+hex/2');
is( unpack('H*', omac('AES','12345678901234561234567890123456',"")), '659fa9f016ce9b4a2bf9f5ec4486732b', 'OMAC/func+raw/2');
is( omac_hex('AES','12345678901234561234567890123456',""), '659fa9f016ce9b4a2bf9f5ec4486732b', 'OMAC/func+hex/2');
is( omac_b64('AES','12345678901234561234567890123456',""), 'ZZ+p8BbOm0or+fXsRIZzKw==', 'OMAC/func+b64/2');
+is( omac_b64u('AES','12345678901234561234567890123456',""), 'ZZ-p8BbOm0or-fXsRIZzKw', 'OMAC/func+b64u/2');
is( unpack('H*', Crypt::Mac::OMAC->new('Blowfish','1234567890123456')->add("")->mac), 'a53ab7d313338f8f', 'OMAC/oo+raw/3');
is( Crypt::Mac::OMAC->new('Blowfish','1234567890123456')->add("")->hexmac, 'a53ab7d313338f8f', 'OMAC/oo+hex/3');
is( unpack('H*', omac('Blowfish','1234567890123456',"")), 'a53ab7d313338f8f', 'OMAC/func+raw/3');
is( omac_hex('Blowfish','1234567890123456',""), 'a53ab7d313338f8f', 'OMAC/func+hex/3');
is( omac_b64('Blowfish','1234567890123456',""), 'pTq30xMzj48=', 'OMAC/func+b64/3');
+is( omac_b64u('Blowfish','1234567890123456',""), 'pTq30xMzj48', 'OMAC/func+b64u/3');
is( unpack('H*', Crypt::Mac::OMAC->new('Blowfish','12345678901234561234567890123456')->add("")->mac), 'a53ab7d313338f8f', 'OMAC/oo+raw/4');
is( Crypt::Mac::OMAC->new('Blowfish','12345678901234561234567890123456')->add("")->hexmac, 'a53ab7d313338f8f', 'OMAC/oo+hex/4');
is( unpack('H*', omac('Blowfish','12345678901234561234567890123456',"")), 'a53ab7d313338f8f', 'OMAC/func+raw/4');
is( omac_hex('Blowfish','12345678901234561234567890123456',""), 'a53ab7d313338f8f', 'OMAC/func+hex/4');
is( omac_b64('Blowfish','12345678901234561234567890123456',""), 'pTq30xMzj48=', 'OMAC/func+b64/4');
-is( unpack('H*', Crypt::Mac::OMAC->new('AES','1234567890123456')->add(123)->mac), 'cdda83e8105929d720615d2e2919f517', 'OMAC/oo+raw/5');
-is( Crypt::Mac::OMAC->new('AES','1234567890123456')->add(123)->hexmac, 'cdda83e8105929d720615d2e2919f517', 'OMAC/oo+hex/5');
-is( unpack('H*', omac('AES','1234567890123456',123)), 'cdda83e8105929d720615d2e2919f517', 'OMAC/func+raw/5');
-is( omac_hex('AES','1234567890123456',123), 'cdda83e8105929d720615d2e2919f517', 'OMAC/func+hex/5');
-is( omac_b64('AES','1234567890123456',123), 'zdqD6BBZKdcgYV0uKRn1Fw==', 'OMAC/func+b64/5');
-is( unpack('H*', Crypt::Mac::OMAC->new('AES','12345678901234561234567890123456')->add(123)->mac), '93cfd941f83b842afe81326332f25e32', 'OMAC/oo+raw/6');
-is( Crypt::Mac::OMAC->new('AES','12345678901234561234567890123456')->add(123)->hexmac, '93cfd941f83b842afe81326332f25e32', 'OMAC/oo+hex/6');
-is( unpack('H*', omac('AES','12345678901234561234567890123456',123)), '93cfd941f83b842afe81326332f25e32', 'OMAC/func+raw/6');
-is( omac_hex('AES','12345678901234561234567890123456',123), '93cfd941f83b842afe81326332f25e32', 'OMAC/func+hex/6');
-is( omac_b64('AES','12345678901234561234567890123456',123), 'k8/ZQfg7hCr+gTJjMvJeMg==', 'OMAC/func+b64/6');
-is( unpack('H*', Crypt::Mac::OMAC->new('Blowfish','1234567890123456')->add(123)->mac), '357f9876a15825ec', 'OMAC/oo+raw/7');
-is( Crypt::Mac::OMAC->new('Blowfish','1234567890123456')->add(123)->hexmac, '357f9876a15825ec', 'OMAC/oo+hex/7');
-is( unpack('H*', omac('Blowfish','1234567890123456',123)), '357f9876a15825ec', 'OMAC/func+raw/7');
-is( omac_hex('Blowfish','1234567890123456',123), '357f9876a15825ec', 'OMAC/func+hex/7');
-is( omac_b64('Blowfish','1234567890123456',123), 'NX+YdqFYJew=', 'OMAC/func+b64/7');
-is( unpack('H*', Crypt::Mac::OMAC->new('Blowfish','12345678901234561234567890123456')->add(123)->mac), '357f9876a15825ec', 'OMAC/oo+raw/8');
-is( Crypt::Mac::OMAC->new('Blowfish','12345678901234561234567890123456')->add(123)->hexmac, '357f9876a15825ec', 'OMAC/oo+hex/8');
-is( unpack('H*', omac('Blowfish','12345678901234561234567890123456',123)), '357f9876a15825ec', 'OMAC/func+raw/8');
-is( omac_hex('Blowfish','12345678901234561234567890123456',123), '357f9876a15825ec', 'OMAC/func+hex/8');
-is( omac_b64('Blowfish','12345678901234561234567890123456',123), 'NX+YdqFYJew=', 'OMAC/func+b64/8');
+is( omac_b64u('Blowfish','12345678901234561234567890123456',""), 'pTq30xMzj48', 'OMAC/func+b64u/4');
+is( unpack('H*', Crypt::Mac::OMAC->new('AES','1234567890123456')->add("123")->mac), 'cdda83e8105929d720615d2e2919f517', 'OMAC/oo+raw/5');
+is( Crypt::Mac::OMAC->new('AES','1234567890123456')->add("123")->hexmac, 'cdda83e8105929d720615d2e2919f517', 'OMAC/oo+hex/5');
+is( unpack('H*', omac('AES','1234567890123456',"123")), 'cdda83e8105929d720615d2e2919f517', 'OMAC/func+raw/5');
+is( omac_hex('AES','1234567890123456',"123"), 'cdda83e8105929d720615d2e2919f517', 'OMAC/func+hex/5');
+is( omac_b64('AES','1234567890123456',"123"), 'zdqD6BBZKdcgYV0uKRn1Fw==', 'OMAC/func+b64/5');
+is( omac_b64u('AES','1234567890123456',"123"), 'zdqD6BBZKdcgYV0uKRn1Fw', 'OMAC/func+b64u/5');
+is( unpack('H*', Crypt::Mac::OMAC->new('AES','12345678901234561234567890123456')->add("123")->mac), '93cfd941f83b842afe81326332f25e32', 'OMAC/oo+raw/6');
+is( Crypt::Mac::OMAC->new('AES','12345678901234561234567890123456')->add("123")->hexmac, '93cfd941f83b842afe81326332f25e32', 'OMAC/oo+hex/6');
+is( unpack('H*', omac('AES','12345678901234561234567890123456',"123")), '93cfd941f83b842afe81326332f25e32', 'OMAC/func+raw/6');
+is( omac_hex('AES','12345678901234561234567890123456',"123"), '93cfd941f83b842afe81326332f25e32', 'OMAC/func+hex/6');
+is( omac_b64('AES','12345678901234561234567890123456',"123"), 'k8/ZQfg7hCr+gTJjMvJeMg==', 'OMAC/func+b64/6');
+is( omac_b64u('AES','12345678901234561234567890123456',"123"), 'k8_ZQfg7hCr-gTJjMvJeMg', 'OMAC/func+b64u/6');
+is( unpack('H*', Crypt::Mac::OMAC->new('Blowfish','1234567890123456')->add("123")->mac), '357f9876a15825ec', 'OMAC/oo+raw/7');
+is( Crypt::Mac::OMAC->new('Blowfish','1234567890123456')->add("123")->hexmac, '357f9876a15825ec', 'OMAC/oo+hex/7');
+is( unpack('H*', omac('Blowfish','1234567890123456',"123")), '357f9876a15825ec', 'OMAC/func+raw/7');
+is( omac_hex('Blowfish','1234567890123456',"123"), '357f9876a15825ec', 'OMAC/func+hex/7');
+is( omac_b64('Blowfish','1234567890123456',"123"), 'NX+YdqFYJew=', 'OMAC/func+b64/7');
+is( omac_b64u('Blowfish','1234567890123456',"123"), 'NX-YdqFYJew', 'OMAC/func+b64u/7');
+is( unpack('H*', Crypt::Mac::OMAC->new('Blowfish','12345678901234561234567890123456')->add("123")->mac), '357f9876a15825ec', 'OMAC/oo+raw/8');
+is( Crypt::Mac::OMAC->new('Blowfish','12345678901234561234567890123456')->add("123")->hexmac, '357f9876a15825ec', 'OMAC/oo+hex/8');
+is( unpack('H*', omac('Blowfish','12345678901234561234567890123456',"123")), '357f9876a15825ec', 'OMAC/func+raw/8');
+is( omac_hex('Blowfish','12345678901234561234567890123456',"123"), '357f9876a15825ec', 'OMAC/func+hex/8');
+is( omac_b64('Blowfish','12345678901234561234567890123456',"123"), 'NX+YdqFYJew=', 'OMAC/func+b64/8');
+is( omac_b64u('Blowfish','12345678901234561234567890123456',"123"), 'NX-YdqFYJew', 'OMAC/func+b64u/8');
is( unpack('H*', Crypt::Mac::OMAC->new('AES','1234567890123456')->add("test\0test\0test\n")->mac), '628848c1604f58010affc6ad6cf07135', 'OMAC/oo+raw/9');
is( Crypt::Mac::OMAC->new('AES','1234567890123456')->add("test\0test\0test\n")->hexmac, '628848c1604f58010affc6ad6cf07135', 'OMAC/oo+hex/9');
is( unpack('H*', omac('AES','1234567890123456',"test\0test\0test\n")), '628848c1604f58010affc6ad6cf07135', 'OMAC/func+raw/9');
is( omac_hex('AES','1234567890123456',"test\0test\0test\n"), '628848c1604f58010affc6ad6cf07135', 'OMAC/func+hex/9');
is( omac_b64('AES','1234567890123456',"test\0test\0test\n"), 'YohIwWBPWAEK/8atbPBxNQ==', 'OMAC/func+b64/9');
+is( omac_b64u('AES','1234567890123456',"test\0test\0test\n"), 'YohIwWBPWAEK_8atbPBxNQ', 'OMAC/func+b64u/9');
is( unpack('H*', Crypt::Mac::OMAC->new('AES','12345678901234561234567890123456')->add("test\0test\0test\n")->mac), '20d6c5cc640730d2b8bb9308031c000b', 'OMAC/oo+raw/10');
is( Crypt::Mac::OMAC->new('AES','12345678901234561234567890123456')->add("test\0test\0test\n")->hexmac, '20d6c5cc640730d2b8bb9308031c000b', 'OMAC/oo+hex/10');
is( unpack('H*', omac('AES','12345678901234561234567890123456',"test\0test\0test\n")), '20d6c5cc640730d2b8bb9308031c000b', 'OMAC/func+raw/10');
is( omac_hex('AES','12345678901234561234567890123456',"test\0test\0test\n"), '20d6c5cc640730d2b8bb9308031c000b', 'OMAC/func+hex/10');
is( omac_b64('AES','12345678901234561234567890123456',"test\0test\0test\n"), 'INbFzGQHMNK4u5MIAxwACw==', 'OMAC/func+b64/10');
+is( omac_b64u('AES','12345678901234561234567890123456',"test\0test\0test\n"), 'INbFzGQHMNK4u5MIAxwACw', 'OMAC/func+b64u/10');
is( unpack('H*', Crypt::Mac::OMAC->new('Blowfish','1234567890123456')->add("test\0test\0test\n")->mac), '40e6d018b49ada77', 'OMAC/oo+raw/11');
is( Crypt::Mac::OMAC->new('Blowfish','1234567890123456')->add("test\0test\0test\n")->hexmac, '40e6d018b49ada77', 'OMAC/oo+hex/11');
is( unpack('H*', omac('Blowfish','1234567890123456',"test\0test\0test\n")), '40e6d018b49ada77', 'OMAC/func+raw/11');
is( omac_hex('Blowfish','1234567890123456',"test\0test\0test\n"), '40e6d018b49ada77', 'OMAC/func+hex/11');
is( omac_b64('Blowfish','1234567890123456',"test\0test\0test\n"), 'QObQGLSa2nc=', 'OMAC/func+b64/11');
+is( omac_b64u('Blowfish','1234567890123456',"test\0test\0test\n"), 'QObQGLSa2nc', 'OMAC/func+b64u/11');
is( unpack('H*', Crypt::Mac::OMAC->new('Blowfish','12345678901234561234567890123456')->add("test\0test\0test\n")->mac), '40e6d018b49ada77', 'OMAC/oo+raw/12');
is( Crypt::Mac::OMAC->new('Blowfish','12345678901234561234567890123456')->add("test\0test\0test\n")->hexmac, '40e6d018b49ada77', 'OMAC/oo+hex/12');
is( unpack('H*', omac('Blowfish','12345678901234561234567890123456',"test\0test\0test\n")), '40e6d018b49ada77', 'OMAC/func+raw/12');
is( omac_hex('Blowfish','12345678901234561234567890123456',"test\0test\0test\n"), '40e6d018b49ada77', 'OMAC/func+hex/12');
is( omac_b64('Blowfish','12345678901234561234567890123456',"test\0test\0test\n"), 'QObQGLSa2nc=', 'OMAC/func+b64/12');
+is( omac_b64u('Blowfish','12345678901234561234567890123456',"test\0test\0test\n"), 'QObQGLSa2nc', 'OMAC/func+b64u/12');
done_testing();
diff --git a/t/mac_pelican.t b/t/mac_pelican.t
index 88fa6643..a3d2cfd0 100644
--- a/t/mac_pelican.t
+++ b/t/mac_pelican.t
@@ -5,67 +5,79 @@ use warnings;
use Test::More;
-use Crypt::Mac::Pelican qw( pelican pelican_hex pelican_b64 );
+use Crypt::Mac::Pelican qw( pelican pelican_hex pelican_b64 pelican_b64u );
is( unpack('H*', Crypt::Mac::Pelican->new('1234567890123456')->add("")->mac), '6b8e5fea81f2022a75357b1e9e8361f4', 'Pelican/oo+raw/1');
is( Crypt::Mac::Pelican->new('1234567890123456')->add("")->hexmac, '6b8e5fea81f2022a75357b1e9e8361f4', 'Pelican/oo+hex/1');
is( unpack('H*', pelican('1234567890123456',"")), '6b8e5fea81f2022a75357b1e9e8361f4', 'Pelican/func+raw/1');
is( pelican_hex('1234567890123456',""), '6b8e5fea81f2022a75357b1e9e8361f4', 'Pelican/func+hex/1');
is( pelican_b64('1234567890123456',""), 'a45f6oHyAip1NXsenoNh9A==', 'Pelican/func+b64/1');
+is( pelican_b64u('1234567890123456',""), 'a45f6oHyAip1NXsenoNh9A', 'Pelican/func+b64u/1');
is( unpack('H*', Crypt::Mac::Pelican->new('12345678901234561234567890123456')->add("")->mac), 'cd253e77578c3a76d20a4f87a582c1c4', 'Pelican/oo+raw/2');
is( Crypt::Mac::Pelican->new('12345678901234561234567890123456')->add("")->hexmac, 'cd253e77578c3a76d20a4f87a582c1c4', 'Pelican/oo+hex/2');
is( unpack('H*', pelican('12345678901234561234567890123456',"")), 'cd253e77578c3a76d20a4f87a582c1c4', 'Pelican/func+raw/2');
is( pelican_hex('12345678901234561234567890123456',""), 'cd253e77578c3a76d20a4f87a582c1c4', 'Pelican/func+hex/2');
is( pelican_b64('12345678901234561234567890123456',""), 'zSU+d1eMOnbSCk+HpYLBxA==', 'Pelican/func+b64/2');
+is( pelican_b64u('12345678901234561234567890123456',""), 'zSU-d1eMOnbSCk-HpYLBxA', 'Pelican/func+b64u/2');
is( unpack('H*', Crypt::Mac::Pelican->new('aaaaaaaaaaaaaaaa')->add("")->mac), '0976b1b1cbc3f4adae5254fb6626ffba', 'Pelican/oo+raw/3');
is( Crypt::Mac::Pelican->new('aaaaaaaaaaaaaaaa')->add("")->hexmac, '0976b1b1cbc3f4adae5254fb6626ffba', 'Pelican/oo+hex/3');
is( unpack('H*', pelican('aaaaaaaaaaaaaaaa',"")), '0976b1b1cbc3f4adae5254fb6626ffba', 'Pelican/func+raw/3');
is( pelican_hex('aaaaaaaaaaaaaaaa',""), '0976b1b1cbc3f4adae5254fb6626ffba', 'Pelican/func+hex/3');
is( pelican_b64('aaaaaaaaaaaaaaaa',""), 'CXaxscvD9K2uUlT7Zib/ug==', 'Pelican/func+b64/3');
+is( pelican_b64u('aaaaaaaaaaaaaaaa',""), 'CXaxscvD9K2uUlT7Zib_ug', 'Pelican/func+b64u/3');
is( unpack('H*', Crypt::Mac::Pelican->new('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')->add("")->mac), 'b8811ef21aeba6a89ee179c8a2a08bf5', 'Pelican/oo+raw/4');
is( Crypt::Mac::Pelican->new('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')->add("")->hexmac, 'b8811ef21aeba6a89ee179c8a2a08bf5', 'Pelican/oo+hex/4');
is( unpack('H*', pelican('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',"")), 'b8811ef21aeba6a89ee179c8a2a08bf5', 'Pelican/func+raw/4');
is( pelican_hex('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',""), 'b8811ef21aeba6a89ee179c8a2a08bf5', 'Pelican/func+hex/4');
is( pelican_b64('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',""), 'uIEe8hrrpqie4XnIoqCL9Q==', 'Pelican/func+b64/4');
-is( unpack('H*', Crypt::Mac::Pelican->new('1234567890123456')->add(123)->mac), 'fbb1d2c3aa308e82a14bfd8efc1cfdac', 'Pelican/oo+raw/5');
-is( Crypt::Mac::Pelican->new('1234567890123456')->add(123)->hexmac, 'fbb1d2c3aa308e82a14bfd8efc1cfdac', 'Pelican/oo+hex/5');
-is( unpack('H*', pelican('1234567890123456',123)), 'fbb1d2c3aa308e82a14bfd8efc1cfdac', 'Pelican/func+raw/5');
-is( pelican_hex('1234567890123456',123), 'fbb1d2c3aa308e82a14bfd8efc1cfdac', 'Pelican/func+hex/5');
-is( pelican_b64('1234567890123456',123), '+7HSw6owjoKhS/2O/Bz9rA==', 'Pelican/func+b64/5');
-is( unpack('H*', Crypt::Mac::Pelican->new('12345678901234561234567890123456')->add(123)->mac), '23c694903f3bce129255cc66a92fc0ca', 'Pelican/oo+raw/6');
-is( Crypt::Mac::Pelican->new('12345678901234561234567890123456')->add(123)->hexmac, '23c694903f3bce129255cc66a92fc0ca', 'Pelican/oo+hex/6');
-is( unpack('H*', pelican('12345678901234561234567890123456',123)), '23c694903f3bce129255cc66a92fc0ca', 'Pelican/func+raw/6');
-is( pelican_hex('12345678901234561234567890123456',123), '23c694903f3bce129255cc66a92fc0ca', 'Pelican/func+hex/6');
-is( pelican_b64('12345678901234561234567890123456',123), 'I8aUkD87zhKSVcxmqS/Ayg==', 'Pelican/func+b64/6');
-is( unpack('H*', Crypt::Mac::Pelican->new('aaaaaaaaaaaaaaaa')->add(123)->mac), '13b5ae418804ccc5c972069b56f3314e', 'Pelican/oo+raw/7');
-is( Crypt::Mac::Pelican->new('aaaaaaaaaaaaaaaa')->add(123)->hexmac, '13b5ae418804ccc5c972069b56f3314e', 'Pelican/oo+hex/7');
-is( unpack('H*', pelican('aaaaaaaaaaaaaaaa',123)), '13b5ae418804ccc5c972069b56f3314e', 'Pelican/func+raw/7');
-is( pelican_hex('aaaaaaaaaaaaaaaa',123), '13b5ae418804ccc5c972069b56f3314e', 'Pelican/func+hex/7');
-is( pelican_b64('aaaaaaaaaaaaaaaa',123), 'E7WuQYgEzMXJcgabVvMxTg==', 'Pelican/func+b64/7');
-is( unpack('H*', Crypt::Mac::Pelican->new('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')->add(123)->mac), 'b5d44a3b4e7fe8099ab63344dc906b2c', 'Pelican/oo+raw/8');
-is( Crypt::Mac::Pelican->new('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')->add(123)->hexmac, 'b5d44a3b4e7fe8099ab63344dc906b2c', 'Pelican/oo+hex/8');
-is( unpack('H*', pelican('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',123)), 'b5d44a3b4e7fe8099ab63344dc906b2c', 'Pelican/func+raw/8');
-is( pelican_hex('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',123), 'b5d44a3b4e7fe8099ab63344dc906b2c', 'Pelican/func+hex/8');
-is( pelican_b64('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',123), 'tdRKO05/6AmatjNE3JBrLA==', 'Pelican/func+b64/8');
+is( pelican_b64u('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',""), 'uIEe8hrrpqie4XnIoqCL9Q', 'Pelican/func+b64u/4');
+is( unpack('H*', Crypt::Mac::Pelican->new('1234567890123456')->add("123")->mac), 'fbb1d2c3aa308e82a14bfd8efc1cfdac', 'Pelican/oo+raw/5');
+is( Crypt::Mac::Pelican->new('1234567890123456')->add("123")->hexmac, 'fbb1d2c3aa308e82a14bfd8efc1cfdac', 'Pelican/oo+hex/5');
+is( unpack('H*', pelican('1234567890123456',"123")), 'fbb1d2c3aa308e82a14bfd8efc1cfdac', 'Pelican/func+raw/5');
+is( pelican_hex('1234567890123456',"123"), 'fbb1d2c3aa308e82a14bfd8efc1cfdac', 'Pelican/func+hex/5');
+is( pelican_b64('1234567890123456',"123"), '+7HSw6owjoKhS/2O/Bz9rA==', 'Pelican/func+b64/5');
+is( pelican_b64u('1234567890123456',"123"), '-7HSw6owjoKhS_2O_Bz9rA', 'Pelican/func+b64u/5');
+is( unpack('H*', Crypt::Mac::Pelican->new('12345678901234561234567890123456')->add("123")->mac), '23c694903f3bce129255cc66a92fc0ca', 'Pelican/oo+raw/6');
+is( Crypt::Mac::Pelican->new('12345678901234561234567890123456')->add("123")->hexmac, '23c694903f3bce129255cc66a92fc0ca', 'Pelican/oo+hex/6');
+is( unpack('H*', pelican('12345678901234561234567890123456',"123")), '23c694903f3bce129255cc66a92fc0ca', 'Pelican/func+raw/6');
+is( pelican_hex('12345678901234561234567890123456',"123"), '23c694903f3bce129255cc66a92fc0ca', 'Pelican/func+hex/6');
+is( pelican_b64('12345678901234561234567890123456',"123"), 'I8aUkD87zhKSVcxmqS/Ayg==', 'Pelican/func+b64/6');
+is( pelican_b64u('12345678901234561234567890123456',"123"), 'I8aUkD87zhKSVcxmqS_Ayg', 'Pelican/func+b64u/6');
+is( unpack('H*', Crypt::Mac::Pelican->new('aaaaaaaaaaaaaaaa')->add("123")->mac), '13b5ae418804ccc5c972069b56f3314e', 'Pelican/oo+raw/7');
+is( Crypt::Mac::Pelican->new('aaaaaaaaaaaaaaaa')->add("123")->hexmac, '13b5ae418804ccc5c972069b56f3314e', 'Pelican/oo+hex/7');
+is( unpack('H*', pelican('aaaaaaaaaaaaaaaa',"123")), '13b5ae418804ccc5c972069b56f3314e', 'Pelican/func+raw/7');
+is( pelican_hex('aaaaaaaaaaaaaaaa',"123"), '13b5ae418804ccc5c972069b56f3314e', 'Pelican/func+hex/7');
+is( pelican_b64('aaaaaaaaaaaaaaaa',"123"), 'E7WuQYgEzMXJcgabVvMxTg==', 'Pelican/func+b64/7');
+is( pelican_b64u('aaaaaaaaaaaaaaaa',"123"), 'E7WuQYgEzMXJcgabVvMxTg', 'Pelican/func+b64u/7');
+is( unpack('H*', Crypt::Mac::Pelican->new('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')->add("123")->mac), 'b5d44a3b4e7fe8099ab63344dc906b2c', 'Pelican/oo+raw/8');
+is( Crypt::Mac::Pelican->new('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')->add("123")->hexmac, 'b5d44a3b4e7fe8099ab63344dc906b2c', 'Pelican/oo+hex/8');
+is( unpack('H*', pelican('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',"123")), 'b5d44a3b4e7fe8099ab63344dc906b2c', 'Pelican/func+raw/8');
+is( pelican_hex('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',"123"), 'b5d44a3b4e7fe8099ab63344dc906b2c', 'Pelican/func+hex/8');
+is( pelican_b64('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',"123"), 'tdRKO05/6AmatjNE3JBrLA==', 'Pelican/func+b64/8');
+is( pelican_b64u('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',"123"), 'tdRKO05_6AmatjNE3JBrLA', 'Pelican/func+b64u/8');
is( unpack('H*', Crypt::Mac::Pelican->new('1234567890123456')->add("test\0test\0test\n")->mac), '5d884e5a46bbd02497d0c9ecc2739822', 'Pelican/oo+raw/9');
is( Crypt::Mac::Pelican->new('1234567890123456')->add("test\0test\0test\n")->hexmac, '5d884e5a46bbd02497d0c9ecc2739822', 'Pelican/oo+hex/9');
is( unpack('H*', pelican('1234567890123456',"test\0test\0test\n")), '5d884e5a46bbd02497d0c9ecc2739822', 'Pelican/func+raw/9');
is( pelican_hex('1234567890123456',"test\0test\0test\n"), '5d884e5a46bbd02497d0c9ecc2739822', 'Pelican/func+hex/9');
is( pelican_b64('1234567890123456',"test\0test\0test\n"), 'XYhOWka70CSX0MnswnOYIg==', 'Pelican/func+b64/9');
+is( pelican_b64u('1234567890123456',"test\0test\0test\n"), 'XYhOWka70CSX0MnswnOYIg', 'Pelican/func+b64u/9');
is( unpack('H*', Crypt::Mac::Pelican->new('12345678901234561234567890123456')->add("test\0test\0test\n")->mac), 'cf279a49ccf7798130d907840056d222', 'Pelican/oo+raw/10');
is( Crypt::Mac::Pelican->new('12345678901234561234567890123456')->add("test\0test\0test\n")->hexmac, 'cf279a49ccf7798130d907840056d222', 'Pelican/oo+hex/10');
is( unpack('H*', pelican('12345678901234561234567890123456',"test\0test\0test\n")), 'cf279a49ccf7798130d907840056d222', 'Pelican/func+raw/10');
is( pelican_hex('12345678901234561234567890123456',"test\0test\0test\n"), 'cf279a49ccf7798130d907840056d222', 'Pelican/func+hex/10');
is( pelican_b64('12345678901234561234567890123456',"test\0test\0test\n"), 'zyeaScz3eYEw2QeEAFbSIg==', 'Pelican/func+b64/10');
+is( pelican_b64u('12345678901234561234567890123456',"test\0test\0test\n"), 'zyeaScz3eYEw2QeEAFbSIg', 'Pelican/func+b64u/10');
is( unpack('H*', Crypt::Mac::Pelican->new('aaaaaaaaaaaaaaaa')->add("test\0test\0test\n")->mac), 'c21e437bee0261e55e66735cb6d4bd56', 'Pelican/oo+raw/11');
is( Crypt::Mac::Pelican->new('aaaaaaaaaaaaaaaa')->add("test\0test\0test\n")->hexmac, 'c21e437bee0261e55e66735cb6d4bd56', 'Pelican/oo+hex/11');
is( unpack('H*', pelican('aaaaaaaaaaaaaaaa',"test\0test\0test\n")), 'c21e437bee0261e55e66735cb6d4bd56', 'Pelican/func+raw/11');
is( pelican_hex('aaaaaaaaaaaaaaaa',"test\0test\0test\n"), 'c21e437bee0261e55e66735cb6d4bd56', 'Pelican/func+hex/11');
is( pelican_b64('aaaaaaaaaaaaaaaa',"test\0test\0test\n"), 'wh5De+4CYeVeZnNcttS9Vg==', 'Pelican/func+b64/11');
+is( pelican_b64u('aaaaaaaaaaaaaaaa',"test\0test\0test\n"), 'wh5De-4CYeVeZnNcttS9Vg', 'Pelican/func+b64u/11');
is( unpack('H*', Crypt::Mac::Pelican->new('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')->add("test\0test\0test\n")->mac), '8a798fcb2181d9f9ed81fcd2a7f6cd4e', 'Pelican/oo+raw/12');
is( Crypt::Mac::Pelican->new('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')->add("test\0test\0test\n")->hexmac, '8a798fcb2181d9f9ed81fcd2a7f6cd4e', 'Pelican/oo+hex/12');
is( unpack('H*', pelican('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',"test\0test\0test\n")), '8a798fcb2181d9f9ed81fcd2a7f6cd4e', 'Pelican/func+raw/12');
is( pelican_hex('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',"test\0test\0test\n"), '8a798fcb2181d9f9ed81fcd2a7f6cd4e', 'Pelican/func+hex/12');
is( pelican_b64('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',"test\0test\0test\n"), 'inmPyyGB2fntgfzSp/bNTg==', 'Pelican/func+b64/12');
+is( pelican_b64u('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',"test\0test\0test\n"), 'inmPyyGB2fntgfzSp_bNTg', 'Pelican/func+b64u/12');
done_testing();
diff --git a/t/mac_pmac.t b/t/mac_pmac.t
index eaad31e1..459871f8 100644
--- a/t/mac_pmac.t
+++ b/t/mac_pmac.t
@@ -5,67 +5,79 @@ use warnings;
use Test::More;
-use Crypt::Mac::PMAC qw( pmac pmac_hex pmac_b64 );
+use Crypt::Mac::PMAC qw( pmac pmac_hex pmac_b64 pmac_b64u );
is( unpack('H*', Crypt::Mac::PMAC->new('AES','1234567890123456')->add("")->mac), '877a45a3b73543ec5cfde831c82998b2', 'PMAC/oo+raw/1');
is( Crypt::Mac::PMAC->new('AES','1234567890123456')->add("")->hexmac, '877a45a3b73543ec5cfde831c82998b2', 'PMAC/oo+hex/1');
is( unpack('H*', pmac('AES','1234567890123456',"")), '877a45a3b73543ec5cfde831c82998b2', 'PMAC/func+raw/1');
is( pmac_hex('AES','1234567890123456',""), '877a45a3b73543ec5cfde831c82998b2', 'PMAC/func+hex/1');
is( pmac_b64('AES','1234567890123456',""), 'h3pFo7c1Q+xc/egxyCmYsg==', 'PMAC/func+b64/1');
+is( pmac_b64u('AES','1234567890123456',""), 'h3pFo7c1Q-xc_egxyCmYsg', 'PMAC/func+b64u/1');
is( unpack('H*', Crypt::Mac::PMAC->new('AES','12345678901234561234567890123456')->add("")->mac), '4fd07f0e3726d907fea45ab72c276b04', 'PMAC/oo+raw/2');
is( Crypt::Mac::PMAC->new('AES','12345678901234561234567890123456')->add("")->hexmac, '4fd07f0e3726d907fea45ab72c276b04', 'PMAC/oo+hex/2');
is( unpack('H*', pmac('AES','12345678901234561234567890123456',"")), '4fd07f0e3726d907fea45ab72c276b04', 'PMAC/func+raw/2');
is( pmac_hex('AES','12345678901234561234567890123456',""), '4fd07f0e3726d907fea45ab72c276b04', 'PMAC/func+hex/2');
is( pmac_b64('AES','12345678901234561234567890123456',""), 'T9B/Djcm2Qf+pFq3LCdrBA==', 'PMAC/func+b64/2');
+is( pmac_b64u('AES','12345678901234561234567890123456',""), 'T9B_Djcm2Qf-pFq3LCdrBA', 'PMAC/func+b64u/2');
is( unpack('H*', Crypt::Mac::PMAC->new('Blowfish','1234567890123456')->add("")->mac), '9b9a50f5d0362a8b', 'PMAC/oo+raw/3');
is( Crypt::Mac::PMAC->new('Blowfish','1234567890123456')->add("")->hexmac, '9b9a50f5d0362a8b', 'PMAC/oo+hex/3');
is( unpack('H*', pmac('Blowfish','1234567890123456',"")), '9b9a50f5d0362a8b', 'PMAC/func+raw/3');
is( pmac_hex('Blowfish','1234567890123456',""), '9b9a50f5d0362a8b', 'PMAC/func+hex/3');
is( pmac_b64('Blowfish','1234567890123456',""), 'm5pQ9dA2Kos=', 'PMAC/func+b64/3');
+is( pmac_b64u('Blowfish','1234567890123456',""), 'm5pQ9dA2Kos', 'PMAC/func+b64u/3');
is( unpack('H*', Crypt::Mac::PMAC->new('Blowfish','12345678901234561234567890123456')->add("")->mac), '9b9a50f5d0362a8b', 'PMAC/oo+raw/4');
is( Crypt::Mac::PMAC->new('Blowfish','12345678901234561234567890123456')->add("")->hexmac, '9b9a50f5d0362a8b', 'PMAC/oo+hex/4');
is( unpack('H*', pmac('Blowfish','12345678901234561234567890123456',"")), '9b9a50f5d0362a8b', 'PMAC/func+raw/4');
is( pmac_hex('Blowfish','12345678901234561234567890123456',""), '9b9a50f5d0362a8b', 'PMAC/func+hex/4');
is( pmac_b64('Blowfish','12345678901234561234567890123456',""), 'm5pQ9dA2Kos=', 'PMAC/func+b64/4');
-is( unpack('H*', Crypt::Mac::PMAC->new('AES','1234567890123456')->add(123)->mac), '180cbe007c36eb4abce45430c079a4d4', 'PMAC/oo+raw/5');
-is( Crypt::Mac::PMAC->new('AES','1234567890123456')->add(123)->hexmac, '180cbe007c36eb4abce45430c079a4d4', 'PMAC/oo+hex/5');
-is( unpack('H*', pmac('AES','1234567890123456',123)), '180cbe007c36eb4abce45430c079a4d4', 'PMAC/func+raw/5');
-is( pmac_hex('AES','1234567890123456',123), '180cbe007c36eb4abce45430c079a4d4', 'PMAC/func+hex/5');
-is( pmac_b64('AES','1234567890123456',123), 'GAy+AHw260q85FQwwHmk1A==', 'PMAC/func+b64/5');
-is( unpack('H*', Crypt::Mac::PMAC->new('AES','12345678901234561234567890123456')->add(123)->mac), 'b5c5ca8f2227bf207c4c5cb6f465b664', 'PMAC/oo+raw/6');
-is( Crypt::Mac::PMAC->new('AES','12345678901234561234567890123456')->add(123)->hexmac, 'b5c5ca8f2227bf207c4c5cb6f465b664', 'PMAC/oo+hex/6');
-is( unpack('H*', pmac('AES','12345678901234561234567890123456',123)), 'b5c5ca8f2227bf207c4c5cb6f465b664', 'PMAC/func+raw/6');
-is( pmac_hex('AES','12345678901234561234567890123456',123), 'b5c5ca8f2227bf207c4c5cb6f465b664', 'PMAC/func+hex/6');
-is( pmac_b64('AES','12345678901234561234567890123456',123), 'tcXKjyInvyB8TFy29GW2ZA==', 'PMAC/func+b64/6');
-is( unpack('H*', Crypt::Mac::PMAC->new('Blowfish','1234567890123456')->add(123)->mac), '9df08c664a191e9f', 'PMAC/oo+raw/7');
-is( Crypt::Mac::PMAC->new('Blowfish','1234567890123456')->add(123)->hexmac, '9df08c664a191e9f', 'PMAC/oo+hex/7');
-is( unpack('H*', pmac('Blowfish','1234567890123456',123)), '9df08c664a191e9f', 'PMAC/func+raw/7');
-is( pmac_hex('Blowfish','1234567890123456',123), '9df08c664a191e9f', 'PMAC/func+hex/7');
-is( pmac_b64('Blowfish','1234567890123456',123), 'nfCMZkoZHp8=', 'PMAC/func+b64/7');
-is( unpack('H*', Crypt::Mac::PMAC->new('Blowfish','12345678901234561234567890123456')->add(123)->mac), '9df08c664a191e9f', 'PMAC/oo+raw/8');
-is( Crypt::Mac::PMAC->new('Blowfish','12345678901234561234567890123456')->add(123)->hexmac, '9df08c664a191e9f', 'PMAC/oo+hex/8');
-is( unpack('H*', pmac('Blowfish','12345678901234561234567890123456',123)), '9df08c664a191e9f', 'PMAC/func+raw/8');
-is( pmac_hex('Blowfish','12345678901234561234567890123456',123), '9df08c664a191e9f', 'PMAC/func+hex/8');
-is( pmac_b64('Blowfish','12345678901234561234567890123456',123), 'nfCMZkoZHp8=', 'PMAC/func+b64/8');
+is( pmac_b64u('Blowfish','12345678901234561234567890123456',""), 'm5pQ9dA2Kos', 'PMAC/func+b64u/4');
+is( unpack('H*', Crypt::Mac::PMAC->new('AES','1234567890123456')->add("123")->mac), '180cbe007c36eb4abce45430c079a4d4', 'PMAC/oo+raw/5');
+is( Crypt::Mac::PMAC->new('AES','1234567890123456')->add("123")->hexmac, '180cbe007c36eb4abce45430c079a4d4', 'PMAC/oo+hex/5');
+is( unpack('H*', pmac('AES','1234567890123456',"123")), '180cbe007c36eb4abce45430c079a4d4', 'PMAC/func+raw/5');
+is( pmac_hex('AES','1234567890123456',"123"), '180cbe007c36eb4abce45430c079a4d4', 'PMAC/func+hex/5');
+is( pmac_b64('AES','1234567890123456',"123"), 'GAy+AHw260q85FQwwHmk1A==', 'PMAC/func+b64/5');
+is( pmac_b64u('AES','1234567890123456',"123"), 'GAy-AHw260q85FQwwHmk1A', 'PMAC/func+b64u/5');
+is( unpack('H*', Crypt::Mac::PMAC->new('AES','12345678901234561234567890123456')->add("123")->mac), 'b5c5ca8f2227bf207c4c5cb6f465b664', 'PMAC/oo+raw/6');
+is( Crypt::Mac::PMAC->new('AES','12345678901234561234567890123456')->add("123")->hexmac, 'b5c5ca8f2227bf207c4c5cb6f465b664', 'PMAC/oo+hex/6');
+is( unpack('H*', pmac('AES','12345678901234561234567890123456',"123")), 'b5c5ca8f2227bf207c4c5cb6f465b664', 'PMAC/func+raw/6');
+is( pmac_hex('AES','12345678901234561234567890123456',"123"), 'b5c5ca8f2227bf207c4c5cb6f465b664', 'PMAC/func+hex/6');
+is( pmac_b64('AES','12345678901234561234567890123456',"123"), 'tcXKjyInvyB8TFy29GW2ZA==', 'PMAC/func+b64/6');
+is( pmac_b64u('AES','12345678901234561234567890123456',"123"), 'tcXKjyInvyB8TFy29GW2ZA', 'PMAC/func+b64u/6');
+is( unpack('H*', Crypt::Mac::PMAC->new('Blowfish','1234567890123456')->add("123")->mac), '9df08c664a191e9f', 'PMAC/oo+raw/7');
+is( Crypt::Mac::PMAC->new('Blowfish','1234567890123456')->add("123")->hexmac, '9df08c664a191e9f', 'PMAC/oo+hex/7');
+is( unpack('H*', pmac('Blowfish','1234567890123456',"123")), '9df08c664a191e9f', 'PMAC/func+raw/7');
+is( pmac_hex('Blowfish','1234567890123456',"123"), '9df08c664a191e9f', 'PMAC/func+hex/7');
+is( pmac_b64('Blowfish','1234567890123456',"123"), 'nfCMZkoZHp8=', 'PMAC/func+b64/7');
+is( pmac_b64u('Blowfish','1234567890123456',"123"), 'nfCMZkoZHp8', 'PMAC/func+b64u/7');
+is( unpack('H*', Crypt::Mac::PMAC->new('Blowfish','12345678901234561234567890123456')->add("123")->mac), '9df08c664a191e9f', 'PMAC/oo+raw/8');
+is( Crypt::Mac::PMAC->new('Blowfish','12345678901234561234567890123456')->add("123")->hexmac, '9df08c664a191e9f', 'PMAC/oo+hex/8');
+is( unpack('H*', pmac('Blowfish','12345678901234561234567890123456',"123")), '9df08c664a191e9f', 'PMAC/func+raw/8');
+is( pmac_hex('Blowfish','12345678901234561234567890123456',"123"), '9df08c664a191e9f', 'PMAC/func+hex/8');
+is( pmac_b64('Blowfish','12345678901234561234567890123456',"123"), 'nfCMZkoZHp8=', 'PMAC/func+b64/8');
+is( pmac_b64u('Blowfish','12345678901234561234567890123456',"123"), 'nfCMZkoZHp8', 'PMAC/func+b64u/8');
is( unpack('H*', Crypt::Mac::PMAC->new('AES','1234567890123456')->add("test\0test\0test\n")->mac), '86bb8eeec8f0ece63582f64f14a9e60c', 'PMAC/oo+raw/9');
is( Crypt::Mac::PMAC->new('AES','1234567890123456')->add("test\0test\0test\n")->hexmac, '86bb8eeec8f0ece63582f64f14a9e60c', 'PMAC/oo+hex/9');
is( unpack('H*', pmac('AES','1234567890123456',"test\0test\0test\n")), '86bb8eeec8f0ece63582f64f14a9e60c', 'PMAC/func+raw/9');
is( pmac_hex('AES','1234567890123456',"test\0test\0test\n"), '86bb8eeec8f0ece63582f64f14a9e60c', 'PMAC/func+hex/9');
is( pmac_b64('AES','1234567890123456',"test\0test\0test\n"), 'hruO7sjw7OY1gvZPFKnmDA==', 'PMAC/func+b64/9');
+is( pmac_b64u('AES','1234567890123456',"test\0test\0test\n"), 'hruO7sjw7OY1gvZPFKnmDA', 'PMAC/func+b64u/9');
is( unpack('H*', Crypt::Mac::PMAC->new('AES','12345678901234561234567890123456')->add("test\0test\0test\n")->mac), '465b8c31fe8f9f6c9089497e2a312c50', 'PMAC/oo+raw/10');
is( Crypt::Mac::PMAC->new('AES','12345678901234561234567890123456')->add("test\0test\0test\n")->hexmac, '465b8c31fe8f9f6c9089497e2a312c50', 'PMAC/oo+hex/10');
is( unpack('H*', pmac('AES','12345678901234561234567890123456',"test\0test\0test\n")), '465b8c31fe8f9f6c9089497e2a312c50', 'PMAC/func+raw/10');
is( pmac_hex('AES','12345678901234561234567890123456',"test\0test\0test\n"), '465b8c31fe8f9f6c9089497e2a312c50', 'PMAC/func+hex/10');
is( pmac_b64('AES','12345678901234561234567890123456',"test\0test\0test\n"), 'RluMMf6Pn2yQiUl+KjEsUA==', 'PMAC/func+b64/10');
+is( pmac_b64u('AES','12345678901234561234567890123456',"test\0test\0test\n"), 'RluMMf6Pn2yQiUl-KjEsUA', 'PMAC/func+b64u/10');
is( unpack('H*', Crypt::Mac::PMAC->new('Blowfish','1234567890123456')->add("test\0test\0test\n")->mac), '3797cde072a8e286', 'PMAC/oo+raw/11');
is( Crypt::Mac::PMAC->new('Blowfish','1234567890123456')->add("test\0test\0test\n")->hexmac, '3797cde072a8e286', 'PMAC/oo+hex/11');
is( unpack('H*', pmac('Blowfish','1234567890123456',"test\0test\0test\n")), '3797cde072a8e286', 'PMAC/func+raw/11');
is( pmac_hex('Blowfish','1234567890123456',"test\0test\0test\n"), '3797cde072a8e286', 'PMAC/func+hex/11');
is( pmac_b64('Blowfish','1234567890123456',"test\0test\0test\n"), 'N5fN4HKo4oY=', 'PMAC/func+b64/11');
+is( pmac_b64u('Blowfish','1234567890123456',"test\0test\0test\n"), 'N5fN4HKo4oY', 'PMAC/func+b64u/11');
is( unpack('H*', Crypt::Mac::PMAC->new('Blowfish','12345678901234561234567890123456')->add("test\0test\0test\n")->mac), '3797cde072a8e286', 'PMAC/oo+raw/12');
is( Crypt::Mac::PMAC->new('Blowfish','12345678901234561234567890123456')->add("test\0test\0test\n")->hexmac, '3797cde072a8e286', 'PMAC/oo+hex/12');
is( unpack('H*', pmac('Blowfish','12345678901234561234567890123456',"test\0test\0test\n")), '3797cde072a8e286', 'PMAC/func+raw/12');
is( pmac_hex('Blowfish','12345678901234561234567890123456',"test\0test\0test\n"), '3797cde072a8e286', 'PMAC/func+hex/12');
is( pmac_b64('Blowfish','12345678901234561234567890123456',"test\0test\0test\n"), 'N5fN4HKo4oY=', 'PMAC/func+b64/12');
+is( pmac_b64u('Blowfish','12345678901234561234567890123456',"test\0test\0test\n"), 'N5fN4HKo4oY', 'PMAC/func+b64u/12');
done_testing();
diff --git a/t/mac_xcbc.t b/t/mac_xcbc.t
index a3b1261f..b78b6a4e 100644
--- a/t/mac_xcbc.t
+++ b/t/mac_xcbc.t
@@ -5,67 +5,79 @@ use warnings;
use Test::More;
-use Crypt::Mac::XCBC qw( xcbc xcbc_hex xcbc_b64 );
+use Crypt::Mac::XCBC qw( xcbc xcbc_hex xcbc_b64 xcbc_b64u );
is( unpack('H*', Crypt::Mac::XCBC->new('AES','1234567890123456')->add("")->mac), '16f66d6127b7fc067e623d157a86b822', 'XCBC/oo+raw/1');
is( Crypt::Mac::XCBC->new('AES','1234567890123456')->add("")->hexmac, '16f66d6127b7fc067e623d157a86b822', 'XCBC/oo+hex/1');
is( unpack('H*', xcbc('AES','1234567890123456',"")), '16f66d6127b7fc067e623d157a86b822', 'XCBC/func+raw/1');
is( xcbc_hex('AES','1234567890123456',""), '16f66d6127b7fc067e623d157a86b822', 'XCBC/func+hex/1');
is( xcbc_b64('AES','1234567890123456',""), 'FvZtYSe3/AZ+Yj0Veoa4Ig==', 'XCBC/func+b64/1');
+is( xcbc_b64u('AES','1234567890123456',""), 'FvZtYSe3_AZ-Yj0Veoa4Ig', 'XCBC/func+b64u/1');
is( unpack('H*', Crypt::Mac::XCBC->new('AES','12345678901234561234567890123456')->add("")->mac), '744807bdb50aca24685b6bc78161c229', 'XCBC/oo+raw/2');
is( Crypt::Mac::XCBC->new('AES','12345678901234561234567890123456')->add("")->hexmac, '744807bdb50aca24685b6bc78161c229', 'XCBC/oo+hex/2');
is( unpack('H*', xcbc('AES','12345678901234561234567890123456',"")), '744807bdb50aca24685b6bc78161c229', 'XCBC/func+raw/2');
is( xcbc_hex('AES','12345678901234561234567890123456',""), '744807bdb50aca24685b6bc78161c229', 'XCBC/func+hex/2');
is( xcbc_b64('AES','12345678901234561234567890123456',""), 'dEgHvbUKyiRoW2vHgWHCKQ==', 'XCBC/func+b64/2');
+is( xcbc_b64u('AES','12345678901234561234567890123456',""), 'dEgHvbUKyiRoW2vHgWHCKQ', 'XCBC/func+b64u/2');
is( unpack('H*', Crypt::Mac::XCBC->new('Blowfish','1234567890123456')->add("")->mac), '9ef018b3c33f6f35', 'XCBC/oo+raw/3');
is( Crypt::Mac::XCBC->new('Blowfish','1234567890123456')->add("")->hexmac, '9ef018b3c33f6f35', 'XCBC/oo+hex/3');
is( unpack('H*', xcbc('Blowfish','1234567890123456',"")), '9ef018b3c33f6f35', 'XCBC/func+raw/3');
is( xcbc_hex('Blowfish','1234567890123456',""), '9ef018b3c33f6f35', 'XCBC/func+hex/3');
is( xcbc_b64('Blowfish','1234567890123456',""), 'nvAYs8M/bzU=', 'XCBC/func+b64/3');
+is( xcbc_b64u('Blowfish','1234567890123456',""), 'nvAYs8M_bzU', 'XCBC/func+b64u/3');
is( unpack('H*', Crypt::Mac::XCBC->new('Blowfish','12345678901234561234567890123456')->add("")->mac), '9ef018b3c33f6f35', 'XCBC/oo+raw/4');
is( Crypt::Mac::XCBC->new('Blowfish','12345678901234561234567890123456')->add("")->hexmac, '9ef018b3c33f6f35', 'XCBC/oo+hex/4');
is( unpack('H*', xcbc('Blowfish','12345678901234561234567890123456',"")), '9ef018b3c33f6f35', 'XCBC/func+raw/4');
is( xcbc_hex('Blowfish','12345678901234561234567890123456',""), '9ef018b3c33f6f35', 'XCBC/func+hex/4');
is( xcbc_b64('Blowfish','12345678901234561234567890123456',""), 'nvAYs8M/bzU=', 'XCBC/func+b64/4');
-is( unpack('H*', Crypt::Mac::XCBC->new('AES','1234567890123456')->add(123)->mac), 'bc9e0ee2a05a751b5ab25ddf0da158ea', 'XCBC/oo+raw/5');
-is( Crypt::Mac::XCBC->new('AES','1234567890123456')->add(123)->hexmac, 'bc9e0ee2a05a751b5ab25ddf0da158ea', 'XCBC/oo+hex/5');
-is( unpack('H*', xcbc('AES','1234567890123456',123)), 'bc9e0ee2a05a751b5ab25ddf0da158ea', 'XCBC/func+raw/5');
-is( xcbc_hex('AES','1234567890123456',123), 'bc9e0ee2a05a751b5ab25ddf0da158ea', 'XCBC/func+hex/5');
-is( xcbc_b64('AES','1234567890123456',123), 'vJ4O4qBadRtasl3fDaFY6g==', 'XCBC/func+b64/5');
-is( unpack('H*', Crypt::Mac::XCBC->new('AES','12345678901234561234567890123456')->add(123)->mac), 'c0a87d7fa68bb2a7e18ad56808ec4eb3', 'XCBC/oo+raw/6');
-is( Crypt::Mac::XCBC->new('AES','12345678901234561234567890123456')->add(123)->hexmac, 'c0a87d7fa68bb2a7e18ad56808ec4eb3', 'XCBC/oo+hex/6');
-is( unpack('H*', xcbc('AES','12345678901234561234567890123456',123)), 'c0a87d7fa68bb2a7e18ad56808ec4eb3', 'XCBC/func+raw/6');
-is( xcbc_hex('AES','12345678901234561234567890123456',123), 'c0a87d7fa68bb2a7e18ad56808ec4eb3', 'XCBC/func+hex/6');
-is( xcbc_b64('AES','12345678901234561234567890123456',123), 'wKh9f6aLsqfhitVoCOxOsw==', 'XCBC/func+b64/6');
-is( unpack('H*', Crypt::Mac::XCBC->new('Blowfish','1234567890123456')->add(123)->mac), '21e88fbfb47a3200', 'XCBC/oo+raw/7');
-is( Crypt::Mac::XCBC->new('Blowfish','1234567890123456')->add(123)->hexmac, '21e88fbfb47a3200', 'XCBC/oo+hex/7');
-is( unpack('H*', xcbc('Blowfish','1234567890123456',123)), '21e88fbfb47a3200', 'XCBC/func+raw/7');
-is( xcbc_hex('Blowfish','1234567890123456',123), '21e88fbfb47a3200', 'XCBC/func+hex/7');
-is( xcbc_b64('Blowfish','1234567890123456',123), 'IeiPv7R6MgA=', 'XCBC/func+b64/7');
-is( unpack('H*', Crypt::Mac::XCBC->new('Blowfish','12345678901234561234567890123456')->add(123)->mac), '21e88fbfb47a3200', 'XCBC/oo+raw/8');
-is( Crypt::Mac::XCBC->new('Blowfish','12345678901234561234567890123456')->add(123)->hexmac, '21e88fbfb47a3200', 'XCBC/oo+hex/8');
-is( unpack('H*', xcbc('Blowfish','12345678901234561234567890123456',123)), '21e88fbfb47a3200', 'XCBC/func+raw/8');
-is( xcbc_hex('Blowfish','12345678901234561234567890123456',123), '21e88fbfb47a3200', 'XCBC/func+hex/8');
-is( xcbc_b64('Blowfish','12345678901234561234567890123456',123), 'IeiPv7R6MgA=', 'XCBC/func+b64/8');
+is( xcbc_b64u('Blowfish','12345678901234561234567890123456',""), 'nvAYs8M_bzU', 'XCBC/func+b64u/4');
+is( unpack('H*', Crypt::Mac::XCBC->new('AES','1234567890123456')->add("123")->mac), 'bc9e0ee2a05a751b5ab25ddf0da158ea', 'XCBC/oo+raw/5');
+is( Crypt::Mac::XCBC->new('AES','1234567890123456')->add("123")->hexmac, 'bc9e0ee2a05a751b5ab25ddf0da158ea', 'XCBC/oo+hex/5');
+is( unpack('H*', xcbc('AES','1234567890123456',"123")), 'bc9e0ee2a05a751b5ab25ddf0da158ea', 'XCBC/func+raw/5');
+is( xcbc_hex('AES','1234567890123456',"123"), 'bc9e0ee2a05a751b5ab25ddf0da158ea', 'XCBC/func+hex/5');
+is( xcbc_b64('AES','1234567890123456',"123"), 'vJ4O4qBadRtasl3fDaFY6g==', 'XCBC/func+b64/5');
+is( xcbc_b64u('AES','1234567890123456',"123"), 'vJ4O4qBadRtasl3fDaFY6g', 'XCBC/func+b64u/5');
+is( unpack('H*', Crypt::Mac::XCBC->new('AES','12345678901234561234567890123456')->add("123")->mac), 'c0a87d7fa68bb2a7e18ad56808ec4eb3', 'XCBC/oo+raw/6');
+is( Crypt::Mac::XCBC->new('AES','12345678901234561234567890123456')->add("123")->hexmac, 'c0a87d7fa68bb2a7e18ad56808ec4eb3', 'XCBC/oo+hex/6');
+is( unpack('H*', xcbc('AES','12345678901234561234567890123456',"123")), 'c0a87d7fa68bb2a7e18ad56808ec4eb3', 'XCBC/func+raw/6');
+is( xcbc_hex('AES','12345678901234561234567890123456',"123"), 'c0a87d7fa68bb2a7e18ad56808ec4eb3', 'XCBC/func+hex/6');
+is( xcbc_b64('AES','12345678901234561234567890123456',"123"), 'wKh9f6aLsqfhitVoCOxOsw==', 'XCBC/func+b64/6');
+is( xcbc_b64u('AES','12345678901234561234567890123456',"123"), 'wKh9f6aLsqfhitVoCOxOsw', 'XCBC/func+b64u/6');
+is( unpack('H*', Crypt::Mac::XCBC->new('Blowfish','1234567890123456')->add("123")->mac), '21e88fbfb47a3200', 'XCBC/oo+raw/7');
+is( Crypt::Mac::XCBC->new('Blowfish','1234567890123456')->add("123")->hexmac, '21e88fbfb47a3200', 'XCBC/oo+hex/7');
+is( unpack('H*', xcbc('Blowfish','1234567890123456',"123")), '21e88fbfb47a3200', 'XCBC/func+raw/7');
+is( xcbc_hex('Blowfish','1234567890123456',"123"), '21e88fbfb47a3200', 'XCBC/func+hex/7');
+is( xcbc_b64('Blowfish','1234567890123456',"123"), 'IeiPv7R6MgA=', 'XCBC/func+b64/7');
+is( xcbc_b64u('Blowfish','1234567890123456',"123"), 'IeiPv7R6MgA', 'XCBC/func+b64u/7');
+is( unpack('H*', Crypt::Mac::XCBC->new('Blowfish','12345678901234561234567890123456')->add("123")->mac), '21e88fbfb47a3200', 'XCBC/oo+raw/8');
+is( Crypt::Mac::XCBC->new('Blowfish','12345678901234561234567890123456')->add("123")->hexmac, '21e88fbfb47a3200', 'XCBC/oo+hex/8');
+is( unpack('H*', xcbc('Blowfish','12345678901234561234567890123456',"123")), '21e88fbfb47a3200', 'XCBC/func+raw/8');
+is( xcbc_hex('Blowfish','12345678901234561234567890123456',"123"), '21e88fbfb47a3200', 'XCBC/func+hex/8');
+is( xcbc_b64('Blowfish','12345678901234561234567890123456',"123"), 'IeiPv7R6MgA=', 'XCBC/func+b64/8');
+is( xcbc_b64u('Blowfish','12345678901234561234567890123456',"123"), 'IeiPv7R6MgA', 'XCBC/func+b64u/8');
is( unpack('H*', Crypt::Mac::XCBC->new('AES','1234567890123456')->add("test\0test\0test\n")->mac), '94cf668c4bbbb2bc0fc0bf14612084b9', 'XCBC/oo+raw/9');
is( Crypt::Mac::XCBC->new('AES','1234567890123456')->add("test\0test\0test\n")->hexmac, '94cf668c4bbbb2bc0fc0bf14612084b9', 'XCBC/oo+hex/9');
is( unpack('H*', xcbc('AES','1234567890123456',"test\0test\0test\n")), '94cf668c4bbbb2bc0fc0bf14612084b9', 'XCBC/func+raw/9');
is( xcbc_hex('AES','1234567890123456',"test\0test\0test\n"), '94cf668c4bbbb2bc0fc0bf14612084b9', 'XCBC/func+hex/9');
is( xcbc_b64('AES','1234567890123456',"test\0test\0test\n"), 'lM9mjEu7srwPwL8UYSCEuQ==', 'XCBC/func+b64/9');
+is( xcbc_b64u('AES','1234567890123456',"test\0test\0test\n"), 'lM9mjEu7srwPwL8UYSCEuQ', 'XCBC/func+b64u/9');
is( unpack('H*', Crypt::Mac::XCBC->new('AES','12345678901234561234567890123456')->add("test\0test\0test\n")->mac), '438ad752323bdaab774e5051556b2336', 'XCBC/oo+raw/10');
is( Crypt::Mac::XCBC->new('AES','12345678901234561234567890123456')->add("test\0test\0test\n")->hexmac, '438ad752323bdaab774e5051556b2336', 'XCBC/oo+hex/10');
is( unpack('H*', xcbc('AES','12345678901234561234567890123456',"test\0test\0test\n")), '438ad752323bdaab774e5051556b2336', 'XCBC/func+raw/10');
is( xcbc_hex('AES','12345678901234561234567890123456',"test\0test\0test\n"), '438ad752323bdaab774e5051556b2336', 'XCBC/func+hex/10');
is( xcbc_b64('AES','12345678901234561234567890123456',"test\0test\0test\n"), 'Q4rXUjI72qt3TlBRVWsjNg==', 'XCBC/func+b64/10');
+is( xcbc_b64u('AES','12345678901234561234567890123456',"test\0test\0test\n"), 'Q4rXUjI72qt3TlBRVWsjNg', 'XCBC/func+b64u/10');
is( unpack('H*', Crypt::Mac::XCBC->new('Blowfish','1234567890123456')->add("test\0test\0test\n")->mac), '98276a4a6aafd86b', 'XCBC/oo+raw/11');
is( Crypt::Mac::XCBC->new('Blowfish','1234567890123456')->add("test\0test\0test\n")->hexmac, '98276a4a6aafd86b', 'XCBC/oo+hex/11');
is( unpack('H*', xcbc('Blowfish','1234567890123456',"test\0test\0test\n")), '98276a4a6aafd86b', 'XCBC/func+raw/11');
is( xcbc_hex('Blowfish','1234567890123456',"test\0test\0test\n"), '98276a4a6aafd86b', 'XCBC/func+hex/11');
is( xcbc_b64('Blowfish','1234567890123456',"test\0test\0test\n"), 'mCdqSmqv2Gs=', 'XCBC/func+b64/11');
+is( xcbc_b64u('Blowfish','1234567890123456',"test\0test\0test\n"), 'mCdqSmqv2Gs', 'XCBC/func+b64u/11');
is( unpack('H*', Crypt::Mac::XCBC->new('Blowfish','12345678901234561234567890123456')->add("test\0test\0test\n")->mac), '98276a4a6aafd86b', 'XCBC/oo+raw/12');
is( Crypt::Mac::XCBC->new('Blowfish','12345678901234561234567890123456')->add("test\0test\0test\n")->hexmac, '98276a4a6aafd86b', 'XCBC/oo+hex/12');
is( unpack('H*', xcbc('Blowfish','12345678901234561234567890123456',"test\0test\0test\n")), '98276a4a6aafd86b', 'XCBC/func+raw/12');
is( xcbc_hex('Blowfish','12345678901234561234567890123456',"test\0test\0test\n"), '98276a4a6aafd86b', 'XCBC/func+hex/12');
is( xcbc_b64('Blowfish','12345678901234561234567890123456',"test\0test\0test\n"), 'mCdqSmqv2Gs=', 'XCBC/func+b64/12');
+is( xcbc_b64u('Blowfish','12345678901234561234567890123456',"test\0test\0test\n"), 'mCdqSmqv2Gs', 'XCBC/func+b64u/12');
done_testing();