Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

Re^2: Equivalent of unpack 'q' with 32-bit Perl (a8)

by Limbic~Region (Chancellor)
on Sep 06, 2016 at 20:49 UTC ( [id://1171268]=note: print w/replies, xml ) Need Help??


in reply to Re: Equivalent of unpack 'q' with 32-bit Perl (a8)
in thread Equivalent of unpack 'q' with 32-bit Perl

Anonymous Monk,

Get the bits only?

Presumably you mean take the first 8 bytes and then convert them to an integer by extracting the individual bits and then doing base conversion.

If that's not what you mean, please enlighten me. If that is what you mean, I would need to play with it because I don't think the b/B templates would be helpful, I think it would need vec

Cheers - L~R

Replies are listed 'Best First'.
Re^3: Equivalent of unpack 'q' with 32-bit Perl (a8)
by Anonymous Monk on Sep 06, 2016 at 22:36 UTC

    No, I mean dont do any conversion if its not possible :) treat it as a string, convert as quad when you can, otherwise its raw bytes ...

    There is always bigint which says

    print hex("0x1234567890123490"),"\n"; # Perl v5.10.0 or later

    So

    use constant CAN_PACK_QUADS => !! eval { my $f = pack 'q'; 1 }; use Math::BigInt; print quad('ffffffffffff'), "\n"; sub quad { CAN_PACK_QUADS ? unpack( 'q<', $_[0] ) : Math::BigInt->new( '0x'.$_[0] ) } __END__
      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.

      Cheers - L~R

        well, shouldn't need to involve vec at all, just use md5_hex to get hex version of digest ... you could unpack 'H*' ... and give that to bigint hex ...

        also negatives, yeah I've no idea :)

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1171268]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others studying the Monastery: (5)
As of 2024-03-28 16:53 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found