Anonymous Monk,
I really appreciate your help and I am not trying to intentionally be obtuse but I am still not following. The code needs to work on the output of Digest::MD5's md5() which according to the docs is This function will concatenate all arguments, calculate the MD5 digest of this "message", and return it in binary form. The returned string will be 16 bytes long.
The following code works
#!/usr/bin/perl
use strict;
use warnings;
use Digest::MD5 'md5';
use Math::BigInt;
my $thing = 'This is a thing';
my $md5 = md5($thing);
print unpack('q', $md5), "\n";
print md5_32bit_sol($md5), "\n";
sub md5_32bit_sol {
my ($md5) = @_;
return md5_32bit_positive($md5) if vec($md5, 63, 1) == 0;
return md5_32bit_negative($md5);
}
sub md5_32bit_negative {
my ($md5) = @_;
my $base_2 = '';
for (reverse 0 .. 63) {
$base_2 .= abs(vec($md5, $_, 1) - 1);
}
$base_2 =~ s/^0+//;
my $decimal = Math::BigInt->new();
my $power = Math::BigInt->new(2);
$power->bpow(length($base_2) - 1);
for my $pos (0 .. length($base_2) - 1) {
$decimal->badd($power * substr($base_2, $pos, 1));
$power->bdiv(2);
}
return ($decimal + 1) * -1;
}
sub md5_32bit_positive {
my ($md5) = @_;
my $base_2 = '';
for (reverse 0 .. 63) {
$base_2 .= vec($md5, $_, 1);
}
$base_2 =~ s/^0+//;
my $decimal = Math::BigInt->new();
my $power = Math::BigInt->new(2);
$power->bpow(length($base_2) - 1);
for my $pos (0 .. length($base_2) - 1) {
$decimal->badd($power * substr($base_2, $pos, 1));
$power->bdiv(2);
}
return $decimal;
}
I am not sure why the code for handling negative numbers is so weird but it works for everything I tested.
|