http://www.perlmonks.org?node_id=1192869


in reply to Signed Long Hash

Math::BigInt is for arbitrary precision, it doesn't understand boundaries like "signed long".

If your Perl can handle quads in pack, you should be able to just use them, no bigint needed:

#!/usr/bin/perl use warnings; use strict; use feature qw{ say }; my $hash = '18165163011005162717'; my $signed = unpack 'q', pack 'Q', $hash; # Using 'q' woudl work, too +. say $signed eq "-281581062704388899";
($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,

Replies are listed 'Best First'.
Re^2: Signed Long Hash
by breezykatt (Acolyte) on Jun 15, 2017 at 17:25 UTC
    One follow up question - how does one convert a numeric value (eg -281581062704388899) to base64 in perl similar to java's call:

    Base64.getEncoder().withoutPadding().encodeToString(Longs.toByteArray(val));

    to get the java base64 encoded string: '/Befg+4HJN0'

      See MIME::Base64 and perhaps pack.

      Update: Although I do not receive the same result - are you sure about the input and output?

      use strict; use warnings; use MIME::Base64 'encode_base64'; use Test::More tests => 1; is (encode_base64((pack 'q', -281581062704388899), ''), '/Befg+4HJN0') +;

      gives '3SQH7oOfF/w=' instead.

        Thanks. What I was trying to do was something similar, but this might not yield the same results to what i'm trying to achieve? I thought I had to convert the value to an array of bytes first and then convert that to base64. Something like:

        $signed="-281581062704388899"; $bits = unpack("B*", pack("N", $signed)); $base64 = encode_base64(pack("B*", $bits), ""); #or $base64 = encode_base64($bits);
Re^2: Signed Long Hash
by Laurent_R (Canon) on Jun 15, 2017 at 16:21 UTC
    Update: Sorry, posted in the wrong place, this was supposed to be an answer to the OP (see below)
Re^2: Signed Long Hash
by breezykatt (Acolyte) on Jun 15, 2017 at 16:50 UTC
    thanks!