Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

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

by Anonymous Monk
on Sep 06, 2016 at 20:23 UTC ( [id://1171267]=note: print w/replies, xml ) Need Help??


in reply to Equivalent of unpack 'q' with 32-bit Perl

Get the bits only?

use constant CAN_PACK_QUADS => !! eval { my $f = pack 'q'; 1 }; sub Int64 { unpack( ( CAN_PACK_QUADS ? 'q<' : 'a8' ), $_[-1] ) } sub UInt64 { unpack( ( CAN_PACK_QUADS ? 'Q<' : 'a8' ), $_[-1] ) }

Replies are listed 'Best First'.
Re^2: Equivalent of unpack 'q' with 32-bit Perl (a8)
by Limbic~Region (Chancellor) on Sep 06, 2016 at 20:49 UTC
    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

      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

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others meditating upon the Monastery: (4)
As of 2024-04-19 14:58 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found