summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MANIFEST12
-rw-r--r--configure.com2
-rw-r--r--ext/Digest/MD5/Changes439
-rw-r--r--ext/Digest/MD5/MD5.pm264
-rw-r--r--ext/Digest/MD5/MD5.xs626
-rw-r--r--ext/Digest/MD5/Makefile.PL20
-rw-r--r--ext/Digest/MD5/hints/irix_6.pl6
-rw-r--r--ext/Digest/MD5/typemap5
-rw-r--r--hints/uwin.sh2
-rw-r--r--hints/vmesa.sh2
-rw-r--r--lib/Digest.pm180
-rw-r--r--t/lib/digest.t21
-rw-r--r--t/lib/md5-aaa.t287
-rw-r--r--t/lib/md5-badf.t26
-rw-r--r--t/lib/md5-file.t111
-rw-r--r--win32/Makefile25
-rw-r--r--win32/makefile.mk17
17 files changed, 2030 insertions, 15 deletions
diff --git a/MANIFEST b/MANIFEST
index 3134e939da..c92cd4ceb6 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -169,6 +169,13 @@ ext/Devel/Peek/Changes Data debugging tool, changelog
ext/Devel/Peek/Makefile.PL Data debugging tool, makefile writer
ext/Devel/Peek/Peek.pm Data debugging tool, module and pod
ext/Devel/Peek/Peek.xs Data debugging tool, externals
+ext/Digest/MD5/Changes Digest::MD5 extension changes
+ext/Digest/MD5/MD5.pm Digest::MD5 extension
+ext/Digest/MD5/MD5.xs Digest::MD5 extension
+ext/Digest/MD5/Makefile.PL Digest::MD5 extension makefile writer
+ext/Digest/MD5/hints/dec_osf.pl Hints for named architecture
+ext/Digest/MD5/hints/irix_6.pl Hints for named architecture
+ext/Digest/MD5/typemap Digest::MD5 extension
ext/DynaLoader/DynaLoader_pm.PL Dynamic Loader perl module
ext/DynaLoader/Makefile.PL Dynamic Loader makefile writer
ext/DynaLoader/README Dynamic Loader notes and intro
@@ -668,6 +675,7 @@ lib/Class/Struct.pm Declare struct-like datatypes as Perl classes
lib/Cwd.pm Various cwd routines (getcwd, fastcwd, chdir)
lib/DB.pm Debugger API (draft)
lib/Devel/SelfStubber.pm Generate stubs for SelfLoader.pm
+lib/Digest.pm Digest extensions
lib/DirHandle.pm like FileHandle only for directories
lib/Dumpvalue.pm Screen dump of perl values
lib/English.pm Readable aliases for short variables
@@ -1411,6 +1419,7 @@ t/lib/compmod.pl Helper for 1_compile.t
t/lib/db-btree.t See if DB_File works
t/lib/db-hash.t See if DB_File works
t/lib/db-recno.t See if DB_File works
+t/lib/digest.t See if Digest extensions work
t/lib/dirhand.t See if DirHandle works
t/lib/dosglob.t See if File::DosGlob works
t/lib/dprof.t Perl code profiler testsuite driver
@@ -1485,6 +1494,9 @@ t/lib/lc-country.t See if Locale::Codes work
t/lib/lc-currency.t See if Locale::Codes work
t/lib/lc-language.t See if Locale::Codes work
t/lib/lc-uk.t See if Locale::Codes work
+t/lib/md5-aaa.t See if Digest::MD5 extension works
+t/lib/md5-badf.t See if Digest::MD5 extension works
+t/lib/md5-file.t See if Digest::MD5 extension works
t/lib/ndbm.t See if NDBM_File works
t/lib/net-hostent.t See if Net::hostent works
t/lib/odbm.t See if ODBM_File works
diff --git a/configure.com b/configure.com
index c27adaf41d..2dce6d3950 100644
--- a/configure.com
+++ b/configure.com
@@ -2392,7 +2392,7 @@ $ echo "SDBM_File if you have the GDBM library built on your machine."
$ echo ""
$ echo "Which modules do you want to build into perl?"
$! we need to add Byteloader to this list:
-$ dflt = "re Fcntl Encode Errno File::Glob Filter::Util::Call IO Opcode Devel::Peek Devel::DProf Data::Dumper attrs VMS::Stdio VMS::DCLsym B SDBM_File Storable Thread Sys::Hostname"
+$ dflt = "re Fcntl Encode Errno File::Glob Filter::Util::Call IO Opcode Devel::Peek Devel::DProf Data::Dumper attrs VMS::Stdio VMS::DCLsym B SDBM_File Storable Thread Sys::Hostname Digest::MD5"
$ IF ccname .EQS. "DEC" .OR. ccname .EQS. "CXX"
$ THEN
$ dflt = dflt + " POSIX"
diff --git a/ext/Digest/MD5/Changes b/ext/Digest/MD5/Changes
new file mode 100644
index 0000000000..62c828075c
--- /dev/null
+++ b/ext/Digest/MD5/Changes
@@ -0,0 +1,439 @@
+2001-03-13 Gisle Aas <gisle@ActiveState.com>
+
+ Release 2.13
+
+ Moved all other Digest:: modules out of the Digest-MD5 dist.
+
+
+
+2000-09-18 Gisle Aas <gisle@ActiveState.com>
+
+ Release 2.12
+
+ Avoid pointer cast warning for machines with bigger ints
+ than pointers. Patch by Robin Barker <rmb1@cise.npl.co.uk>.
+
+
+
+2000-08-19 Gisle Aas <gisle@ActiveState.com>
+
+ Release 2.11
+
+ The fallback code introduced in 2.10 did only work for
+ perl-5.6.0. It should now for for perl5.004 and 5.005
+ as well. Patch by Ville Skyttä <ville@office.popsystems.com>.
+
+
+
+2000-08-18 Gisle Aas <gisle@ActiveState.com>
+
+ Release 2.10
+
+ Digest::MD5 will now try to fallback to the pure perl
+ implementation of Digest::Perl::MD5 if bootstrap fails.
+
+ Added a bit internal paranoia about casting the IV
+ in the Digest::MD5 object to the MD5_CTX* pointer.
+
+
+
+1999-08-06 Gisle Aas <gisle@aas.no>
+
+ Release 2.09
+
+ Documentation update.
+
+
+
+1999-07-28 Gisle Aas <gisle@aas.no>
+
+ Release 2.08
+
+ The addfile() methods could trigger a core dump when passed
+ a filehandle that had failed to open.
+
+
+
+1999-04-26 Gisle Aas <gisle@aas.no>
+
+ Release 2.07
+
+ The Digest::SHA1 module failed on some 64-bit systems, because I
+ assumed there was a correspondence between the U32 size and
+ BYTEORDER. This version use 'unsigned long' as Uwe's original
+ SHA module did.
+
+ The module should now work better when liked statically with perl,
+ because we now use a safer module-loaded test in Digest.pm.
+
+ Assume we know the outcome of the alignment test on VMS. Patch by
+ Chuck Lane <lane@duphy4.physics.drexel.edu>
+
+
+
+1999-03-26 Gisle Aas <gisle@aas.no>
+
+ Release 2.06
+
+ Avoid LONG and BYTE types in SHA.xs as they was in conflict
+ with similar definitions in <winnt.h>.
+
+ Patch by Marko Asplund <aspa@hip.fi> to make the the alignment
+ test program link successfully with sfio-perl.
+
+ Fixed a typo in MD5.xs that might have affected 64-bit systems.
+ Spotted by Nick Ing-Simmons
+
+
+
+1999-03-15 Gisle Aas <gisle@aas.no>
+
+ Release 2.05
+
+ Included Digest::SHA1 based on Uwe Hollerbach's SHA module.
+
+
+
+1999-03-05 Gisle Aas <gisle@aas.no>
+
+ Release 2.04
+
+ Avoid the -o option when compiling alignment test program
+ for Win32 as suggested by Gurusamy Sarathy.
+
+ DEC Compiler bug workaround. Contributed by D Roland Walker
+ <walker@ncbi.nlm.nih.gov>
+
+ Having references to a local variable called "na" was not
+ very safe either. Some older versions of Perl can apparently
+ macroize this into something completely different.
+
+
+
+1999-02-27 Gisle Aas <gisle@aas.no>
+
+ Release 2.03
+
+ Patch from Christopher J. Madsen <chris_madsen@geocities.com> that
+ should help getting the u32align test program to compile with
+ Visual C++ 5 on Windows NT.
+
+ Got rid of references to PL_na.
+
+
+
+1999-01-31 Gisle Aas <gisle@aas.no>
+
+ Release 2.02
+
+ Added a hints file as workaround for an IRIX compiler bug.
+ Contributed by D Roland Walker <walker@ncbi.nlm.nih.gov>.
+
+ Note that the rfc2202 test can still fail on some DEC Alpha,
+ because of a compiler bug that affects the perl 'x' operator.
+ The Digest:: modules should work and be safe to install anyway.
+
+
+
+1998-12-18 Gisle Aas <aas@sn.no>
+
+ Release 2.01
+
+ Some casts and tweaks to make picky compilers more happy.
+
+
+
+1998-11-04 Gisle Aas <aas@sn.no>
+
+ Release 2.00.
+
+ Taken out Digest::SHA1 as this module will be provided from Uwe
+ Hollerbach later.
+
+ Some tweaks to MD2.xs and MD5.xs since "na" disappeared in
+ perl5.005_53
+
+
+
+1998-10-30 Gisle Aas <aas@sn.no>
+
+ Release 1.99_60
+
+ The 1.99_59 release introduced compilation problems for big-endian
+ systems with free U32 alignment. Bug reported, and fix suggested
+ by Paul J. Schinder <schinder@pobox.com>.
+
+
+
+1998-10-28 Gisle Aas <aas@sn.no>
+
+ Release 1.99_59
+
+ Makefile.PL will run a test program to find out if U32 values can
+ be aligned anywhere. This hopefully cures the core dumps reported
+ on Solaris and other big endian systems. Thanks to Graham Barr for
+ debugging this.
+
+
+
+1998-10-28 Gisle Aas <aas@sn.no>
+
+ Release 1.99_58
+
+ Should be very close to a 2.00 release now. Need some success
+ reports from people running on big-endian machines first I think.
+
+ Added a Digest::MD2 implementation.
+
+ Wrote Digest.pm documentation. This define the interface that all
+ Digest:: modules should provide.
+
+ Avoided some code duplication in MD5.xs
+
+ Fixed typo, that prevented Digest::SHA1::sha1_base64() from working.
+
+
+
+1998-10-27 Gisle Aas <aas@sn.no>
+
+ Release 1.99_57
+
+ Rewritten most of the MD5 C code to make it real fast (especially
+ on little-endian machines without alignment restrictions for U32).
+ Compared to MD5-1.7 we can process files 4 times as fast and we
+ digest small stuff in memory 7 times faster. I came to these
+ conclusions after these tests (gcc -O2, i586, Linux):
+
+ First tested calculation of the digest of a 31 MB file, using
+ perl -le 'print Digest::MD5->new->addfile(*STDIN)->hexdigest'
+ and similar stuff:
+
+ MD5-1.7: 21.06s
+ Digest::MD5-1.99_57: 5.23s
+ md5sum (GNU textutils): 4.90s
+
+ As you can see, we do nearly as good as the md5sum program. I
+ think the reason we don't beat md5sum is that perl always insist on
+ loading extra modules like Config.pm, Carp.pm, strict.pm, vars.pm,
+ AutoLoader.pm and DynaLoader.pm. When I simply wrapped the MD5.xs
+ hasher code in a C program I managed to process the file in 4.68s.
+
+ Then we calculated the digest of the same 6 byte sting, 20000
+ times:
+
+ MD5-1.7: 11.81s
+ Digest::MD5-1.99_57: 1.68s
+
+ Digest::MD5 benefit from making this into a plain procedure call
+ instead of a static method call.
+
+
+ Other changes in this release are:
+
+ Documentation update
+
+ Internal MD5.xs cleanup.
+
+ $md5->digest will automatically reset now.
+
+ Digest::HMAC methods add() and addfile() did not return the
+ corret object.
+
+ Added Digest.pm loading module. I am not sure this is a good idea.
+
+ Added Digest::SHA1 and Digest::HMAC_SHA1 module. The Digest::SHA1
+ module is just a wrapper around SHA.pm. I hope to get the author
+ of SHA.pm to move his module to the Digest:: category.
+
+
+
+1998-10-25 Gisle Aas <aas@sn.no>
+
+ Release 1.99_56
+
+ Fix memcpy_byteswap() function in MD5.xs. Must be careful with
+ htovl() as it might evaluate its arguments more than once.
+
+
+
+1998-10-25 Gisle Aas <aas@sn.no>
+
+ Release 1.99_55
+
+ Grahams HMAC_MD5.pm splitted into two modules. Digest::HMAC and
+ Digest::HMAC_MD5. Also provide functional interface. Documentation
+ is still lacking.
+
+ Included RFC 2202 based test for HMAC-MD5.
+
+
+
+1998-10-24 Gisle Aas <aas@sn.no>
+
+ Release 1.99_54
+
+ Included HMAC_MD5.pm, contributed by Graham Barr <gbarr@ti.com>.
+
+ I have a hard time to make up my mind :-) md5_bin() renamed back
+ to md5(). Functions are not exported by default any more.
+
+ Try to Encode/Decode with memcpy_byteswap for 32-bit big-endian
+ machines.
+
+
+
+1998-10-23 Gisle Aas <aas@sn.no>
+
+ Release 1.99_53
+
+ Renamed core module as Digest::MD5. Leave a MD5.pm stub for
+ legacy code.
+
+ The md5() function renamed as md5_bin().
+
+ The constructor, Digest::MD5->new, no longer takes any extra
+ arguments.
+
+ Added some new tests.
+
+ Updated the documentation.
+
+ $md5->b64digest implemented with same base64 encoder as md5_base64.
+
+
+
+1998-10-23 Gisle Aas <aas@sn.no>
+
+ Release 1.99_52
+
+ Patch from Graham Barr which make it work for big-endian machines
+ again.
+
+
+
+1998-10-22 Gisle Aas <aas@sn.no>
+
+ Release 1.99_51
+
+ The MD5 class is now subclassable.
+
+ The add() and addfile() methods now return $self.
+
+ The reset() method is just an alias for new().
+
+ The constructor (MD5->new) now takes optional arguments which are
+ automatically added. It means that we can now write:
+
+ MD5->new($data)->hexdigest;
+
+ New $md5->b64digest method.
+
+ New functions that are exported on request: md5, md5_hex, md5_base64
+
+ Included RFC 1321
+
+ Barely started to update the documentation.
+
+
+
+1998-10-22 Gisle Aas <aas@sn.no>
+
+ Release 1.99_50
+
+ Much better performance (more than twice as fast now). Mostly
+ because we use Copy/Zero instead of the original MD5_memcpy and
+ MD5_memset functions.
+
+ The addfile() and hexdigest() methods are now XS implemented.
+
+ All RSA functions now included in MD5.xs and made static.
+
+ Use perl's Copy/Zero.
+
+ Random cleanup, simplifications and reformatting.
+ Merged things better with the perl configuration.
+
+
+
+Neil Winton's versions below:
+
+
+*** 96/06/20 Version 1.7
+
+MD5 is now completely 64-bit clean (I hope). The basic MD5 code uses
+32-bit quantities and requires a typedef UINT4 to be defined in
+global.h. Perl configuration data (the value of BYTEORDER) is used to
+determine if unsigned longs have 4 or 8 bytes. On 64-bit platforms (eg
+DEC Alpha) then it assumes that "unsigned int" will be a 32-bit type.
+If this is incorrect then adding -DUINT4_IS_LONG to the DEFINES line in
+Makefile.PL will override this.
+
+On some machines (at least Cray that I know of) there is no 32-bit
+integer type. In this case defining TRUNCATE_UINT4 (which is done
+automatically for a Cray) will ensure that 64-bit values are masked
+down to 32 bits. I have done my best to test this but without easy
+access to a true 64-bit machine I can not totally guarantee it (unless
+anyone wants to lend me a spare Cray :-)
+
+There is one remaining limitation for 64-bit enabled processors. The
+amount of data passed to any single call to the underlying MD5
+routines is limited to (2^32 - 1) bytes -- that's 4 gigabytes. I'm
+sorry if that's a real problem for you ...
+
+And finally, a minor complilation warning (unsigned char * used with
+function having char * prototype) has also been eliminated.
+
+*** 96/04/09 Version 1.6
+
+Re-generated module framework using h2xs to pick up the latest module
+conventions for versions etc. You can now say "use MD5 1.6;" and things
+should work correctly. MD5.pod has been integrated into MD5.pm and
+CHANGES renamed to Changes. There is a fairly comprehensive test.pl
+which can be invoked via "make test". There are no functional changes
+to the MD5 routines themselves.
+
+*** 96/03/14 Version 1.5.3
+
+Fixed addfile method to accept type-glob references for the file-handle
+(eg \*STDOUT). This is more consistent with other routines and is now the
+recommended way of passing file-handles. The documentation now gives more
+examples as to how the routines might be used.
+
+*** 96/03/12 Version 1.5.2
+
+Minor fixes from Christopher J Madsen <madsen@computek.net> to provide
+support for building on OS/2 (and to work arround a perl -w bug).
+
+Remove warning about possible difference between add('foo', 'bar') and
+add('foobar'). This is not true (it may have been true in the earliest
+version of the module but is no longer the case).
+
+*** 96/03/08 Version 1.5.1
+
+Add CHANGES file to make it easier for people to figure out what has
+been going on. (Meant to do this as part of 1.5)
+
+*** 96/03/05 Version 1.5
+
+Add hash() and hexhash() methods at the suggestion/request of Gary
+Howland <gary@kampai.euronet.nl> before inclusion in a wider library
+of cryptography modules.
+
+*** 96/02/27 Version 1.4
+
+Finally fixed the pesky Solaris dynamic loading bug. All kudos to Ken
+Pizzini <kenp@spry.com>!
+
+*** 95/11/29 Version 1.3.1
+
+Add explanations of current known problems.
+
+*** 95/06/02 Version 1.3
+
+Fix problems with scope resolution in addfile() reported by
+Jean-Claude Giese <Jean-Claude.Giese@loria.fr>. Basically ARGV is
+always implicitly in package main while other filehandles aren't.
+
+*** 95/05/23 Version 1.2.1
+
+[Changes pre 1.2.1 not recorded]
diff --git a/ext/Digest/MD5/MD5.pm b/ext/Digest/MD5/MD5.pm
new file mode 100644
index 0000000000..7a627b8811
--- /dev/null
+++ b/ext/Digest/MD5/MD5.pm
@@ -0,0 +1,264 @@
+package Digest::MD5;
+
+use strict;
+use vars qw($VERSION @ISA @EXPORT_OK);
+
+$VERSION = '2.14';
+
+require Exporter;
+*import = \&Exporter::import;
+@EXPORT_OK = qw(md5 md5_hex md5_base64);
+
+require DynaLoader;
+@ISA=qw(DynaLoader);
+
+eval {
+ Digest::MD5->bootstrap($VERSION);
+};
+if ($@) {
+ # Try to load the pure perl version
+ require Digest::Perl::MD5;
+
+ Digest::Perl::MD5->import(qw(md5 md5_hex md5_base64));
+ push(@ISA, "Digest::Perl::MD5"); # make OO interface work
+}
+else {
+ *reset = \&new;
+}
+
+1;
+__END__
+
+=head1 NAME
+
+Digest::MD5 - Perl interface to the MD5 Algorithm
+
+=head1 SYNOPSIS
+
+ # Functional style
+ use Digest::MD5 qw(md5 md5_hex md5_base64);
+
+ $digest = md5($data);
+ $digest = md5_hex($data);
+ $digest = md5_base64($data);
+
+ # OO style
+ use Digest::MD5;
+
+ $ctx = Digest::MD5->new;
+
+ $ctx->add($data);
+ $ctx->addfile(*FILE);
+
+ $digest = $ctx->digest;
+ $digest = $ctx->hexdigest;
+ $digest = $ctx->b64digest;
+
+=head1 DESCRIPTION
+
+The C<Digest::MD5> module allows you to use the RSA Data Security
+Inc. MD5 Message Digest algorithm from within Perl programs. The
+algorithm takes as input a message of arbitrary length and produces as
+output a 128-bit "fingerprint" or "message digest" of the input.
+
+The C<Digest::MD5> module provide a procedural interface for simple
+use, as well as an object oriented interface that can handle messages
+of arbitrary length and which can read files directly.
+
+A binary digest will be 16 bytes long. A hex digest will be 32
+characters long. A base64 digest will be 22 characters long.
+
+=head1 FUNCTIONS
+
+The following functions can be exported from the C<Digest::MD5>
+module. No functions are exported by default.
+
+=over 4
+
+=item md5($data,...)
+
+This function will concatenate all arguments, calculate the MD5 digest
+of this "message", and return it in binary form.
+
+=item md5_hex($data,...)
+
+Same as md5(), but will return the digest in hexadecimal form.
+
+=item md5_base64($data,...)
+
+Same as md5(), but will return the digest as a base64 encoded string.
+
+=back
+
+=head1 METHODS
+
+The following methods are available:
+
+=over 4
+
+=item $md5 = Digest::MD5->new
+
+The constructor returns a new C<Digest::MD5> object which encapsulate
+the state of the MD5 message-digest algorithm. You can add data to
+the object and finally ask for the digest.
+
+If called as a instance method (i.e. $md5->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.
+
+=item $md5->reset
+
+This is just an alias for $md5->new.
+
+=item $md5->add($data,...)
+
+The $data provided as argument are appended to the message we
+calculate the digest for. The return value is the $md5 object itself.
+
+=item $md5->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 $md5
+object itself.
+
+In most cases you want to make sure that the $io_handle is set up to
+be in binmode().
+
+=item $md5->digest
+
+Return the binary digest for the message.
+
+Note that the C<digest> operation is effectively a destructive,
+read-once operation. Once it has been performed, the C<Digest::MD5>
+object is automatically C<reset> and can be used to calculate another
+digest value.
+
+=item $md5->hexdigest
+
+Same as $md5->digest, but will return the digest in hexadecimal form.
+
+=item $md5->b64digest
+
+Same as $md5->digest, but will return the digest as a base64 encoded
+string.
+
+=back
+
+
+=head1 EXAMPLES
+
+The simplest way to use this library is to import the md5_hex()
+function (or one of its cousins):
+
+ use Digest::MD5 qw(md5_hex);
+ print "Digest is ", md5_hex("foobarbaz"), "\n";
+
+The above example would print out the message
+
+ Digest is 6df23dc03f9b54cc38a0fc1483df6e21
+
+provided that the implementation is working correctly. The same
+checksum can also be calculated in OO style:
+
+ use Digest::MD5;
+
+ $md5 = Digest::MD5->new;
+ $md5->add('foo', 'bar');
+ $md5->add('baz');
+ $digest = $md5->hexdigest;
+
+ print "Digest is $digest\n";
+
+With OO style you can break the message arbitrary. This means that we
+are no longer limited to have space for the whole message in memory, i.e.
+we can handle messages of any size.
+
+This is useful when calculating checksum for files:
+
+ use Digest::MD5;
+
+ my $file = shift || "/etc/passwd";
+ open(FILE, $file) or die "Can't open '$file': $!";
+ binmode(FILE);
+
+ $md5 = Digest::MD5->new;
+ while (<FILE>) {
+ $md5->add($_);
+ }
+ close(FILE);
+ print $md5->b64digest, " $file\n";
+
+Or we can use the builtin addfile method for more efficient reading of
+the file:
+
+ use Digest::MD5;
+
+ my $file = shift || "/etc/passwd";
+ open(FILE, $file) or die "Can't open '$file': $!";
+ binmode(FILE);
+
+ print Digest::MD5->new->addfile(*FILE)->hexdigest, " $file\n";
+
+=head1 SEE ALSO
+
+L<Digest>,
+L<Digest::MD2>,
+L<Digest::SHA1>,
+L<Digest::HMAC>
+
+L<md5sum(1)>
+
+RFC 1321
+
+=head1 COPYRIGHT
+
+This library is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+ Copyright 1998-2000 Gisle Aas.
+ Copyright 1995-1996 Neil Winton.
+ Copyright 1991-1992 RSA Data Security, Inc.
+
+The MD5 algorithm is defined in RFC 1321. The basic C code
+implementing the algorithm is derived from that in the RFC and is
+covered by the following copyright:
+
+=over 4
+
+=item
+
+Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+rights reserved.
+
+License to copy and use this software is granted provided that it
+is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+Algorithm" in all material mentioning or referencing this software
+or this function.
+
+License is also granted to make and use derivative works provided
+that such works are identified as "derived from the RSA Data
+Security, Inc. MD5 Message-Digest Algorithm" in all material
+mentioning or referencing the derived work.
+
+RSA Data Security, Inc. makes no representations concerning either
+the merchantability of this software or the suitability of this
+software for any particular purpose. It is provided "as is"
+without express or implied warranty of any kind.
+
+These notices must be retained in any copies of any part of this
+documentation and/or software.
+
+=back
+
+This copyright does not prohibit distribution of any version of Perl
+containing this extension under the terms of the GNU or Artistic
+licenses.
+
+=head1 AUTHORS
+
+The original MD5 interface was written by Neil Winton
+(C<N.Winton@axion.bt.co.uk>).
+
+This release was made by Gisle Aas <gisle@ActiveState.com>
+
+=cut
diff --git a/ext/Digest/MD5/MD5.xs b/ext/Digest/MD5/MD5.xs
new file mode 100644
index 0000000000..40110c31b3
--- /dev/null
+++ b/ext/Digest/MD5/MD5.xs
@@ -0,0 +1,626 @@
+/* $Id: MD5.xs,v 1.26 2000/09/18 14:27:44 gisle Exp $ */
+
+/*
+ * This library is free software; you can redistribute it and/or
+ * modify it under the same terms as Perl itself.
+ *
+ * Copyright 1998-2000 Gisle Aas.
+ * Copyright 1995-1996 Neil Winton.
+ * Copyright 1991-1992 RSA Data Security, Inc.
+ *
+ * This code is derived from Neil Winton's MD5-1.7 Perl module, which in
+ * turn is derived from the reference implementation in RFC 1231 which
+ * comes with this message:
+ *
+ * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+ * rights reserved.
+ *
+ * License to copy and use this software is granted provided that it
+ * is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+ * Algorithm" in all material mentioning or referencing this software
+ * or this function.
+ *
+ * License is also granted to make and use derivative works provided
+ * that such works are identified as "derived from the RSA Data
+ * Security, Inc. MD5 Message-Digest Algorithm" in all material
+ * mentioning or referencing the derived work.
+ *
+ * RSA Data Security, Inc. makes no representations concerning either
+ * the merchantability of this software or the suitability of this
+ * software for any particular purpose. It is provided "as is"
+ * without express or implied warranty of any kind.
+ *
+ * These notices must be retained in any copies of any part of this
+ * documentation and/or software.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include "EXTERN.h"
+#include "perl.h"
+#include "XSUB.h"
+#ifdef __cplusplus
+}
+#endif
+
+/*#define MD5_DEBUG /**/
+
+/* Perl does not guarantee that U32 is exactly 32 bits. Some system
+ * has no integral type with exactly 32 bits. For instance, A Cray has
+ * short, int and long all at 64 bits so we need to apply this macro
+ * to reduce U32 values to 32 bits at appropriate places. If U32
+ * really does have 32 bits then this is a no-op.
+ */
+#if BYTEORDER > 0x4321 || defined(TRUNCATE_U32)
+ #define TO32(x) ((x) & 0xFFFFffff)
+ #define TRUNC32(x) ((x) &= 0xFFFFffff)
+#else
+ #define TO32(x) (x)
+ #define TRUNC32(x) /*nothing*/
+#endif
+
+/* The MD5 algorithm is defined in terms of little endian 32-bit
+ * values. The following macros (and functions) allow us to convert
+ * between native integers and such values.
+ */
+#undef BYTESWAP
+#ifndef U32_ALIGNMENT_REQUIRED
+ #if BYTEORDER == 0x1234 /* 32-bit little endian */
+ #define BYTESWAP(x) (x) /* no-op */
+
+ #elif BYTEORDER == 0x4321 /* 32-bit big endian */
+ #define BYTESWAP(x) ((((x)&0xFF)<<24) \
+ |(((x)>>24)&0xFF) \
+ |(((x)&0x0000FF00)<<8) \
+ |(((x)&0x00FF0000)>>8) )
+ #endif
+#endif
+
+#ifndef BYTESWAP
+static void u2s(U32 u, U8* s)
+{
+ *s++ = u & 0xFF;
+ *s++ = (u >> 8) & 0xFF;
+ *s++ = (u >> 16) & 0xFF;
+ *s = (u >> 24) & 0xFF;
+}
+
+#define s2u(s,u) ((u) = (U32)(*s) | \
+ ((U32)(*(s+1)) << 8) | \
+ ((U32)(*(s+2)) << 16) | \
+ ((U32)(*(s+3)) << 24))
+#endif
+
+#define MD5_CTX_SIGNATURE 200003165
+
+/* This stucture keeps the current state of algorithm.
+ */
+typedef struct {
+ U32 signature; /* safer cast in get_md5_ctx() */
+ U32 A, B, C, D; /* current digest */
+ U32 bytes_low; /* counts bytes in message */
+ U32 bytes_high; /* turn it into a 64-bit counter */
+ U8 buffer[128]; /* collect complete 64 byte blocks */
+} MD5_CTX;
+
+
+/* Padding is added at the end of the message in order to fill a
+ * complete 64 byte block (- 8 bytes for the message length). The
+ * padding is also the reason the buffer in MD5_CTX have to be
+ * 128 bytes.
+ */
+static unsigned char PADDING[64] = {
+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/* Constants for MD5Transform routine.
+ */
+#define S11 7
+#define S12 12
+#define S13 17
+#define S14 22
+#define S21 5
+#define S22 9
+#define S23 14
+#define S24 20
+#define S31 4
+#define S32 11
+#define S33 16
+#define S34 23
+#define S41 6
+#define S42 10
+#define S43 15
+#define S44 21
+
+/* F, G, H and I are basic MD5 functions.
+ */
+#define F(x, y, z) (((x) & ((y) ^ (z)) ^ (z)))
+#define G(x, y, z) F(z, x, y)
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define I(x, y, z) ((y) ^ ((x) | (~z)))
+
+/* ROTATE_LEFT rotates x left n bits.
+ */
+#define ROTATE_LEFT(x, n) (((x) << (n) | ((x) >> (32-(n)))))
+
+/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
+ * Rotation is separate from addition to prevent recomputation.
+ */
+#define FF(a, b, c, d, s, ac) \
+ (a) += F ((b), (c), (d)) + (NEXTx) + (U32)(ac); \
+ TRUNC32((a)); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ TRUNC32((a));
+
+#define GG(a, b, c, d, x, s, ac) \
+ (a) += G ((b), (c), (d)) + X[x] + (U32)(ac); \
+ TRUNC32((a)); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ TRUNC32((a));
+
+#define HH(a, b, c, d, x, s, ac) \
+ (a) += H ((b), (c), (d)) + X[x] + (U32)(ac); \
+ TRUNC32((a)); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ TRUNC32((a));
+
+#define II(a, b, c, d, x, s, ac) \
+ (a) += I ((b), (c), (d)) + X[x] + (U32)(ac); \
+ TRUNC32((a)); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ TRUNC32((a));
+
+
+static void
+MD5Init(MD5_CTX *ctx)
+{
+ /* Start state */
+ ctx->A = 0x67452301;
+ ctx->B = 0xefcdab89;
+ ctx->C = 0x98badcfe;
+ ctx->D = 0x10325476;
+
+ /* message length */
+ ctx->bytes_low = ctx->bytes_high = 0;
+}
+
+
+static void
+MD5Transform(MD5_CTX* ctx, const U8* buf, STRLEN blocks)
+{
+ static int tcount = 0;
+
+ U32 A = ctx->A;
+ U32 B = ctx->B;
+ U32 C = ctx->C;
+ U32 D = ctx->D;
+
+#ifndef U32_ALIGNMENT_REQUIRED
+ const U32 *x = (U32*)buf; /* really just type casting */
+#endif
+
+ do {
+ U32 a = A;
+ U32 b = B;
+ U32 c = C;
+ U32 d = D;
+
+#if BYTEORDER == 0x1234 && !defined(U32_ALIGNMENT_REQUIRED)
+ const U32 *X = x;
+ #define NEXTx (*x++)
+#else
+ U32 X[16]; /* converted values, used in round 2-4 */
+ U32 *uptr = X;
+ U32 tmp;
+ #ifdef BYTESWAP
+ #define NEXTx (tmp=*x++, *uptr++ = BYTESWAP(tmp))
+ #else
+ #define NEXTx (s2u(buf,tmp), buf += 4, *uptr++ = tmp)
+ #endif
+#endif
+
+#ifdef MD5_DEBUG
+ if (buf == ctx->buffer)
+ fprintf(stderr,"%5d: Transform ctx->buffer", ++tcount);
+ else
+ fprintf(stderr,"%5d: Transform %p (%d)", ++tcount, buf, blocks);
+
+ {
+ int i;
+ fprintf(stderr,"[");
+ for (i = 0; i < 16; i++) {
+ fprintf(stderr,"%x,", x[i]);
+ }
+ fprintf(stderr,"]\n");
+ }
+#endif
+
+ /* Round 1 */
+ FF (a, b, c, d, S11, 0xd76aa478); /* 1 */
+ FF (d, a, b, c, S12, 0xe8c7b756); /* 2 */
+ FF (c, d, a, b, S13, 0x242070db); /* 3 */
+ FF (b, c, d, a, S14, 0xc1bdceee); /* 4 */
+ FF (a, b, c, d, S11, 0xf57c0faf); /* 5 */
+ FF (d, a, b, c, S12, 0x4787c62a); /* 6 */
+ FF (c, d, a, b, S13, 0xa8304613); /* 7 */
+ FF (b, c, d, a, S14, 0xfd469501); /* 8 */
+ FF (a, b, c, d, S11, 0x698098d8); /* 9 */
+ FF (d, a, b, c, S12, 0x8b44f7af); /* 10 */
+ FF (c, d, a, b, S13, 0xffff5bb1); /* 11 */
+ FF (b, c, d, a, S14, 0x895cd7be); /* 12 */
+ FF (a, b, c, d, S11, 0x6b901122); /* 13 */
+ FF (d, a, b, c, S12, 0xfd987193); /* 14 */
+ FF (c, d, a, b, S13, 0xa679438e); /* 15 */
+ FF (b, c, d, a, S14, 0x49b40821); /* 16 */
+
+ /* Round 2 */
+ GG (a, b, c, d, 1, S21, 0xf61e2562); /* 17 */
+ GG (d, a, b, c, 6, S22, 0xc040b340); /* 18 */
+ GG (c, d, a, b, 11, S23, 0x265e5a51); /* 19 */
+ GG (b, c, d, a, 0, S24, 0xe9b6c7aa); /* 20 */
+ GG (a, b, c, d, 5, S21, 0xd62f105d); /* 21 */
+ GG (d, a, b, c, 10, S22, 0x2441453); /* 22 */
+ GG (c, d, a, b, 15, S23, 0xd8a1e681); /* 23 */
+ GG (b, c, d, a, 4, S24, 0xe7d3fbc8); /* 24 */
+ GG (a, b, c, d, 9, S21, 0x21e1cde6); /* 25 */
+ GG (d, a, b, c, 14, S22, 0xc33707d6); /* 26 */
+ GG (c, d, a, b, 3, S23, 0xf4d50d87); /* 27 */
+ GG (b, c, d, a, 8, S24, 0x455a14ed); /* 28 */
+ GG (a, b, c, d, 13, S21, 0xa9e3e905); /* 29 */
+ GG (d, a, b, c, 2, S22, 0xfcefa3f8); /* 30 */
+ GG (c, d, a, b, 7, S23, 0x676f02d9); /* 31 */
+ GG (b, c, d, a, 12, S24, 0x8d2a4c8a); /* 32 */
+
+ /* Round 3 */
+ HH (a, b, c, d, 5, S31, 0xfffa3942); /* 33 */
+ HH (d, a, b, c, 8, S32, 0x8771f681); /* 34 */
+ HH (c, d, a, b, 11, S33, 0x6d9d6122); /* 35 */
+ HH (b, c, d, a, 14, S34, 0xfde5380c); /* 36 */
+ HH (a, b, c, d, 1, S31, 0xa4beea44); /* 37 */
+ HH (d, a, b, c, 4, S32, 0x4bdecfa9); /* 38 */
+ HH (c, d, a, b, 7, S33, 0xf6bb4b60); /* 39 */
+ HH (b, c, d, a, 10, S34, 0xbebfbc70); /* 40 */
+ HH (a, b, c, d, 13, S31, 0x289b7ec6); /* 41 */
+ HH (d, a, b, c, 0, S32, 0xeaa127fa); /* 42 */
+ HH (c, d, a, b, 3, S33, 0xd4ef3085); /* 43 */
+ HH (b, c, d, a, 6, S34, 0x4881d05); /* 44 */
+ HH (a, b, c, d, 9, S31, 0xd9d4d039); /* 45 */
+ HH (d, a, b, c, 12, S32, 0xe6db99e5); /* 46 */
+ HH (c, d, a, b, 15, S33, 0x1fa27cf8); /* 47 */
+ HH (b, c, d, a, 2, S34, 0xc4ac5665); /* 48 */
+
+ /* Round 4 */
+ II (a, b, c, d, 0, S41, 0xf4292244); /* 49 */
+ II (d, a, b, c, 7, S42, 0x432aff97); /* 50 */
+ II (c, d, a, b, 14, S43, 0xab9423a7); /* 51 */
+ II (b, c, d, a, 5, S44, 0xfc93a039); /* 52 */
+ II (a, b, c, d, 12, S41, 0x655b59c3); /* 53 */
+ II (d, a, b, c, 3, S42, 0x8f0ccc92); /* 54 */
+ II (c, d, a, b, 10, S43, 0xffeff47d); /* 55 */
+ II (b, c, d, a, 1, S44, 0x85845dd1); /* 56 */
+ II (a, b, c, d, 8, S41, 0x6fa87e4f); /* 57 */
+ II (d, a, b, c, 15, S42, 0xfe2ce6e0); /* 58 */
+ II (c, d, a, b, 6, S43, 0xa3014314); /* 59 */
+ II (b, c, d, a, 13, S44, 0x4e0811a1); /* 60 */
+ II (a, b, c, d, 4, S41, 0xf7537e82); /* 61 */
+ II (d, a, b, c, 11, S42, 0xbd3af235); /* 62 */
+ II (c, d, a, b, 2, S43, 0x2ad7d2bb); /* 63 */
+ II (b, c, d, a, 9, S44, 0xeb86d391); /* 64 */
+
+ A += a; TRUNC32(A);
+ B += b; TRUNC32(B);
+ C += c; TRUNC32(C);
+ D += d; TRUNC32(D);
+
+ } while (--blocks);
+ ctx->A = A;
+ ctx->B = B;
+ ctx->C = C;
+ ctx->D = D;
+}
+
+
+#ifdef MD5_DEBUG
+static char*
+ctx_dump(MD5_CTX* ctx)
+{
+ static char buf[1024];
+ sprintf(buf, "{A=%x,B=%x,C=%x,D=%x,%d,%d(%d)}",
+ ctx->A, ctx->B, ctx->C, ctx->D,
+ ctx->bytes_low, ctx->bytes_high, (ctx->bytes_low&0x3F));
+ return buf;
+}
+#endif
+
+
+static void
+MD5Update(MD5_CTX* ctx, const U8* buf, STRLEN len)
+{
+ STRLEN blocks;
+ STRLEN fill = ctx->bytes_low & 0x3F;
+
+#ifdef MD5_DEBUG
+ static int ucount = 0;
+ fprintf(stderr,"%5i: Update(%s, %p, %d)\n", ++ucount, ctx_dump(ctx),
+ buf, len);
+#endif
+
+ ctx->bytes_low += len;
+ if (ctx->bytes_low < len) /* wrap around */
+ ctx->bytes_high++;
+
+ if (fill) {
+ STRLEN missing = 64 - fill;
+ if (len < missing) {
+ Copy(buf, ctx->buffer + fill, len, U8);
+ return;
+ }
+ Copy(buf, ctx->buffer + fill, missing, U8);
+ MD5Transform(ctx, ctx->buffer, 1);
+ buf += missing;
+ len -= missing;
+ }
+
+ blocks = len >> 6;
+ if (blocks)
+ MD5Transform(ctx, buf, blocks);
+ if ( (len &= 0x3F)) {
+ Copy(buf + (blocks << 6), ctx->buffer, len, U8);
+ }
+}
+
+
+static void
+MD5Final(U8* digest, MD5_CTX *ctx)
+{
+ STRLEN fill = ctx->bytes_low & 0x3F;
+ STRLEN padlen = (fill < 56 ? 56 : 120) - fill;
+ U32 bits_low, bits_high;
+#ifdef MD5_DEBUG
+ fprintf(stderr," Final: %s\n", ctx_dump(ctx));
+#endif
+ Copy(PADDING, ctx->buffer + fill, padlen, U8);
+ fill += padlen;
+
+ bits_low = ctx->bytes_low << 3;
+ bits_high = (ctx->bytes_high << 3) | (ctx->bytes_low >> 29);
+#ifdef BYTESWAP
+ *(U32*)(ctx->buffer + fill) = BYTESWAP(bits_low); fill += 4;
+ *(U32*)(ctx->buffer + fill) = BYTESWAP(bits_high); fill += 4;
+#else
+ u2s(bits_low, ctx->buffer + fill); fill += 4;
+ u2s(bits_high, ctx->buffer + fill); fill += 4;
+#endif
+
+ MD5Transform(ctx, ctx->buffer, fill >> 6);
+#ifdef MD5_DEBUG
+ fprintf(stderr," Result: %s\n", ctx_dump(ctx));
+#endif
+
+#ifdef BYTESWAP
+ *(U32*)digest = BYTESWAP(ctx->A); digest += 4;
+ *(U32*)digest = BYTESWAP(ctx->B); digest += 4;
+ *(U32*)digest = BYTESWAP(ctx->C); digest += 4;
+ *(U32*)digest = BYTESWAP(ctx->D);
+#else
+ u2s(ctx->A, digest);
+ u2s(ctx->B, digest+4);
+ u2s(ctx->C, digest+8);
+ u2s(ctx->D, digest+12);
+#endif
+}
+
+#ifndef INT2PTR
+#define INT2PTR(any,d) (any)(d)
+#endif
+
+static MD5_CTX* get_md5_ctx(SV* sv)
+{
+ if (SvROK(sv)) {
+ sv = SvRV(sv);
+ if (SvIOK(sv)) {
+ MD5_CTX* ctx = INT2PTR(MD5_CTX*, SvIV(sv));
+ if (ctx && ctx->signature == MD5_CTX_SIGNATURE) {
+ return ctx;
+ }
+ }
+ }
+ croak("Not a reference to a Digest::MD5 object");
+ return (MD5_CTX*)0; /* some compilers insist on a return value */
+}
+
+
+static char* hex_16(const unsigned char* from, char* to)
+{
+ static char *hexdigits = "0123456789abcdef";
+ const unsigned char *end = from + 16;
+ char *d = to;
+
+ while (from < end) {
+ *d++ = hexdigits[(*from >> 4)];
+ *d++ = hexdigits[(*from & 0x0F)];
+ from++;
+ }
+ *d = '\0';
+ return to;
+}
+
+static char* base64_16(const unsigned char* from, char* to)
+{
+ static char* base64 =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+ const unsigned char *end = from + 16;
+ unsigned char c1, c2, c3;
+ char *d = to;
+
+ while (1) {
+ c1 = *from++;
+ *d++ = base64[c1>>2];
+ if (from == end) {
+ *d++ = base64[(c1 & 0x3) << 4];
+ break;
+ }
+ c2 = *from++;
+ c3 = *from++;
+ *d++ = base64[((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4)];
+ *d++ = base64[((c2 & 0xF) << 2) | ((c3 & 0xC0) >>6)];
+ *d++ = base64[c3 & 0x3F];
+ }
+ *d = '\0';
+ return to;
+}
+
+/* Formats */
+#define F_BIN 0
+#define F_HEX 1
+#define F_B64 2
+
+static SV* make_mortal_sv(const unsigned char *src, int type)
+{
+ STRLEN len;
+ char result[33];
+ char *ret;
+
+ switch (type) {
+ case F_BIN:
+ ret = (char*)src;
+ len = 16;
+ break;
+ case F_HEX:
+ ret = hex_16(src, result);
+ len = 32;
+ break;
+ case F_B64:
+ ret = base64_16(src, result);
+ len = 22;
+ break;
+ default:
+ croak("Bad convertion type (%d)", type);
+ break;
+ }
+ return sv_2mortal(newSVpv(ret,len));
+}
+
+
+/********************************************************************/
+
+typedef PerlIO* InputStream;
+
+MODULE = Digest::MD5 PACKAGE = Digest::MD5
+
+PROTOTYPES: DISABLE
+
+void
+new(xclass)
+ SV* xclass
+ PREINIT:
+ MD5_CTX* context;
+ PPCODE:
+ if (!SvROK(xclass)) {
+ STRLEN my_na;
+ char *sclass = SvPV(xclass, my_na);
+ New(55, context, 1, MD5_CTX);
+ context->signature = MD5_CTX_SIGNATURE;
+ ST(0) = sv_newmortal();
+ sv_setref_pv(ST(0), sclass, (void*)context);
+ SvREADONLY_on(SvRV(ST(0)));
+ } else {
+ context = get_md5_ctx(xclass);
+ }
+ MD5Init(context);
+ XSRETURN(1);
+
+void
+DESTROY(context)
+ MD5_CTX* context
+ CODE:
+ Safefree(context);
+
+void
+add(self, ...)
+ SV* self
+ PREINIT:
+ MD5_CTX* context = get_md5_ctx(self);
+ int i;
+ unsigned char *data;
+ STRLEN len;
+ PPCODE:
+ for (i = 1; i < items; i++) {
+ data = (unsigned char *)(SvPV(ST(i), len));
+ MD5Update(context, data, len);
+ }
+ XSRETURN(1); /* self */
+
+void
+addfile(self, fh)
+ SV* self
+ InputStream fh
+ PREINIT:
+ MD5_CTX* context = get_md5_ctx(self);
+ STRLEN fill = context->bytes_low & 0x3F;
+ unsigned char buffer[4096];
+ int n;
+ CODE:
+ if (fh) {
+ if (fill) {
+ /* The MD5Update() function is faster if it can work with
+ * complete blocks. This will fill up any buffered block
+ * first.
+ */
+ STRLEN missing = 64 - fill;
+ if ( (n = PerlIO_read(fh, buffer, missing)))
+ MD5Update(context, buffer, n);
+ else
+ XSRETURN(1); /* self */
+ }
+
+ /* Process blocks until EOF */
+ while ( (n = PerlIO_read(fh, buffer, sizeof(buffer)))) {
+ MD5Update(context, buffer, n);
+ }
+ }
+ XSRETURN(1); /* self */
+
+void
+digest(context)
+ MD5_CTX* context
+ ALIAS:
+ Digest::MD5::digest = F_BIN
+ Digest::MD5::hexdigest = F_HEX
+ Digest::MD5::b64digest = F_B64
+ PREINIT:
+ unsigned char digeststr[16];
+ PPCODE:
+ MD5Final(digeststr, context);
+ MD5Init(context); /* In case it is reused */
+ ST(0) = make_mortal_sv(digeststr, ix);
+ XSRETURN(1);
+
+void
+md5(...)
+ ALIAS:
+ Digest::MD5::md5 = F_BIN
+ Digest::MD5::md5_hex = F_HEX
+ Digest::MD5::md5_base64 = F_B64
+ PREINIT:
+ MD5_CTX ctx;
+ int i;
+ unsigned char *data;
+ STRLEN len;
+ unsigned char digeststr[16];
+ PPCODE:
+ MD5Init(&ctx);
+ for (i = 0; i < items; i++) {
+ data = (unsigned char *)(SvPV(ST(i), len));
+ MD5Update(&ctx, data, len);
+ }
+ MD5Final(digeststr, &ctx);
+ ST(0) = make_mortal_sv(digeststr, ix);
+ XSRETURN(1);
diff --git a/ext/Digest/MD5/Makefile.PL b/ext/Digest/MD5/Makefile.PL
new file mode 100644
index 0000000000..9d59dba621
--- /dev/null
+++ b/ext/Digest/MD5/Makefile.PL
@@ -0,0 +1,20 @@
+require 5.004;
+use strict;
+use Config qw(%Config);
+use ExtUtils::MakeMaker;
+
+my @extra;
+@extra = (DEFINE => "-DU32_ALIGNMENT_REQUIRED")
+ if $Config{'byteorder'} ne '1234' ||
+ $Config{'byteorder'} ne '4321' ||
+ $^O eq 'VMS' ||
+ $Config{u32_alignment_required};
+
+WriteMakefile(
+ 'NAME' => 'Digest::MD5',
+ 'VERSION_FROM' => 'MD5.pm',
+ @extra,
+ 'dist' => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', },
+);
+exit;
+
diff --git a/ext/Digest/MD5/hints/irix_6.pl b/ext/Digest/MD5/hints/irix_6.pl
new file mode 100644
index 0000000000..e38ae14951
--- /dev/null
+++ b/ext/Digest/MD5/hints/irix_6.pl
@@ -0,0 +1,6 @@
+# The Mongoose v7.1 compiler freezes up somewhere in the optimization of
+# MD5Transform() in MD5.c with optimization -O3. This is a workaround:
+
+if ($Config{cc} =~ /64|n32/ && `$Config{cc} -version 2>&1` =~ /\s7\.1/) {
+ $self->{OPTIMIZE} = "-O1";
+}
diff --git a/ext/Digest/MD5/typemap b/ext/Digest/MD5/typemap
new file mode 100644
index 0000000000..d52827e046
--- /dev/null
+++ b/ext/Digest/MD5/typemap
@@ -0,0 +1,5 @@
+MD5_CTX* T_MD5_CTX
+
+INPUT
+T_MD5_CTX
+ $var = get_md5_ctx($arg)
diff --git a/hints/uwin.sh b/hints/uwin.sh
index 9141efcd13..cdab6fb715 100644
--- a/hints/uwin.sh
+++ b/hints/uwin.sh
@@ -24,7 +24,7 @@ i_utime=undef
# compile/link flags
ldflags=-g
optimize=-g
-static_ext="B Data/Dumper Fcntl Filter::Util::Call IO IPC/SysV Opcode POSIX SDBM_File Socket Storable attrs"
+static_ext="B Data/Dumper Digest/MD5 Fcntl Filter::Util::Call IO IPC/SysV Opcode POSIX SDBM_File Socket Storable attrs"
#static_ext=none
# dynamic loading needs work
usedl=undef
diff --git a/hints/vmesa.sh b/hints/vmesa.sh
index 2c95fd353f..d6d5315355 100644
--- a/hints/vmesa.sh
+++ b/hints/vmesa.sh
@@ -218,7 +218,7 @@ dynamic_ext=''
eagain='EAGAIN'
ebcdic='define'
exe_ext=''
-extensions=' Data/Dumper Errno Fcntl Filter::Util:Call GDBM_File IO NDBM_File Opcode POSIX Socket Storable IPC/SysV Thread attrs re'
+extensions='Data/Dumper Digest/MD5 Errno Fcntl Filter::Util:Call GDBM_File IO NDBM_File Opcode POSIX Socket Storable IPC/SysV Thread attrs re'
fpostype='fpos_t'
freetype='void'
groupstype='gid_t'
diff --git a/lib/Digest.pm b/lib/Digest.pm
new file mode 100644
index 0000000000..047380ebeb
--- /dev/null
+++ b/lib/Digest.pm
@@ -0,0 +1,180 @@
+package Digest;
+
+use strict;
+use vars qw($VERSION %MMAP $AUTOLOAD);
+
+$VERSION = "1.00";
+
+%MMAP = (
+ "SHA-1" => "Digest::SHA1",
+ "HMAC-MD5" => "Digest::HMAC_MD5",
+ "HMAC-SHA-1" => "Digest::HMAC_SHA1",
+);
+
+sub new
+{
+ shift; # class ignored
+ my $algorithm = shift;
+ my $class = $MMAP{$algorithm} || "Digest::$algorithm";
+ no strict 'refs';
+ unless (exists ${"$class\::"}{"VERSION"}) {
+ eval "require $class";
+ die $@ if $@;
+ }
+ $class->new(@_);
+}
+
+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
+
+ $md2 = Digest->MD2;
+ $md5 = Digest->MD5;
+
+ $sha1 = Digest->SHA1;
+ $sha1 = Digest->new("SHA-1");
+
+ $hmac = Digest->HMAC_MD5($key);
+
+=head1 DESCRIPTION
+
+The C<Digest::> 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.
+
+An important property of the digest algorithms is that the digest is
+I<likely> to change if the message change in some way. Another
+property is that digest functions are one-way functions, i.e. it
+should be I<hard> 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.
+
+All C<Digest::> 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<binary>
+
+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<hex>
+
+A twice as long string of (lowercase) hexadecimal digits.
+
+=item I<base64>
+
+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<MIME::Base64> 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<Digest::> 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 new() is called as a 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 $ctx->reset
+
+This is just an alias for $ctx->new.
+
+=item $ctx->add($data,...)
+
+The $data provided as argument are appended to the message we
+calculate the digest for. The return value is the $ctx object itself.
+
+=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.
+
+=item $ctx->digest
+
+Return the binary digest for the message.
+
+Note that the C<digest> operation is effectively a destructive,
+read-once operation. Once it has been performed, the $ctx object is
+automatically C<reset> and can be used to calculate another digest
+value.
+
+=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 SEE ALSO
+
+L<Digest::MD5>, L<Digest::SHA1>, L<Digest::HMAC>, L<Digest::MD2>
+
+L<MIME::Base64>
+
+=head1 AUTHOR
+
+Gisle Aas <gisle@aas.no>
+
+The C<Digest::> interface is based on the interface originally
+developed by Neil Winton for his C<MD5> module.
+
+=cut
diff --git a/t/lib/digest.t b/t/lib/digest.t
new file mode 100644
index 0000000000..200de2bc54
--- /dev/null
+++ b/t/lib/digest.t
@@ -0,0 +1,21 @@
+print "1..3\n";
+
+BEGIN {
+ chdir 't' if -d 't';
+ @INC = '../lib';
+}
+
+use Digest;
+
+print "not " unless Digest->MD5->add("abc")->hexdigest eq "900150983cd24fb0d6963f7d28e17f72";
+print "ok 1\n";
+
+print "not " unless Digest->MD5->add("abc")->hexdigest eq "900150983cd24fb0d6963f7d28e17f72";
+print "ok 2\n";
+
+eval {
+ print "not " unless Digest->new("HMAC-MD5" => "Jefe")->add("what do ya want for nothing?")->hexdigest eq "750c783e6ab0b503eaa86e310a5db738";
+ print "ok 3\n";
+};
+print "ok 3\n" if $@ && $@ =~ /^Can't locate/;
+
diff --git a/t/lib/md5-aaa.t b/t/lib/md5-aaa.t
new file mode 100644
index 0000000000..62ae4c66e1
--- /dev/null
+++ b/t/lib/md5-aaa.t
@@ -0,0 +1,287 @@
+BEGIN {
+ chdir 't' if -d 't';
+ @INC = '../lib';
+}
+
+use strict;
+print "1..256\n";
+
+use Digest::MD5 qw(md5_hex);
+
+my $testno = 0;
+while (<DATA>) {
+ my($hexdigest, $message) = split;
+ $message =~ s/\"//g;
+
+ my $failed;
+ $failed++ unless md5_hex($message) eq $hexdigest;
+ $failed++ unless Digest::MD5->new->add(split(//, $message))->digest
+ eq pack("H*", $hexdigest);
+
+ print "not " if $failed;
+ print "ok ", ++$testno, "\n";
+}
+
+
+
+# This data was generated with:
+#
+# perl -e 'for (1..256) { system("md5sum --string=" . ("a" x $_)); }'
+#
+__END__
+0cc175b9c0f1b6a831c399e269772661 "a"
+4124bc0a9335c27f086f24ba207a4912 "aa"
+47bce5c74f589f4867dbd57e9ca9f808 "aaa"
+74b87337454200d4d33f80c4663dc5e5 "aaaa"
+594f803b380a41396ed63dca39503542 "aaaaa"
+0b4e7a0e5fe84ad35fb5f95b9ceeac79 "aaaaaa"
+5d793fc5b00a2348c3fb9ab59e5ca98a "aaaaaaa"
+3dbe00a167653a1aaee01d93e77e730e "aaaaaaaa"
+552e6a97297c53e592208cf97fbb3b60 "aaaaaaaaa"
+e09c80c42fda55f9d992e59ca6b3307d "aaaaaaaaaa"
+d57f21e6a273781dbf8b7657940f3b03 "aaaaaaaaaaa"
+45e4812014d83dde5666ebdf5a8ed1ed "aaaaaaaaaaaa"
+c162de19c4c3731ca3428769d0cd593d "aaaaaaaaaaaaa"
+451599a5f9afa91a0f2097040a796f3d "aaaaaaaaaaaaaa"
+12f9cf6998d52dbe773b06f848bb3608 "aaaaaaaaaaaaaaa"
+23ca472302f49b3ea5592b146a312da0 "aaaaaaaaaaaaaaaa"
+88e42e96cc71151b6e1938a1699b0a27 "aaaaaaaaaaaaaaaaa"
+2c60c24e7087e18e45055a33f9a5be91 "aaaaaaaaaaaaaaaaaa"
+639d76897485360b3147e66e0a8a3d6c "aaaaaaaaaaaaaaaaaaa"
+22d42eb002cefa81e9ad604ea57bc01d "aaaaaaaaaaaaaaaaaaaa"
+bd049f221af82804c5a2826809337c9b "aaaaaaaaaaaaaaaaaaaaa"
+ff49cfac3968dbce26ebe7d4823e58bd "aaaaaaaaaaaaaaaaaaaaaa"
+d95dbfee231e34cccb8c04444412ed7d "aaaaaaaaaaaaaaaaaaaaaaa"
+40edae4bad0e5bf6d6c2dc5615a86afb "aaaaaaaaaaaaaaaaaaaaaaaa"
+a5a8bfa3962f49330227955e24a2e67c "aaaaaaaaaaaaaaaaaaaaaaaaa"
+ae791f19bdf77357ff10bb6b0e97e121 "aaaaaaaaaaaaaaaaaaaaaaaaaa"
+aaab9c59a88bf0bdfcb170546c5459d6 "aaaaaaaaaaaaaaaaaaaaaaaaaaa"
+b0f0545856af1a340acdedce23c54b97 "aaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+f7ce3d7d44f3342107d884bfa90c966a "aaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+59e794d45697b360e18ba972bada0123 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+3b0845db57c200be6052466f87b2198a "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+5eca9bd3eb07c006cd43ae48dfde7fd3 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+b4f13cb081e412f44e99742cb128a1a5 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+4c660346451b8cf91ef50f4634458d41 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+11db24dc3f6c2145701db08625dd6d76 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+80dad3aad8584778352c68ab06250327 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+1227fe415e79db47285cb2689c93963f "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+8e084f489f1bdf08c39f98ff6447ce6d "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+08b2f2b0864bac1ba1585043362cbec9 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+4697843037d962f62a5a429e611e0f5f "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+10c4da18575c092b486f8ab96c01c02f "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+af205d729450b663f48b11d839a1c8df "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+0d3f91798fac6ee279ec2485b25f1124 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+4c3c7c067634daec9716a80ea886d123 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+d1e358e6e3b707282cdd06e919f7e08c "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+8c6ded4f0af86e0a7e301f8a716c4363 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+4c2d8bcb02d982d7cb77f649c0a2dea8 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+bdb662f765cd310f2a547cab1cfecef6 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+08ff5f7301d30200ab89169f6afdb7af "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+6eb6a030bcce166534b95bc2ab45d9cf "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+1bb77918e5695c944be02c16ae29b25e "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+b6fe77c19f0f0f4946c761d62585bfea "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+e9e7e260dce84ffa6e0e7eb5fd9d37fc "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+eced9e0b81ef2bba605cbc5e2e76a1d0 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ef1772b6dff9a122358552954ad0df65 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+3b0c8ac703f828b04c6c197006d17218 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+652b906d60af96844ebd21b674f35e93 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+dc2f2f2462a0d72358b2f99389458606 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+762fc2665994b217c52c3c2eb7d9f406 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+cc7ed669cf88f201c3297c6a91e1d18d "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+cced11f7bbbffea2f718903216643648 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+24612f0ce2c9d2cf2b022ef1e027a54f "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+b06521f39153d618550606be297466d5 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+014842d480b571495a4a0363793f7367 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+c743a45e0d2e6a95cb859adae0248435 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+def5d97e01e1219fb2fc8da6c4d6ba2f "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+92cb737f8687ccb93022fdb411a77cca "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+a0d1395c7fb36247bfe2d49376d9d133 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ab75504250558b788f99d1ebd219abf2 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+0f5c6c4e740bfcc08c3c26ccb2673d46 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+cddd19bec7f310d8c87149ef47a1828f "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+96b39b8b95e016c79d104d83395b8133 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+f1fc0b14ff8fa674b02344577e23eeb1 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+0e8d28a1cafa3ffcff22afd480cce7d8 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+448539ffc17e1e81005b65581855cef4 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+61e39aae7c53e6e77db2e4405d9fb157 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+618a426895ee6133a372bebd1129b63e "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+046c90690c9e36578b9d4a7e1d249c75 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+aadab38075c43296ee7e12466ebb03e3 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+b15af9cdabbaea0516866a33d8fd0f98 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+986e6938ed767a8ae9530eef54bfe5f1 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+7ae25a72b71a42ccbc5477fd989cd512 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+98d34e50d4aa7a893cc7919a91acb0e3 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+3fc53fc22ea40f1a0afd78fc2cd9aa0f "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+923e37c738b9d7b1526f70b65229cc3d "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+b3966b7a08e5d46fd0774b797ba78dc2 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+f50c7286b540bb181db1d6e05a51a296 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+4efd6c8826e65a61f82af954d431b59b "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ef1031e79e7a15a4470a5e98b23781b5 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+067876bfd0df0f4c5002780ec85e6f8c "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+789851dfa4c03563e9cef5f7bc050a7e "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+baf934720818ee49477e74fc644faa5e "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+9a0ea77ca26d2c121ddcc179edb76308 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+20c825561572e33d026f99ddfd999538 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+464c461455c5a927079a13609c20b637 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+cf37d42f89b6adb0e1a9e99104501b82 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+d266af45e3d06b70d9f52e2df4344186 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+f8b59fa22eb0ba944e2b7aa24d67b681 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+0918d7c2f9062743450a86eae9dde1a3 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+36a92cc94a9e0fa21f625f8bfb007adf "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+681d73898dad5685d48b5e8438bc3a66 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+337ccef058459c3c16411381778da0c4 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+6ccdfcc742862036ce07583633c5f77e "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ddfa1adc974649dc5b414be86def7457 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+650ebc28ad85f11aa4b63b6ee565b89d "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+e4571793bcaba284017eeabd8df85697 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+4fc040d354ad9ba5e4f62862109d3e17 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+25814274e02aa7cc03d6314eb703e655 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+11378ecaee0089c840d26352704027e3 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+86f950bfcd824d5546da01c40576db31 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+089f243d1e831c5879aa375ee364a06e "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+9146ef3527c7cfcc66dc615c3986e391 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+d727cfdfc9ed0347e6917a68b982f7bc "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+da8f45e1fdc12deecfe56aeb5288796e "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+29cfcf52d8250a253a535cf7989c7bd2 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+0f6eb555b8e3c35411eebe9348594193 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+a922439f963e7e59040e4756992c6f1b "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+81f8453cf3f7e5ee5479c777e5a8d80c "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+8a7bd0732ed6a28ce75f6dabc90e1613 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+5f61c0ccad4cac44c75ff505e1f1e537 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+f6acfca2d47c87f2b14ca038234d3614 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+269fc62c517f3d55c368152addca57e7 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+50587cb16413da779b35508018721647 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+5e4a3ecfdaa4636b84a39b6a7be7c047 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+c5339dc2af6bf595580281ffb07353f6 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+e51176a47347e167ed0ed766b6de1a0c "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+020406e1d05cdc2aa287641f7ae2cc39 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+e510683b3f5ffe4093d021808bc6ff70 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+b325dc1c6f5e7a2b7cf465b9feab7948 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+e016e4ccc7fdaea56fc377600b58c4cb "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+3870ec709d2fc64b255d65be3123ad69 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+a92bde1f862c3fe797ecd69510bbd266 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+04daa146f3a2256fdcbf015c0f67e168 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+3d13c8bf627421ccc937aa1c9ac87bf1 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+247dc7ffc545e4dda64ae12def481c4e "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+2dfd4def392ee9563241b7db7eb7c346 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+d11a18a4743a1a0a699d1704efb74a0d "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+55b62fabd9c77d44d86e992eeeb093e6 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+9a72cf7d0bd5ae2907c79f91837e3ced "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+d3828cce1835534475029202ebd799e4 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+b0bebbf0015658d4740679f263a3f01f "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+02368ebf1f53bc4634211b1693021666 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+04960f7d18960e348372949e4baa9752 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+c6041e7a86d407e9402b175670519260 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+439fd4c056bec1d14acd393746f6ae59 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+81a855120e04494c5a6c874a2360fd57 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ef57bd47a964dc3aadd959c4131e64ac "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+0b0ab27b16cbba267c141fe0f4ee9189 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+abccd84f340bfe4ba59095cc3d5ca6ad "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+bc620e8c15265f195c8818e2f3e3c58b "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+fdcd84c4143286f6fc70c69208acd18d "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+50e05071e773b1e9f3009a4a559ce6b2 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+9e69c7a6c1863fbba2532f09ba665bde "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+47a962111aa5187eeef3d17a278d95f2 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+c13e57e33526bc713b5a1825f92651bc "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+72b392f15593e42404b38e5c889fa75e "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+5327acd3278274265d44e22ccfc4042c "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+930dcac6da160b2a4c51879da76d3417 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+41292c326f926f1534ead47fe302f0a0 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+2bdecb5cf6b69a00f7832299ef2fb5a5 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+8bf93e9e8a3e4396de3f211c788e177e "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+eea9cb566e19d6a7f55fbae78d94ef2a "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+3b8452700a829dec78397aa5c0458dd3 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+7950059f699eaea1e0a1759340d7c153 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+40840c5f1de00f17a8e70d5bd4d00af2 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+80f86f6af38be9ca8e40c2dc44491a0a "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+7aab2c2e72c77163e7102412dc332125 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+bfd6869ae2ee2fe2675846d341eaa67d "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+7e4d976f6d552d1d5bac7e2693dc8759 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+37d9884c32abfc6f372ee899434e64ad "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+e362cd83a4b49d81ac6788b7839a56fd "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+9203cbb93b25d80b9d1b75e3c6c4b0dc "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+77441eda11554ec5b915d942605f66ed "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+e0fe0c02b5c9c5afe10ab9d6a3769efe "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+cc7682cf11b214e928f3df899772e789 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ade0901d347afb25ecf9df4955bb8061 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+987379587cbe8e94b7057269232ff826 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+fd44a60101b04b7ddbc2b4e9b509ca1f "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+53107a7f1e6f13a2e63239b6f2bf0ef1 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+0b82cdd562f26aaa2459610a7ba8cd76 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+79f12de7255e9c8c0ec9a9be45ee6210 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+92338d8de02ed7aa8b3adc9120b94e71 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+8fc48efda580fce85b8705d540e8382e "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+63642b027ee89938c922722650f2eb9b "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+fe54daa473502e9cc2c26dd66d564eab "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+b90f3d4b7dcd8cdd8d96cb14695f4793 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+3e73392e7a03bca45b67650d79a8fc63 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+7fe51f2642dffbabc33eea2fcc2039ba "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+bc33790e52f99718cf920329961ee753 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+54d1e41ebac5db7886f01ab0afb65b17 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+16e2824f7a3f00ef0028994182071953 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+234c07907df5019d5f40f03936939bce "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+8ea3af1d9476fa0b6c04ce4f3a336c03 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+e95b69eae07d498d484afc771d1c45fc "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+f22a673abbc4372544ba37b51a5f5a91 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+7e6161eb1be7b06928c536fada91b7f1 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+4dfe3c301e88fff67822e1cfcfece43f "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+edda210ac6645fbf5815eb4c58821f6d "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+6a514de2bf1926129b08f9234cd0115e "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+887f30b43b2867f4a9accceee7d16e6c "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+15936442c22dab9b685de350bfe75971 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+281a39e10bab29f1f2dead149a1f3f87 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+04d5f8a53b0eeda82d3c0ccafd02c98e "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+a91e6b80fe9d6db74fac76c7a67f065a "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+30334486fa9841044afb07f2573107a5 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+0183c0cf15a3c2ed97d326f421b6d62c "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+4dc2a01b2161653753019b5228f765f8 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+71ef2dbdec7f78005354abebbfec8d8f "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+a1d1cd1446c113726ba50cc86d8b6519 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ed6da79cfd13ece051c4cb7c88e80c2e "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+d2047852ce178d4ddb7978da3883f9c5 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+d75382e07dd096b618faeeac033eefff "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+3fb48e286d462dcc237c3335aa63ba14 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+55b959972677ea06c4d0e32f7fb2f10a "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+0a479c3623cfb9745e54d3376d0b9ae2 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+7825ad1ba19db7eec57d88b16936f32f "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+833ccf25509cb423a4aa98accb15512d "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+cae9609b05a9782610a5a43d7cd4b8ff "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+6c303e1da7f8a3032d13fe995847a722 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+4c47143a568e30ecde86dafe3bcb0558 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+9c48f0592f504b86360cfb6de00203b3 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+e1524f5686f170209366f9723880d9b0 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+a96164a43a192543d40e538b9e9e4ece "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+b774a4f788458a60e131d998705e4a06 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+1e97f0a7dfd3fac6ae585acdcf51a549 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+b6364c77b6dd495c2a7f6b0211ac6fce "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+5d22315e78df2bc4146aa66f6c405dbb "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+2a773d5b04e910612543a42deeaaaa62 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+0165449ac66b086accdec3051e0b691e "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+54884ba571054eae72b2a5271828a1fc "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+520fb61f8625ea916d72a54a37937bc6 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+7717f05d6e424a2c7a20ab7977b21ec8 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+b64e4f62e3e14317e3a90f9ff2cde576 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+a49128259cfe50ba3bed80bbd11add7f "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+b10cb153b79c2e4af6a8431c265aa82d "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+2e50fee6f574241042bdfabfdd46a153 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+5d5656a09b98c24edd01c530d3aad5e2 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+5ac1e1609d82274371c349d5b7875298 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+b7b40d64ffccebd78abcf522376b3aae "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+8619933469d908a2d4a2d890909bea43 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+591a0ee6dccd872b46ae184eb0f9450e "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+8cd256a02c8c5c1676e9220e655d9ac4 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+e48c0e2ed3e4e299a6e62e5416eb6d83 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+f30f75dce71e757ee562218c1efa0645 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+06bd7e90c0410dacb155732cf956f520 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+531a0a821a9304c215f1829b880306f1 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+93f4621c0b88499297ec3f8fbb3fb9c4 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+6af3d61e2e3ef8e189cffbea802c7e69 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+df84d21c884f99d6764d9bca4dec26e1 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+1bdbdf1c9087c796394bcda5789f7206 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+21f5b107cda33036590a19419afd7fb6 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+0eae304c738191613302fb6721ea3605 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+abed9cdef66dcec954b87124ba18c1ab "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+dfde09457e2017e31d4ecfaea010db8f "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+46bc249a5a8fc5d622cf12c42c463ae0 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+81109eec5aa1a284fb5327b10e9c16b9 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
diff --git a/t/lib/md5-badf.t b/t/lib/md5-badf.t
new file mode 100644
index 0000000000..63effdfc21
--- /dev/null
+++ b/t/lib/md5-badf.t
@@ -0,0 +1,26 @@
+BEGIN {
+ chdir 't' if -d 't';
+ @INC = '../lib';
+}
+
+# Digest::MD5 2.07 and older used to trigger a core dump when
+# passed an illegal file handle that failed to open.
+
+print "1..2\n";
+
+use Digest::MD5 ();
+
+$md5 = Digest::MD5->new;
+
+eval {
+ use vars qw(*FOO);
+ $md5->addfile(*FOO);
+};
+print "not " unless $@ =~ /^Bad filehandle: FOO/;
+print "ok 1\n";
+
+open(BAR, "none-existing-file.$$");
+$md5->addfile(*BAR);
+
+print "not " unless $md5->hexdigest eq "d41d8cd98f00b204e9800998ecf8427e";
+print "ok 2\n";
diff --git a/t/lib/md5-file.t b/t/lib/md5-file.t
new file mode 100644
index 0000000000..5e6ba338f9
--- /dev/null
+++ b/t/lib/md5-file.t
@@ -0,0 +1,111 @@
+BEGIN {
+ chdir 't' if -d 't';
+ @INC = '../lib';
+}
+
+print "1..2\n";
+
+use strict;
+use Digest::MD5 qw(md5 md5_hex);
+
+#
+# This is the output of: 'md5sum MD5.pm MD5.xs'
+#
+my $EXPECT = <<EOT;
+9e1d1183ff41717c91a563c41e08d672 ext/Digest/MD5/MD5.pm
+61debd0ec12e131e1ba220e2f3ad2d26 ext/Digest/MD5/MD5.xs
+EOT
+
+my $testno = 0;
+
+use File::Spec;
+
+for (split /^/, $EXPECT) {
+ my($md5hex, $file) = split ' ';
+ my @path = split(m:/:, $file);
+ my $last = pop @path;
+ my $path = File::Spec->updir;
+ while (@path) {
+ $path = File::Spec->catdir($path, shift @path);
+ }
+ $file = File::Spec->catfile($path, $last);
+ my $md5bin = pack("H*", $md5hex);
+ my $failed;
+
+ if (digest_file($file, 'digest') ne $md5bin) {
+ print "$file: Bad digest\n";
+ $failed++;
+ }
+
+ if (digest_file($file, 'hexdigest') ne $md5hex) {
+ print "$file: Bad hexdigest\n";
+ $failed++;
+ }
+
+ my $data = cat_file($file);
+ if (md5($data) ne $md5bin) {
+ print "$file: md5() failed\n";
+ $failed++;
+ }
+ if (md5_hex($data) ne $md5hex) {
+ print "$file: md5_hex() failed\n";
+ $failed++;
+ }
+
+ if (Digest::MD5->new->add($data)->digest ne $md5bin) {
+ print "$file: MD5->new->add(...)->digest failed\n";
+ $failed++;
+ }
+ if (Digest::MD5->new->add($data)->hexdigest ne $md5hex) {
+ print "$file: MD5->new->add(...)->hexdigest failed\n";
+ $failed++;
+ }
+
+ my @data = split //, $data;
+ if (md5(@data) ne $md5bin) {
+ print "$file: md5(\@data) failed\n";
+ $failed++;
+ }
+ if (Digest::MD5->new->add(@data)->digest ne $md5bin) {
+ print "$file: MD5->new->add(\@data)->digest failed\n";
+ $failed++;
+ }
+ my $md5 = Digest::MD5->new;
+ for (@data) {
+ $md5->add($_);
+ }
+ if ($md5->digest ne $md5bin) {
+ print "$file: $md5->add()-loop failed\n";
+ $failed++;
+ }
+
+ print "not " if $failed;
+ print "ok ", ++$testno, "\n";
+}
+
+
+sub digest_file
+{
+ my($file, $method) = @_;
+ $method ||= "digest";
+ #print "$file $method\n";
+
+ open(FILE, $file) or die "Can't open $file: $!";
+ binmode(FILE);
+ my $digest = Digest::MD5->new->addfile(*FILE)->$method();
+ close(FILE);
+
+ $digest;
+}
+
+sub cat_file
+{
+ my($file) = @_;
+ local $/; # slurp
+ open(FILE, $file) or die "Can't open $file: $!";
+ binmode(FILE);
+ my $tmp = <FILE>;
+ close(FILE);
+ $tmp;
+}
+
diff --git a/win32/Makefile b/win32/Makefile
index 9049099398..295afc46b8 100644
--- a/win32/Makefile
+++ b/win32/Makefile
@@ -608,7 +608,7 @@ SETARGV_OBJ = setargv$(o)
DYNAMIC_EXT = Socket IO Fcntl Opcode SDBM_File POSIX attrs Thread B re \
Data/Dumper Devel/Peek ByteLoader Devel/DProf File/Glob \
- Sys/Hostname Storable Filter/Util/Call Encode
+ Sys/Hostname Storable Filter/Util/Call Encode Digest/MD5
STATIC_EXT = DynaLoader
NONXS_EXT = Errno
@@ -633,6 +633,7 @@ HOSTNAME = $(EXTDIR)\Sys\Hostname\Hostname
STORABLE = $(EXTDIR)\Storable\Storable
FILTER = $(EXTDIR)\Filter\Util\Call\Call
ENCODE = $(EXTDIR)\Encode\Encode
+MD5 = $(EXTDIR)\Digest\MD5\MD5
SOCKET_DLL = $(AUTODIR)\Socket\Socket.dll
FCNTL_DLL = $(AUTODIR)\Fcntl\Fcntl.dll
@@ -653,6 +654,7 @@ HOSTNAME_DLL = $(AUTODIR)\Sys\Hostname\Hostname.dll
STORABLE_DLL = $(AUTODIR)\Storable\Storable.dll
FILTER_DLL = $(AUTODIR)\Filter\Util\Call\Call.dll
ENCODE_DLL = $(AUTODIR)\Encode\Encode.dll
+MD5_DLL = $(AUTODIR)\Digest\MD5\MD5.dll
ERRNO_PM = $(LIBDIR)\Errno.pm
@@ -675,7 +677,8 @@ EXTENSION_C = \
$(HOSTNAME).c \
$(STORABLE).c \
$(FILTER).c \
- $(ENCODE).c
+ $(ENCODE).c \
+ $(MD5).c
EXTENSION_DLL = \
$(SOCKET_DLL) \
@@ -696,7 +699,8 @@ EXTENSION_DLL = \
$(HOSTNAME_DLL) \
$(STORABLE_DLL) \
$(FILTER_DLL) \
- $(ENCODE_DLL)
+ $(ENCODE_DLL) \
+ $(MD5_DLL)
EXTENSION_PM = \
$(ERRNO_PM)
@@ -980,12 +984,6 @@ $(BYTELOADER_DLL): $(PERLEXE) $(BYTELOADER).xs
$(MAKE)
cd ..\..\win32
-$(ENCODE_DLL): $(PERLEXE) $(ENCODE).xs
- cd $(EXTDIR)\$(*B)
- ..\..\miniperl -I..\..\lib Makefile.PL INSTALLDIRS=perl
- $(MAKE)
- cd ..\..\win32
-
$(STORABLE_DLL): $(PERLEXE) $(STORABLE).xs
cd $(EXTDIR)\$(*B)
..\..\miniperl -I..\..\lib Makefile.PL INSTALLDIRS=perl
@@ -1004,6 +1002,12 @@ $(ENCODE_DLL): $(PERLEXE) $(ENCODE).xs
$(MAKE)
cd ..\..\win32
+$(MD5_DLL): $(PERLEXE) $(MD5).xs
+ cd $(EXTDIR)\$(*B)
+ ..\..\miniperl -I..\..\lib Makefile.PL INSTALLDIRS=perl
+ $(MAKE)
+ cd ..\..\win32
+
$(ERRNO_PM): $(PERLEXE) $(ERRNO)_pm.PL
cd $(EXTDIR)\$(*B)
..\..\miniperl -I..\..\lib Makefile.PL INSTALLDIRS=perl
@@ -1058,6 +1062,7 @@ distclean: clean
-del /f $(LIBDIR)\File\Glob.pm
-del /f $(LIBDIR)\Storable.pm
-del /f $(LIBDIR)\Filter\Util\Call\Call.pm
+ -del /f $(LIBDIR)\Digest\MD5.pm
-if exist $(LIBDIR)\IO rmdir /s /q $(LIBDIR)\IO
-rmdir /s $(LIBDIR)\IO
-if exist $(LIBDIR)\Thread rmdir /s /q $(LIBDIR)\Thread
@@ -1068,6 +1073,8 @@ distclean: clean
-rmdir /s $(LIBDIR)\Data
-if exist $(LIBDIR)\Filter\Util\Call rmdir /s /q $(LIBDIR)\Filter\Util\Call
-if exist $(LIBDIR)\Filter\Util rmdir /s /q $(LIBDIR)\Filter\Util
+ -if exist $(LIBDIR)\Digest rmdir /s /q $(LIBDIR)\Digest
+ -rmdir /s $(LIBDIR)\Digest
-del /f $(PODDIR)\*.html
-del /f $(PODDIR)\*.bat
cd ..\utils
diff --git a/win32/makefile.mk b/win32/makefile.mk
index 5c21ebba8f..6e91bc2b82 100644
--- a/win32/makefile.mk
+++ b/win32/makefile.mk
@@ -743,7 +743,7 @@ SETARGV_OBJ = setargv$(o)
DYNAMIC_EXT = Socket IO Fcntl Opcode SDBM_File POSIX attrs Thread B re \
Data/Dumper Devel/Peek ByteLoader Devel/DProf File/Glob \
- Sys/Hostname Storable Filter/Util/Call Encode
+ Sys/Hostname Storable Filter/Util/Call Encode Digest/MD5
STATIC_EXT = DynaLoader
NONXS_EXT = Errno
@@ -768,6 +768,7 @@ HOSTNAME = $(EXTDIR)\Sys\Hostname\Hostname
STORABLE = $(EXTDIR)\Storable\Storable
FILTER = $(EXTDIR)\Filter\Util\Call\Call
ENCODE = $(EXTDIR)\Encode\Encode
+MD5 = $(EXTDIR)\Digest\MD5\MD5
SOCKET_DLL = $(AUTODIR)\Socket\Socket.dll
FCNTL_DLL = $(AUTODIR)\Fcntl\Fcntl.dll
@@ -788,6 +789,7 @@ HOSTNAME_DLL = $(AUTODIR)\Sys\Hostname\Hostname.dll
STORABLE_DLL = $(AUTODIR)\Storable\Storable.dll
FILTER_DLL = $(AUTODIR)\Filter\Util\Call\Call.dll
ENCODE_DLL = $(AUTODIR)\Encode\Encode.dll
+MD5_DLL = $(AUTODIR)\Digest\MD5\MD5.dll
ERRNO_PM = $(LIBDIR)\Errno.pm
@@ -810,7 +812,8 @@ EXTENSION_C = \
$(HOSTNAME).c \
$(STORABLE).c \
$(FILTER).c \
- $(ENCODE).c
+ $(ENCODE).c \
+ $(MD5).c
EXTENSION_DLL = \
$(SOCKET_DLL) \
@@ -831,7 +834,8 @@ EXTENSION_DLL = \
$(HOSTNAME_DLL) \
$(STORABLE_DLL) \
$(FILTER_DLL) \
- $(ENCODE_DLL)
+ $(ENCODE_DLL) \
+ $(MD5_DLL)
EXTENSION_PM = \
$(ERRNO_PM)
@@ -1230,6 +1234,11 @@ $(FILTER_DLL): $(PERLDEP) $(FILTER).xs
..\..\..\..\miniperl -I..\..\..\..\lib Makefile.PL INSTALLDIRS=perl
cd $(EXTDIR)\Filter\Util\Call && $(MAKE)
+$(MD5_DLL): $(PERLDEP) $(FILTER).xs
+ cd $(EXTDIR)\Digest\MD5 && \
+ ..\..\..\miniperl -I..\..\..\lib Makefile.PL INSTALLDIRS=perl
+ cd $(EXTDIR)\Digest\MD5 && $(MAKE)
+
$(ERRNO_PM): $(PERLDEP) $(ERRNO)_pm.PL
cd $(EXTDIR)\$(*B) && \
..\..\miniperl -I..\..\lib Makefile.PL INSTALLDIRS=perl
@@ -1279,12 +1288,14 @@ distclean: clean
-del /f $(LIBDIR)\File\Glob.pm
-del /f $(LIBDIR)\Storable.pm
-del /f $(LIBDIR)\Filter\Util\Call\Call.pm
+ -del /f $(LIBDIR)\Digest\MD5.pm
-if exist $(LIBDIR)\IO rmdir /s /q $(LIBDIR)\IO || rmdir /s $(LIBDIR)\IO
-if exist $(LIBDIR)\Thread rmdir /s /q $(LIBDIR)\Thread || rmdir /s $(LIBDIR)\Thread
-if exist $(LIBDIR)\B rmdir /s /q $(LIBDIR)\B || rmdir /s $(LIBDIR)\B
-if exist $(LIBDIR)\Data rmdir /s /q $(LIBDIR)\Data || rmdir /s $(LIBDIR)\Data
-if exist $(LIBDIR)\Filter\Util\Call rmdir /s /q $(LIBDIR)\Filter\Util\Call || rmdir /s $(LIBDIR)\Filter
-if exist $(LIBDIR)\Filter\Util rmdir /s /q $(LIBDIR)\Filter\Util || rmdir /s $(LIBDIR)\Filter
+ -if exist $(LIBDIR)\Digest rmdir /s /q $(LIBDIR)\Digest || rmdir /s $(LIBDIR)\Digest
-del /f $(PODDIR)\*.html
-del /f $(PODDIR)\*.bat
-cd ..\utils && del /f h2ph splain perlbug pl2pm c2ph h2xs perldoc \