Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change

Re: Understanding Unpack on Decimal Value

by choroba (Cardinal)
on Nov 01, 2018 at 21:05 UTC ( [id://1225074]=note: print w/replies, xml ) Need Help??

in reply to Understanding Unpack on Decimal Value

First, check pack:

> V An unsigned long (32-bit) in "VAX" (little-endian) order.

Have you noticed the pattern?

bytes chars 36353935 ----> 36 35 39 35 ----> 6 5 9 5 | | | | first 4 digits reverse | | | | 595661 -------------> 5956 ------> 6 5 9 5

It works for any input greater or equal to 1000:

#! /usr/bin/perl use warnings; use strict; use Test::More; sub what { my ($input) = @_; my $unpacked = unpack "V", $input; my $result = join "", map chr hex, sprintf("%x\n", $unpacked) =~ / +(..)/g; is $result, reverse substr $input, 0, 4; } what($_) for 1000 .. 2000, 2e4, 3e5, 4e6, 5e7, 6e8, 7e9, 8e10, 9e11, 2 ** 64 - 3; done_testing();

Update: For numbers fitting into integer, you can also use

reverse($input) % 10_000

($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: Understanding Unpack on Decimal Value
by arblargan (Acolyte) on Nov 01, 2018 at 21:27 UTC

    ASCII!! That didn't even occur to me as this portion of the function is entirely numeric. I suspect that the way this was implemented in the original script was incorrectly understood. Thank you for the clarification. One additional question, if I could...

    Since it returns only a portion of the result, I attempted to modify the snippet a little bit, but it still produced the same result. See below.

    my $input = 0x916CD; #595661 my @unpacked = unpack "VV", $input; print(join ", ", @unpacked); >>909457717 #0x36353935

    From your reply, I was expecting to have the following.

    Dec: 825_636_405, 14_645 Hex: 0x31363635, 0x3935

    Could you help me understand why this doesn't unpack into the array like I thought it would? Thanks for the help!

      You need a number greater than 9_999_999 to get more than one element back:
      for my $input (9_999_990 .. 10_000_010) { my @unpacked = unpack 'VV', $input; say scalar @unpacked, " $input"; }
      ($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,

Log In?

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

How do I use this?Last hourOther CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (1)
As of 2024-04-15 21:44 GMT
Find Nodes?
    Voting Booth?

    No recent polls found