【问题标题】:Python's pack/unpack in .NetPython 在 .Net 中的打包/解包
【发布时间】:2021-01-29 02:02:37
【问题描述】:

在 C# 中是否有任何与 Python 的 struct.pack 和 strike.unpack 等效的函数可以让我像这样打包和解包值?

【问题讨论】:

  • 你能用你自己的话解释一下这些方法实际上是做什么的,在什么数据结构或类型上,例如输入输出。你打算如何使用它,什么不适合你,你有什么问题?
  • 请不要发布代码图片,而是将代码粘贴到您的问题中。

标签: python c# byte converters


【解决方案1】:

查看struct图书馆。

有一个类似于你在图片中发布的解包方法

 struct.pack(format, v1, v2, ...)

    Return a bytes object containing the values v1, v2, … packed according to the format string format. The arguments must match the values required by the format exactly

【讨论】:

    【解决方案2】:

    不,没有。您必须手动使用BinaryWriterMemoryStreamBitConverter 或新的BinaryPrimitives 加上Span<> 可能由byte[] 支持(但它更复杂...在开始写入之前,您必须知道缓冲区的最终宽度,而 MemoryStream 是自动放大的)。

    更糟糕的是:使用 .NET 使用多类型数组(每个元素都可以是任何类型的数组)就像 unpack 返回的那样有点令人不悦,而且性能低下。你必须使用object[],所以你会装箱每个元素。

    现在...手动“序列化”为二进制非常容易(即使比 Python 长得多):

    byte command_type = 1;
    byte command_class = 5;
    byte command_code = 0x14;
    int arg0 = 0;
    int arg1 = 0;
    
    // We know the message plus the checksum has length 12
    var packedMessage2 = new byte[12];
    
    // We use the new Span feature
    var span = new Span<byte>(packedMessage2);
    
    // We can directly set the single bytes
    span[0] = command_type;
    span[1] = command_class;
    span[2] = command_code;
    
    // The pack is <, so little endian. Note the use of Slice: first the position (3 or 7), then the length of the data (4 for int)
    BinaryPrimitives.WriteInt32LittleEndian(span.Slice(3, 4), arg0);
    BinaryPrimitives.WriteInt32LittleEndian(span.Slice(7, 4), arg1);
    
    // The checksum
    // The sum is modulo 255, because it is a single byte.
    // the unchecked is normally useless because it is standard in C#, but we write it to make it clear
    var sum = unchecked((byte)packedMessage2.Take(11).Sum(x => x));
    
    // We set the sum
    span[11] = sum;
    
    // Without checksum
    Console.WriteLine(string.Concat(packedMessage2.Take(11).Select(x => $@"\x{x:x2}")));
    
    // With checksum
    Console.WriteLine(string.Concat(packedMessage2.Select(x => $@"\x{x:x2}")));
    

    【讨论】:

    • 兄弟!非常感谢您的帮助。
    猜你喜欢
    • 2015-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-14
    • 2017-10-17
    • 1970-01-01
    • 1970-01-01
    • 2018-02-13
    相关资源
    最近更新 更多