使用 C# 从 PHP 中的 pack() 解压文件

Unpacking files from pack() in PHP with C#

我们正在使用 PHP 中的 pack() 将数据序列化到各种文件中。我们现在需要使用 C# 反序列化此数据(如果有任何不同,则不使用 .NET)。

我们正在这样打包数据:

pack('iii', $m_id, $f_id, time() )。这导致 12 个字节被写入文件。使用 unpack( 'lmid/lfid/ltime' , $data); 在 PHP.

中正常工作

我们正在尝试用 C# 解压相同的数据,到目前为止,我们有以下内容:

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);

我们得到了非常奇怪的结果,我们已经尝试了不同的数据类型,颠倒字节数组(big/little 字节序),但结果仍然与 PHP 不同。以前有没有人遇到过这个问题,pack 格式是否遗漏了什么?

文件和bytes包含

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

这应该导致

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

我不知道你是怎么得到那个文件的,但那个包不会产生它。

$ 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

这是人们所期望的(来自在小端机器上具有 32 位 int 的编译器)因为

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

问题与 C# 无关,而是与您的 PHP 代码有关。您的 C# 代码为正确的输入提供正确的输出。

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
        }
    }
}