简体   繁体   中英

What is the C# equivalent of the PHP Pack() function?

I have a line of PHP code that does the following:

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

What this appears to do is prepend a binary string of the length of $xml (plus 4) to the value of $xml .

How do I do the equivalent of this in C#?

It looks like your request requires a length prefixed string made up of single byte characters, so it's gonna need a bit more work in C# which uses Unicode characters. I'm going to assume you want your string of XML encoded with UTF-8. We also won't be able to use a string to hold the request when its been put together, instead we'll use a byte array.

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

The other thing to notice here is that the php pack() function with the 'N' parameter forces big-endian on your leading 4 bytes. I therefore wrote the ToBigEndian() method to handle conversion into big-endian on any platform.

System.IO.BinaryWriter would appear to be a closer match.

I'm not a PHP guru (haven't used it in years), but the following is probably pretty close in functionality:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM