verenion verenion - 11 months ago 117
PHP Question

Unpacking files from pack() in PHP with C#

We are serialising data using

pack()
in PHP to various files. We now need to deserialise this data using C# (without .NET if it makes any difference).

We are packing the data like this:

pack('iii', $m_id, $f_id, time() )
. Which is resulting in 12 bytes being written to file. Using
unpack( 'lmid/lfid/ltime' , $data);
is working correctly within PHP.

We are attempting to unpack the same data in C#, so far, we have the following:

byte[] bytes = new byte[12];

fs.Read(bytes, 0, 12);

uint mid = BitConverter.ToUInt32(bytes, 0);
uint fid = BitConverter.ToUInt32(bytes, 4);
uint time = BitConverter.ToUInt32(bytes, 8);


We are getting very odd results and we have experimented with different datatypes, reversing the bytes array (big/little endian) and still, the values are not coming out the same as PHP. Has anyone had this issue before, is there something we are missing with the
pack
format?

The file and
bytes
contain

// String.Join(".", bytes.Select(_ => String.Format("{0,2:X2}", _)))
5F.01.00.00.00.00.00.00.35.49.96.46


This should result in

mid = 36945;
fid = 90666;
time = 1493068812;

Answer Source

I don't know how you got that file, but that pack doesn't produce it.

$ echo '<?php echo pack('iii', 36945, 90666, 1493068812) ?>' | php | od -t x1
0000000 51 90 00 00 2a 62 01 00 0c 6c fe 58
0000014

This is what one would expect (from a compiler with 32-bit int on a little-endian machine) because

  • 3694510 = 0000905116
  • 9066610 = 0001622A16
  • 149306881210 = 58FE6C0C16

The problem has nothing to do with C#, but with your PHP code. Your C# code provides the right output for the correct input.

namespace ConsoleApplication
{
    class Program
    {
        static private void DecodeAndDump(byte[] bytes)
        {
            uint mid = BitConverter.ToUInt32(bytes, 0);
            uint fid = BitConverter.ToUInt32(bytes, 4);
            uint time = BitConverter.ToUInt32(bytes, 8);
            Console.WriteLine(String.Format("mid: {0}, fid: {1}, time: {2}", mid, fid, time));
        }

        static void Main(string[] args)
        {
            DecodeAndDump( new byte[] { 0x5F, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x49, 0x96, 0x46 } );
                // mid: 351, fid: 0, time: 1184254261
            DecodeAndDump( new byte[] { 0x51, 0x90, 0x00, 0x00, 0x2A, 0x62, 0x01, 0x00, 0x0C, 0x6C, 0xFE, 0x58 } );
                // mid: 36945, fid: 90666, time: 1493068812
        }
    }
}
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download