3

I am trying to reproduce a sequence of code from a Python program in C#. In Python I have:

element1, element2 = struct.unpack('!hh', data[2:6])

The above statement unpacks from a "substring" of data in short-short (network byte order) format. The values resulted (element1,element2) are: 96 and 16

My attempt in C# is:

byte[] bytesOfInterval = ASCIIEncoding.ASCII.GetBytes (data.Substring (2, 4));
using (MemoryStream stream = new MemoryStream(bytesOfInterval)) {
    using (BinaryReader reader = new BinaryReader(stream)) {
        Logger.Trace (reader.ReadInt16().ToString());
        Logger.Trace (reader.ReadInt16().ToString());
    }
}

It outputs: 24576 and 4096 .

As you can see the output from the Python program is slightly different from the C# one. To verify the "substrings" (input), I've encoded them in hex format to see if there is any difference. They were both equal to 00600010, hence, the input is the same the output is different. Why?

Notes:

Gabe
  • 961
  • 1
  • 10
  • 23

1 Answers1

2

I think it is an endianness problem try this for example

Int16 x1 = 4096;  
var x2 = IPAddress.HostToNetworkOrder(x1);

x2 will be 16 (same for 24576 => 96)

So you can use IPAddress.HostToNetworkOrder method.

L.B
  • 114,136
  • 19
  • 178
  • 224
  • Don't use `HostToNetworkOrder` for general-purpose endian-swapping, especially for doing the opposite of what it says (converting network order to host order)… That's what [`BitConverter`](http://msdn.microsoft.com/en-us/library/system.bitconverter(v=vs.110).aspx) is for. See the linked docs for sample code. – abarnert Dec 24 '13 at 19:53
  • Or just see [this question](http://stackoverflow.com/questions/8620885/c-sharp-binary-reader-in-big-endian) for how to wrap it all up nicely. (I'd prefer to pass the endianness to the constructor, and swap if it's `!= BitConverter.IsLittleEndian`, rather than always swapping in one class and never in another… but it's good sample code.) – abarnert Dec 24 '13 at 19:53