当前位置: 动力学知识库 > 问答 > 编程问答 >

python - Using unpack() to convert to a byte array in PHP

问题描述:

I'm trying to convert a binary string to a byte array of a specific format.

Sample binary data:

ê≤ÚEZêK

The hex version of the binary string looks like this:

00151b000000000190b2f20304455a000003900000004b0000

The Python script uses struct package and unpacks the above string (in binary) using this code:

data = unpack(">hBiiiiih",binarydata)

The desired byte array looks like this. This is also the output of the data array is:

(21, 27, 0, 26260210, 50611546, 912, 75, 0)

How can I unpack the same binary string using PHP's unpack() function and get the same output? That is, what's the >hBiiiiih equivalent in PHP?

So far my PHP code

$hex = "00151b000000000190b2f20304455a000003900000004b0000";

$bin = pack("H*",$hex);

print_r(unpack("x/c*"));

Which gives:

Array ( [*1] => 21 [*2] => 27 [*3] => 0 [*4] => 0 [*5] => 0 [*6] => 0 [*7] => 1 [*8] => -112 [*9] => -78 [*10] => -14 [*11] => 3 [*12] => 4 [*13] => 69 [*14] => 90 [*15] => 0 [*16] => 0 [*17] => 3 [*18] => -112 [*19] => 0 [*20] => 0 [*21] => 0 [*22] => 75 [*23] => 0 [*24] => 0 )

Would also appreciate links to a PHP tutorial on working with pack/unpack.

网友答案:

This produces the same result as does Python, but it treats signed values as unsigned because unpack() does not have format codes for signed values with endianness. Also note that the integers are converted using long, but this is OK because both have the same size.

$hex = "00151b000000000190b2f20304455a000003900000004b0000";
$bin = pack("H*", $hex);
$x = unpack("nbe_unsigned_1/Cunsigned_char/N5be_unsigned_long/nbe_unsigned_2", $bin);

print_r($x);
Array
(
    [be_unsigned_1] => 21
    [unsigned_char] => 27
    [be_unsigned_long1] => 0
    [be_unsigned_long2] => 26260210
    [be_unsigned_long3] => 50611546
    [be_unsigned_long4] => 912
    [be_unsigned_long5] => 75
    [be_unsigned_2] => 0
)

Because this data is treated as unsigned, you will need to detect whether the original data was negative, which can be done for 2 byte shorts with something similar to this:

if $x["be_unsigned_1"] >= pow(2, 15)
    $x["be_unsigned_1"] = $x["be_unsigned_1"] - pow(2, 16);

and for longs using

if $x["be_unsigned_long2"] >= pow(2, 31)
    $x["be_unsigned_long2"] = $x["be_unsigned_long2"] - pow(2, 32);
分享给朋友:
您可能感兴趣的文章:
随机阅读: