什么是PHP Pack()函数的C#等价物?

时间:2009-10-30 01:01:15

标签: c# php

我有一行PHP代码可以执行以下操作:

$xml = "<xml><request>...[snipped for brevity]...</request></xml>";
$request = pack('N', (strlen($xml)+4)).$xml;

这似乎是将$xml(加4)长度的二进制字符串添加到$xml的值。

如何在C#中完成相同的操作?

2 个答案:

答案 0 :(得分:1)

System.IO.BinaryWriter似乎更接近匹配。

我不是PHP大师(多年来没有使用它),但以下功能可能非常接近:

using System.IO;
using System.Text;

string xml = "the original data to pack";
using (MemoryStream ms = new MemoryStream())
{
  using (BinaryWriter bw = new BinaryWriter(ms))
  {
    byte[] data = Encodings.ASCII.GetBytes(xml);
    bw.Write((Int32)data.Length + 4); // Size of ASCII string + length (4 byte int)
    bw.Write(data);
  }

  request = ms.ToArray();
}

答案 1 :(得分:1)

看起来您的请求需要一个由单字节字符组成的长度前缀字符串,因此在C#中需要使用Unicode字符的更多工作。我假设你想要用UTF-8编码的XML字符串。我们也将无法使用字符串来保存请求,而是使用字节数组。

using System;
using System.IO;
using System.Text;

class Program
{
    static void
    Main(string[] args)
    {
        string xml = "<xml><request>...[snipped for brevity]...</request></xml>";
        using ( MemoryStream stream = new MemoryStream() )
        {
            using ( BinaryWriter writer = new BinaryWriter(stream) )
            {
                byte [] encodedXml = Encoding.UTF8.GetBytes(xml);
                writer.Write(ToBigEndian(encodedXml.Length + 4));
                writer.Write(encodedXml);
            }

            byte [] request = stream.ToArray();

            //  now use request however you like
        }
    }

    static byte []
    ToBigEndian(int value)
    {
        byte [] retval = BitConverter.GetBytes(value);
        if ( BitConverter.IsLittleEndian )
        {
            Array.Reverse(retval);
        }
        return retval;
    }
}

另一件需要注意的是,带有'N'参数的php pack()函数会强制你的前4个字节使用big-endian。因此,我编写了ToBigEndian()方法来处理在任何平台上转换为big-endian。