使用 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
}
}
}
我们正在使用 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
}
}
}