in reply to Perl equivalent of Java code

You can use unpack. But unless you're already a pack/unpack wizard, it will take you about 10 times longer to figure out the magical unpack formula than, for example, the following simple solution:

my $key = "0123456789ABCDEF0123456789ABCDEF"; my @b = map { chr hex $_ } $key =~ /(..)/g;
We're building the house of the future together.

Replies are listed 'Best First'.
Re^2: Perl equivalent of Java code
by ikegami (Patriarch) on Jan 19, 2006 at 17:01 UTC

    Not quite. There are three bugs in your code:

    • Incorrect results are returned when the most significant bit is set. A sign bit should be added, adding an extra byte. *
      "FFFF" should return ("\x00", "\xFF", "\xFF").

    • Incorrect results are returned when there are leading zeroes.
      "000102" should return ("\x01", "\x02").

    • Incorrect results are returned when an odd number of hex digits are provided.
      "102" should return ("\x01", "\x02").

    Relevant docs:
    java.Math.BigInteger.BigInteger(java.lang.String, int)
    java.Math.BigInteger.toByteArray()
    java.Math.BigInteger.bitLength()

    Fixed code:

    my $key = "0123456789ABCDEF0123456789ABCDEF"; local $_ = $key; s/^0+//; $_ = "0$_" if length % 2 == 1; $_ = "00$_" if /^[89ABCDEFabcdef]/; my @b = map { chr hex $_ } /(..)/g;

    * – I'm assuming new BigInteger("FFFF", 16) is considered to be 65535 (not -1).

      Thanks for the reply
      , Please let me know what I should read to get familiar with these ( I do not have much computer background ).
      when i print the java output (each element of the array) I get the following result ..

      1 35 69 103 -119 -85 -51 -17 1 35 69 103 -119 -85 -51 -17


      The perl one gives this output

      1 35 69 103 137 171 205 239 1 35 69 103 137 171 205 239

        Apparently, bytes as considered signed in Java. No problem.

        I could fix the map, but it's getting quite long. It's easier to just use pack and unpack.

        my $key = "0123456789ABCDEF0123456789ABCDEF"; local $_ = $key; s/^0+//; $_ = "0$_" if length % 2 == 1; $_ = "00$_" if /^[89ABCDEFabcdef]/; my @b = unpack('c*', pack('H*', $_));
        Could you do me a favour and test to make sure it works for "FFFF", "000102" and "102"?