Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Incorrect value converting hexadecimal numbers to UInt C# [duplicate]

Tags:

c#

hex

I am trying to read a binary file in C#, but I am facing a problem. I declared the following:

public static readonly UInt32 NUMBER = 0XCAFEBABE;

Then while reading from the very beginning of the file I am asking to read the first 4 bytes (already tried different ways, but this is the simplest):

UInt32 num = in_.ReadUInt32(); // in_ is a BinaryReader

While I have that the 4 bytes are CA, FE, BA and BE (in hex) while convert them to UInt I am getting different values. NUMBER is 3405691582, num is 3199925962. I also tried to do this:

byte[] f2 = {0xCA, 0xFE, 0xBA, 0xBE};

and the result of doing BitConverter.ToUInt32(new byte[]{0xCA, 0xFE, 0xBA, 0xBE},0) is 3199925962.

can anyone help me?

like image 730
pinker Avatar asked Apr 19 '13 10:04

pinker


1 Answers

This is because of the little endianness of your machine. See BitConverter.IsLittleEndian property to check this.

Basically, numbers are stored in reverse byte order, compared to how you would write them down. We write the most significant number on the left, but the (little endian) PC stores the least significant byte on the left. Thus, the result you're getting is really 0xBEBAFECA (3199925962 decimal) and not what you expected.

You can convert using bit shifting operations:

uint value = (f2[0] << 24) | (f2[1] << 16) | (f2[2] << 8) | f2[3];

There are many more ways to convert, including IPAddress.NetworkToHostOrder as I4V pointed out, f2.Reverse(), etc.

For your specific code, I believe this would be most practical:

uint num = (uint)IPAddress.NetworkToHostOrder(in_.ReadInt32());

This may result in an arithmetic underflow however, so it may cause problems with a /checked compiler option or checked keyword (neither are very common).

If you want to deal with these situations and get even cleaner code, wrap it in an extension method:

public static uint ReadUInt32NetworkOrder(this BinaryReader reader)
{
    unchecked
    {
        return (uint)IPAddress.NetworkToHostOrder(reader.ReadInt32());    
    }
}
like image 126
Thorarin Avatar answered Oct 15 '22 18:10

Thorarin