struct.pack采用一种格式,后跟一系列将根据格式打包的值。在您的问题中,您致电:
struct.pack('<l', len(message))+struct.pack('<l',0)+message
这就是说“将此消息的长度打包为 little-endian long,然后将零打包为 little-endian long,然后附加我的其余消息”。
当您在 C# 中处理此类问题时,很遗憾我们没有 struct.pack 的直接端口。您最接近的等价物是使用BitConverter进行一次性转换,例如:
BitConverter.GetBytes((long)message.length) + BitConverter.GetBytes(0l) + message
或使用BinaryWriter进入MemoryStream。这带来了另一个问题,即您无法使用这些工具控制字节序。他们公开了“IsLittleEndian”,因此您知道他们的行为方式,但您无法更改它。
然而,Jon Skeet 就是这样 - 他的MiscUtils库包含一个可以使用的 LittleEndianBitConverter (MiscUtil.Conversion.LittleEndianBitConverter) 或一个 EndianBinaryWriter,如果您使用 Writer/MemoryStream 路线。所以把它们放在一起,参考 MiscUtil 库并使用类似的东西:
var bytes = new List<byte[]>(new[]
{
LittleEndianBitConverter.GetBytes(message.LongLength),
LittleEndianBitConverter.GetBytes(0l),
message
});
var msg = new byte[bytes.Sum(barray => barray.LongLength)];
int offset = 0;
foreach (var bArray in bytes)
{
System.Buffer.BlockCopy(bArray, 0, msg, offset, bArray.Length);
offset = bArray.Length;
}
该代码未经测试,但应该为您提供一个合理的起点。假设您的消息已经是一个字节数组,并且 msg 是您要返回的数组。我们使用 System.Buffer.BlockCopy,因为它是原始类型最有效的复制方法。
* 编辑*
我以问题中的示例为例,并在IDEOne中为Python 代码及其在 C# 中的等价物模拟了一个快速脚本。这里的关键是Struct.Pack('<l', 0)
调用忽略了字节并且没有将它添加到输出中,这可能是让你绊倒的原因。这导致输出过长 8 个字节。
这些脚本应该为您指明正确的方向。如果您仍然遇到问题,您可以发布您尝试过的代码。
作为参考,Python中的完成代码:
import struct
message = b'message "Render"'
msg = struct.pack('<l',len(message)) + struct.pack('<l',0) + message
print(":".join("{0:x}".format(ord(c)) for c in msg))
在 C# 中:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MiscUtil.Conversion;
public class Test
{
public static void Main()
{
var message = Encoding.ASCII.GetBytes("message \"Render\"");
var lenc = new LittleEndianBitConverter();
var bytes = new List<byte[]>(new[]
{
lenc.GetBytes(message.LongLength),
message
});
var msg = new byte[bytes.Sum(barray => barray.LongLength)];
int offset = 0;
foreach (var bArray in bytes)
{
Buffer.BlockCopy(bArray, 0, msg, offset, bArray.Length);
offset = bArray.Length;
}
Console.WriteLine(BitConverter.ToString(msg).Replace("-", ":"));
}
}