Digest-1.17/000755 000765 000024 00000000000 11642034364 013132 5ustar00gislestaff000000 000000 Digest-1.17/Changes000644 000765 000024 00000006777 11642034220 014435 0ustar00gislestaff000000 000000 2011-10-02 Gisle Aas Release 1.17. Gisle Aas (6): Less noisy 'git status' output Merge pull request #1 from schwern/bug/require_eval Don't clobber $@ in Digest->new [RT#50663] More meta info added to Makefile.PL Fix typo in RIPEMD160 [RT#50629] Add schwern's test files Michael G. Schwern (5): Turn on strict. Convert tests to use Test::More Untabify Turn Digest::Dummy into a real file which exercises the Digest->new() require logic. Close the eval "require $module" security hole in Digest->new($algorithm) 2009-06-09 Gisle Aas Release 1.16. Gisle Aas (3): For SHA-1 try Digest::SHA before tryign Digest::SHA1 as suggested by Adam Trickett Support Digest->new("RIPEMD-160") as suggested by Zefram Use 3-arg open for fewer surprises Jarkko Hietaniemi (1): Sync up with EBCDIC changes from core perl. 2006-03-20 Gisle Aas Release 1.15. Improved documentation. 2005-11-26 Gisle Aas Release 1.14 Documentation tweaks. 2005-10-18 Gisle Aas Release 1.13 Fixed documentation typo. 2005-09-29 Gisle Aas Release 1.12 Fix documentation typo. Patch by . 2005-09-11 Gisle Aas Release 1.11 Make Digest->new("SHA-224") work. Patch by Mark Shelor . 2004-11-08 Gisle Aas Release 1.10 Added Digest::file module which provide convenience functions that calculate digests of files. 2004-11-05 Gisle Aas Release 1.09 Fix trivial documentation typo. 2004-04-29 Gisle Aas Release 1.08 Make Digest->new("CRC-16"), Digest->new("CRC-32") and Digest->new("CRC-CCITT") work. Patch by Oliver Maul . 2004-04-25 Gisle Aas Release 1.07 Updated benchmark. 2004-04-01 Gisle Aas Release 1.06 Added MIME::Base64 dependency. Minor doc tweak. 2003-12-01 Gisle Aas Release 1.05 Drop Digest::MD5 dependency. Avoids circular dependency now that Digest::MD5 depend on this package to inherit Digest::base. Included a section about digest speed with benchmark results for some implementations of this API. 2003-11-29 Gisle Aas Release 1.04 Doc tweaks to unconfuse search.cpan.org. 2003-11-28 Gisle Aas Release 1.03 Added add_bits() method as requested by the Digest::SHA author Mark Shelor. Added Digest::base class that Digest implementations can use to get default implementations of addfile(), add_bits(), hexdigest() and b64digest(). Digest->new("SHA-256") and similar should work now given that you have either Digest::SHA or Digest::SHA2 installed. 2003-01-18 Gisle Aas Release 1.02 Sync up with version bundled with perl-5.8. Patch by Jarkko Hietaniemi . Override INSTALLDIRS for 5.8 as suggested by Guido Ostkamp . 2003-01-04 Gisle Aas Release 1.01 Document the clone() method. 2001-03-13 Gisle Aas Release 1.00 Broken out of the Digest-MD5-2.12 distribution and made into a separate dist. Digest-1.17/Digest/000755 000765 000024 00000000000 11642034364 014351 5ustar00gislestaff000000 000000 Digest-1.17/digest-bench000755 000765 000024 00000001027 11154225152 015407 0ustar00gislestaff000000 000000 #!/usr/bin/perl -w use strict; die unless @ARGV; my($mod, @args) = @ARGV; eval "require $mod"; die $@ if $@; $a = substr(join("", "a" .. "z",) x 800, 0, 8 * 1024); my $count = 4*1024; use Time::HiRes qw(time); my $before = time; my $ctx = $mod->new(@args); for (1 .. $count) { $ctx->add($a); } print $ctx->hexdigest, "\n"; my $sec = time - $before; my $bytes = length($a) * $count; print "$bytes/$sec\n"; my $vers = do { no strict 'refs'; ${$mod . '::VERSION'} }; printf "$mod $vers\t%.2f MB/s\n", $bytes/(1024*1024*$sec) Digest-1.17/Digest.pm000644 000765 000024 00000024545 11642033643 014720 0ustar00gislestaff000000 000000 package Digest; use strict; use vars qw($VERSION %MMAP $AUTOLOAD); $VERSION = "1.17"; %MMAP = ( "SHA-1" => [["Digest::SHA", 1], "Digest::SHA1", ["Digest::SHA2", 1]], "SHA-224" => [["Digest::SHA", 224]], "SHA-256" => [["Digest::SHA", 256], ["Digest::SHA2", 256]], "SHA-384" => [["Digest::SHA", 384], ["Digest::SHA2", 384]], "SHA-512" => [["Digest::SHA", 512], ["Digest::SHA2", 512]], "HMAC-MD5" => "Digest::HMAC_MD5", "HMAC-SHA-1" => "Digest::HMAC_SHA1", "CRC-16" => [["Digest::CRC", type => "crc16"]], "CRC-32" => [["Digest::CRC", type => "crc32"]], "CRC-CCITT" => [["Digest::CRC", type => "crcccitt"]], "RIPEMD-160" => "Crypt::RIPEMD160", ); sub new { shift; # class ignored my $algorithm = shift; my $impl = $MMAP{$algorithm} || do { $algorithm =~ s/\W+//g; "Digest::$algorithm"; }; $impl = [$impl] unless ref($impl); local $@; # don't clobber it for our caller my $err; for (@$impl) { my $class = $_; my @args; ($class, @args) = @$class if ref($class); no strict 'refs'; unless (exists ${"$class\::"}{"VERSION"}) { my $pm_file = $class . ".pm"; $pm_file =~ s{::}{/}g; eval { require $pm_file }; if ($@) { $err ||= $@; next; } } return $class->new(@args, @_); } die $err; } sub AUTOLOAD { my $class = shift; my $algorithm = substr($AUTOLOAD, rindex($AUTOLOAD, '::')+2); $class->new($algorithm, @_); } 1; __END__ =head1 NAME Digest - Modules that calculate message digests =head1 SYNOPSIS $md5 = Digest->new("MD5"); $sha1 = Digest->new("SHA-1"); $sha256 = Digest->new("SHA-256"); $sha384 = Digest->new("SHA-384"); $sha512 = Digest->new("SHA-512"); $hmac = Digest->HMAC_MD5($key); =head1 DESCRIPTION The C modules calculate digests, also called "fingerprints" or "hashes", of some data, called a message. The digest is (usually) some small/fixed size string. The actual size of the digest depend of the algorithm used. The message is simply a sequence of arbitrary bytes or bits. An important property of the digest algorithms is that the digest is I to change if the message change in some way. Another property is that digest functions are one-way functions, that is it should be I to find a message that correspond to some given digest. Algorithms differ in how "likely" and how "hard", as well as how efficient they are to compute. Note that the properties of the algorithms change over time, as the algorithms are analyzed and machines grow faster. If your application for instance depends on it being "impossible" to generate the same digest for a different message it is wise to make it easy to plug in stronger algorithms as the one used grow weaker. Using the interface documented here should make it easy to change algorithms later. All C modules provide the same programming interface. A functional interface for simple use, as well as an object oriented interface that can handle messages of arbitrary length and which can read files directly. The digest can be delivered in three formats: =over 8 =item I This is the most compact form, but it is not well suited for printing or embedding in places that can't handle arbitrary data. =item I A twice as long string of lowercase hexadecimal digits. =item I A string of portable printable characters. This is the base64 encoded representation of the digest with any trailing padding removed. The string will be about 30% longer than the binary version. L tells you more about this encoding. =back The functional interface is simply importable functions with the same name as the algorithm. The functions take the message as argument and return the digest. Example: use Digest::MD5 qw(md5); $digest = md5($message); There are also versions of the functions with "_hex" or "_base64" appended to the name, which returns the digest in the indicated form. =head1 OO INTERFACE The following methods are available for all C modules: =over 4 =item $ctx = Digest->XXX($arg,...) =item $ctx = Digest->new(XXX => $arg,...) =item $ctx = Digest::XXX->new($arg,...) The constructor returns some object that encapsulate the state of the message-digest algorithm. You can add data to the object and finally ask for the digest. The "XXX" should of course be replaced by the proper name of the digest algorithm you want to use. The two first forms are simply syntactic sugar which automatically load the right module on first use. The second form allow you to use algorithm names which contains letters which are not legal perl identifiers, e.g. "SHA-1". If no implementation for the given algorithm can be found, then an exception is raised. If new() is called as an instance method (i.e. $ctx->new) it will just reset the state the object to the state of a newly created object. No new object is created in this case, and the return value is the reference to the object (i.e. $ctx). =item $other_ctx = $ctx->clone The clone method creates a copy of the digest state object and returns a reference to the copy. =item $ctx->reset This is just an alias for $ctx->new. =item $ctx->add( $data ) =item $ctx->add( $chunk1, $chunk2, ... ) The string value of the $data provided as argument is appended to the message we calculate the digest for. The return value is the $ctx object itself. If more arguments are provided then they are all appended to the message, thus all these lines will have the same effect on the state of the $ctx object: $ctx->add("a"); $ctx->add("b"); $ctx->add("c"); $ctx->add("a")->add("b")->add("c"); $ctx->add("a", "b", "c"); $ctx->add("abc"); Most algorithms are only defined for strings of bytes and this method might therefore croak if the provided arguments contain chars with ordinal number above 255. =item $ctx->addfile( $io_handle ) The $io_handle is read until EOF and the content is appended to the message we calculate the digest for. The return value is the $ctx object itself. The addfile() method will croak() if it fails reading data for some reason. If it croaks it is unpredictable what the state of the $ctx object will be in. The addfile() method might have been able to read the file partially before it failed. It is probably wise to discard or reset the $ctx object if this occurs. In most cases you want to make sure that the $io_handle is in "binmode" before you pass it as argument to the addfile() method. =item $ctx->add_bits( $data, $nbits ) =item $ctx->add_bits( $bitstring ) The add_bits() method is an alternative to add() that allow partial bytes to be appended to the message. Most users should just ignore this method as partial bytes is very unlikely to be of any practical use. The two argument form of add_bits() will add the first $nbits bits from $data. For the last potentially partial byte only the high order C<< $nbits % 8 >> bits are used. If $nbits is greater than C<< length($data) * 8 >>, then this method would do the same as C<< $ctx->add($data) >>. The one argument form of add_bits() takes a $bitstring of "1" and "0" chars as argument. It's a shorthand for C<< $ctx->add_bits(pack("B*", $bitstring), length($bitstring)) >>. The return value is the $ctx object itself. This example shows two calls that should have the same effect: $ctx->add_bits("111100001010"); $ctx->add_bits("\xF0\xA0", 12); Most digest algorithms are byte based and for these it is not possible to add bits that are not a multiple of 8, and the add_bits() method will croak if you try. =item $ctx->digest Return the binary digest for the message. Note that the C operation is effectively a destructive, read-once operation. Once it has been performed, the $ctx object is automatically C and can be used to calculate another digest value. Call $ctx->clone->digest if you want to calculate the digest without resetting the digest state. =item $ctx->hexdigest Same as $ctx->digest, but will return the digest in hexadecimal form. =item $ctx->b64digest Same as $ctx->digest, but will return the digest as a base64 encoded string. =back =head1 Digest speed This table should give some indication on the relative speed of different algorithms. It is sorted by throughput based on a benchmark done with of some implementations of this API: Algorithm Size Implementation MB/s MD4 128 Digest::MD4 v1.3 165.0 MD5 128 Digest::MD5 v2.33 98.8 SHA-256 256 Digest::SHA2 v1.1.0 66.7 SHA-1 160 Digest::SHA v4.3.1 58.9 SHA-1 160 Digest::SHA1 v2.10 48.8 SHA-256 256 Digest::SHA v4.3.1 41.3 Haval-256 256 Digest::Haval256 v1.0.4 39.8 SHA-384 384 Digest::SHA2 v1.1.0 19.6 SHA-512 512 Digest::SHA2 v1.1.0 19.3 SHA-384 384 Digest::SHA v4.3.1 19.2 SHA-512 512 Digest::SHA v4.3.1 19.2 Whirlpool 512 Digest::Whirlpool v1.0.2 13.0 MD2 128 Digest::MD2 v2.03 9.5 Adler-32 32 Digest::Adler32 v0.03 1.3 CRC-16 16 Digest::CRC v0.05 1.1 CRC-32 32 Digest::CRC v0.05 1.1 MD5 128 Digest::Perl::MD5 v1.5 1.0 CRC-CCITT 16 Digest::CRC v0.05 0.8 These numbers was achieved Apr 2004 with ActivePerl-5.8.3 running under Linux on a P4 2.8 GHz CPU. The last 5 entries differ by being pure perl implementations of the algorithms, which explains why they are so slow. =head1 SEE ALSO L, L, L, L, L, L, L, L, L, L, L New digest implementations should consider subclassing from L. L http://en.wikipedia.org/wiki/Cryptographic_hash_function =head1 AUTHOR Gisle Aas The C interface is based on the interface originally developed by Neil Winton for his C module. This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. Copyright 1998-2006 Gisle Aas. Copyright 1995,1996 Neil Winton. =cut Digest-1.17/Makefile.PL000644 000765 000024 00000002121 11642032702 015072 0ustar00gislestaff000000 000000 require 5.004; use ExtUtils::MakeMaker; WriteMakefile( 'NAME' => 'Digest', 'VERSION_FROM' => 'Digest.pm', ($] >= 5.008 ? ('INSTALLDIRS' => 'perl') : ()), ABSTRACT_FROM => 'Digest.pm', AUTHOR => 'Gisle Aas ', LICENSE => 'perl', MIN_PERL_VERSION => '5.004', 'PREREQ_PM' => { 'MIME::Base64' => 0, 'Test::More' => '0.47' }, META_MERGE => { resources => { repository => 'http://github.com/gisle/digest', } }, ); BEGIN { # compatibility with older versions of MakeMaker my $developer = -f ".gitignore"; my %mm_req = ( LICENCE => 6.31, META_MERGE => 6.45, META_ADD => 6.45, MIN_PERL_VERSION => 6.48, ); undef(*WriteMakefile); *WriteMakefile = sub { my %arg = @_; for (keys %mm_req) { unless (eval { ExtUtils::MakeMaker->VERSION($mm_req{$_}) }) { warn "$_ $@" if $developer; delete $arg{$_}; } } ExtUtils::MakeMaker::WriteMakefile(%arg); }; } Digest-1.17/MANIFEST000644 000765 000024 00000000350 11642034364 014261 0ustar00gislestaff000000 000000 Changes Digest.pm Digest/base.pm Digest/file.pm digest-bench MANIFEST Makefile.PL README t/base.t t/digest.t t/file.t t/lib/Digest/Dummy.pm t/security.t META.yml Module meta-data (added by MakeMaker) Digest-1.17/META.yml000644 000765 000024 00000001226 11642034364 014404 0ustar00gislestaff000000 000000 --- #YAML:1.0 name: Digest version: 1.17 abstract: Modules that calculate message digests author: - Gisle Aas license: perl distribution_type: module configure_requires: ExtUtils::MakeMaker: 0 build_requires: ExtUtils::MakeMaker: 0 requires: MIME::Base64: 0 perl: 5.004 Test::More: 0.47 resources: repository: http://github.com/gisle/digest no_index: directory: - t - inc generated_by: ExtUtils::MakeMaker version 6.57_05 meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: 1.4 Digest-1.17/README000644 000765 000024 00000000640 11154225152 014005 0ustar00gislestaff000000 000000 This is just a simple frontend module for autoloading of various Digest:: modules. It also provide documentation of the interface that all Digest:: modules should provide. You will need perl version 5.004 or better to install this module. Copyright 1998-2006 Gisle Aas. Copyright 1995-1996 Neil Winton. This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. Digest-1.17/t/000755 000765 000024 00000000000 11642034364 013375 5ustar00gislestaff000000 000000 Digest-1.17/t/base.t000644 000765 000024 00000002737 11642032702 014477 0ustar00gislestaff000000 000000 #!perl -w use Test::More tests => 12; { package LenDigest; require Digest::base; use vars qw(@ISA); @ISA = qw(Digest::base); sub new { my $class = shift; my $str = ""; bless \$str, $class; } sub add { my $self = shift; $$self .= join("", @_); return $self; } sub digest { my $self = shift; my $len = length($$self); my $first = ($len > 0) ? substr($$self, 0, 1) : "X"; $$self = ""; return sprintf "$first%04d", $len; } } my $ctx = LenDigest->new; is($ctx->digest, "X0000"); my $EBCDIC = ord('A') == 193; if ($EBCDIC) { is($ctx->hexdigest, "e7f0f0f0f0"); is($ctx->b64digest, "5/Dw8PA"); } else { is($ctx->hexdigest, "5830303030"); is($ctx->b64digest, "WDAwMDA"); } $ctx->add("foo"); is($ctx->digest, "f0003"); $ctx->add("foo"); is($ctx->hexdigest, $EBCDIC ? "86f0f0f0f3" : "6630303033"); $ctx->add("foo"); is($ctx->b64digest, $EBCDIC ? "hvDw8PM" : "ZjAwMDM"); open(F, ">xxtest$$") || die; binmode(F); print F "abc" x 100, "\n"; close(F) || die; open(F, "xxtest$$") || die; $ctx->addfile(*F); close(F); unlink("xxtest$$") || warn; is($ctx->digest, "a0301"); eval { $ctx->add_bits("1010"); }; like($@, '/^Number of bits must be multiple of 8/'); $ctx->add_bits($EBCDIC ? "11100100" : "01010101"); is($ctx->digest, "U0001"); eval { $ctx->add_bits("abc", 12); }; like($@, '/^Number of bits must be multiple of 8/'); $ctx->add_bits("abc", 16); is($ctx->digest, "a0002"); $ctx->add_bits("abc", 32); is($ctx->digest, "a0003"); Digest-1.17/t/digest.t000644 000765 000024 00000000604 11642032702 015033 0ustar00gislestaff000000 000000 #!/usr/bin/env perl use strict; use Test::More tests => 4; # To find Digest::Dummy use lib 't/lib'; use Digest; $@ = "rt#50663"; my $d; $d = Digest->new("Dummy"); is $@, "rt#50663"; is $d->digest, "ooo"; $d = Digest->Dummy; is $d->digest, "ooo"; $Digest::MMAP{"Dummy-24"} = [["NotThere"], "NotThereEither", ["Digest::Dummy", 24]]; $d = Digest->new("Dummy-24"); is $d->digest, "24"; Digest-1.17/t/file.t000644 000765 000024 00000001777 11642032702 014507 0ustar00gislestaff000000 000000 #!perl -w use Test::More tests => 5; { package Digest::Foo; require Digest::base; use vars qw(@ISA $VERSION); @ISA = qw(Digest::base); sub new { my $class = shift; my $str = ""; bless \$str, $class; } sub add { my $self = shift; $$self .= join("", @_); return $self; } sub digest { my $self = shift; return sprintf "%04d", length($$self); } } use Digest::file qw(digest_file digest_file_hex digest_file_base64); my $file = "test-$$"; die if -f $file; open(F, ">$file") || die "Can't create '$file': $!"; binmode(F); print F "foo\0\n"; close(F) || die "Can't write '$file': $!"; is(digest_file($file, "Foo"), "0005"); if (ord('A') == 193) { # EBCDIC. is(digest_file_hex($file, "Foo"), "f0f0f0f5"); is(digest_file_base64($file, "Foo"), "8PDw9Q"); } else { is(digest_file_hex($file, "Foo"), "30303035"); is(digest_file_base64($file, "Foo"), "MDAwNQ"); } unlink($file) || warn "Can't unlink '$file': $!"; ok !eval { digest_file("not-there.txt", "Foo") }; ok $@; Digest-1.17/t/lib/000755 000765 000024 00000000000 11642034364 014143 5ustar00gislestaff000000 000000 Digest-1.17/t/security.t000644 000765 000024 00000000326 11642032702 015424 0ustar00gislestaff000000 000000 #!/usr/bin/env perl # Digest->new() had an exploitable eval use strict; use warnings; use Test::More tests => 1; use Digest; $LOL::PWNED = 0; eval { Digest->new(q[MD;5;$LOL::PWNED = 42]) }; is $LOL::PWNED, 0; Digest-1.17/t/lib/Digest/000755 000765 000024 00000000000 11642034364 015362 5ustar00gislestaff000000 000000 Digest-1.17/t/lib/Digest/Dummy.pm000644 000765 000024 00000000410 11642032702 017000 0ustar00gislestaff000000 000000 package Digest::Dummy; use strict; use vars qw($VERSION @ISA); $VERSION = 1; require Digest::base; @ISA = qw(Digest::base); sub new { my $class = shift; my $d = shift || "ooo"; bless { d => $d }, $class; } sub add {} sub digest { shift->{d} } 1; Digest-1.17/Digest/base.pm000644 000765 000024 00000003414 11213527613 015621 0ustar00gislestaff000000 000000 package Digest::base; use strict; use vars qw($VERSION); $VERSION = "1.16"; # subclass is supposed to implement at least these sub new; sub clone; sub add; sub digest; sub reset { my $self = shift; $self->new(@_); # ugly } sub addfile { my ($self, $handle) = @_; my $n; my $buf = ""; while (($n = read($handle, $buf, 4*1024))) { $self->add($buf); } unless (defined $n) { require Carp; Carp::croak("Read failed: $!"); } $self; } sub add_bits { my $self = shift; my $bits; my $nbits; if (@_ == 1) { my $arg = shift; $bits = pack("B*", $arg); $nbits = length($arg); } else { ($bits, $nbits) = @_; } if (($nbits % 8) != 0) { require Carp; Carp::croak("Number of bits must be multiple of 8 for this algorithm"); } return $self->add(substr($bits, 0, $nbits/8)); } sub hexdigest { my $self = shift; return unpack("H*", $self->digest(@_)); } sub b64digest { my $self = shift; require MIME::Base64; my $b64 = MIME::Base64::encode($self->digest(@_), ""); $b64 =~ s/=+$//; return $b64; } 1; __END__ =head1 NAME Digest::base - Digest base class =head1 SYNOPSIS package Digest::Foo; use base 'Digest::base'; =head1 DESCRIPTION The C class provide implementations of the methods C and C in terms of C, and of the methods C and C in terms of C. Digest implementations might want to inherit from this class to get this implementations of the alternative I and I methods. A minimal subclass needs to implement the following methods by itself: new clone add digest The arguments and expected behaviour of these methods are described in L. =head1 SEE ALSO L Digest-1.17/Digest/file.pm000644 000765 000024 00000003304 11213527600 015620 0ustar00gislestaff000000 000000 package Digest::file; use strict; use Exporter (); use Carp qw(croak); use Digest (); use vars qw($VERSION @ISA @EXPORT_OK); $VERSION = "1.16"; @ISA = qw(Exporter); @EXPORT_OK = qw(digest_file_ctx digest_file digest_file_hex digest_file_base64); sub digest_file_ctx { my $file = shift; croak("No digest algorithm specified") unless @_; local *F; open(F, "<", $file) || croak("Can't open '$file': $!"); binmode(F); my $ctx = Digest->new(@_); $ctx->addfile(*F); close(F); return $ctx; } sub digest_file { digest_file_ctx(@_)->digest; } sub digest_file_hex { digest_file_ctx(@_)->hexdigest; } sub digest_file_base64 { digest_file_ctx(@_)->b64digest; } 1; __END__ =head1 NAME Digest::file - Calculate digests of files =head1 SYNOPSIS # Poor mans "md5sum" command use Digest::file qw(digest_file_hex); for (@ARGV) { print digest_file_hex($_, "MD5"), " $_\n"; } =head1 DESCRIPTION This module provide 3 convenience functions to calculate the digest of files. The following functions are provided: =over =item digest_file( $file, $algorithm, [$arg,...] ) This function will calculate and return the binary digest of the bytes of the given file. The function will croak if it fails to open or read the file. The $algorithm is a string like "MD2", "MD5", "SHA-1", "SHA-512". Additional arguments are passed to the constructor for the implementation of the given algorithm. =item digest_file_hex( $file, $algorithm, [$arg,...] ) Same as digest_file(), but return the digest in hex form. =item digest_file_base64( $file, $algorithm, [$arg,...] ) Same as digest_file(), but return the digest as a base64 encoded string. =back =head1 SEE ALSO L