tajinderpalsingh61 has asked for the wisdom of the Perl Monks concerning the following question:

I am trying to replicate some java code in perl. The operation, I need to perform is to convert Java BigInteger to byte array Java Code:
public class Main { public static void main(String[] args) { BigInteger n = new BigInteger("1677259342285725925376"); System.out.println(Arrays.toString(n.toByteArray())); } }
Output: [90, -20, -90, 53, 78, -38, 2, -128, 0]

I need to do similar operation in perl, I am completely new in perl. So, no idea. Thanks in advance.

2019-08-26 Athanasius added code tags around output.

Replies are listed 'Best First'.
Re: How to convert bigint to bytearray in perl
by Athanasius (Archbishop) on Aug 26, 2019 at 06:26 UTC

    Hello tajinderpalsingh61, and welcome to the Monastery!

    To expand on swl’s answer, here is one approach:

    use strict; use warnings; use Data::Dump; use Math::BigInt; my $string = '1677259342285725925376'; my $n = Math::BigInt->new($string); my @bytes = map { ord } split //, $n->to_bytes(); @bytes = map { $_ >= 128 ? $_ - 256 : $_ } @bytes; dd \@bytes;

    Output:

    16:16 >perl 2015_SoPW.pl [90, -20, -90, 53, 78, -38, 2, -128, 0] 16:16 >

    Explanation: Math::BigInt->to_bytes returns a reprsentation of the integer as a byte string. split // splits that string into its component bytes. ord() turns a byte from a character into a number (its numerical representation).

    The useful function map applies the expression in braces to each element of the list it receives, and returns the resulting new list; so I’ve used it twice, once to convert byte characters into their numerical representations, and again to convert those numbers above 127 into their corresponding signed 8-bit integers.

    For the ?: ternary operator, see Conditional Operator. And Data::Dump is a useful CPAN module for displaying complex data structures.

    Hope that helps,

    Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

      That's not equivalent. It fails for negative numbers, as well as positive numbers that requires a multiple of 8 bits to represent (e.g. 128-255, and 32678-65535).

      The following addresses the second of the above limitations:

      sub bigint_to_bytearray { my $bigint = shift; die "Negative numbers not supported" if $bigint < 0; my @bytes = unpack('c*', $bigint->to_bytes); unshift @bytes, 0x00 if $bytes[0] < 0; # Add sign bit if necessary return @bytes; }

      The above requires a relatively new version of Math::BigInt. The following is less efficient, but it works on far older versions:

      sub bigint_to_bytearray { my $bigint = shift; die "Negative numbers not supported" if $bigint < 0; my @bytes = unpack('c*', pack('H*', substr($bigint->as_hex, 2))); unshift @bytes, 0x00 if $bytes[0] < 0; # Add sign bit if necessary return @bytes; }
        Thanks, You saved my day, How can I accept your answer?
      Thanks for your help, tried your code, unfortunately, i am getting below error.

      Can't locate object method "to_bytes" via package "Math::BigInt"

        Can't locate object method "to_bytes" via package "Math::BigInt"

        The to_bytes method was added in Math::BigInt 1.999807, which was distributed with Perl 5.28. You should be able to install the latest version from CPAN.

Re: How to convert bigint to bytearray in perl
by swl (Prior) on Aug 26, 2019 at 06:11 UTC

    See the Math::BigInt documentation

    Update: Hopefully someone else can describe how to extract the values.