Int to byte array

断了今生、忘了曾经 提交于 2019-11-29 02:47:37
byte[] bytes = BitConverter.GetBytes(i);

although note also that you might want to check BitConverter.IsLittleEndian to see which way around that is going to appear!

Note that if you are doing this repeatedly you might want to avoid all those short-lived array allocations by writing it yourself via either shift operations (>> / <<), or by using unsafe code. Shift operations also have the advantage that they aren't affected by your platform's endianness; you always get the bytes in the order you expect them.

Marc's answer is of course the right answer. But since he mentioned the shift operators and unsafe code as an alternative. I would like to share a less common alternative. Using a struct with Explicit layout. This is similar in principal to a C/C++ union.

Here is an example of a struct that can be used to get to the component bytes of the Int32 data type and the nice thing is that it is two way, you can manipulate the byte values and see the effect on the Int.

  using System.Runtime.InteropServices;

  [StructLayout(LayoutKind.Explicit)]
  struct Int32Converter
  {
    [FieldOffset(0)] public int Value;
    [FieldOffset(0)] public byte Byte1;
    [FieldOffset(1)] public byte Byte2;
    [FieldOffset(2)] public byte Byte3;
    [FieldOffset(3)] public byte Byte4;

    public Int32Converter(int value)
    {
      Byte1 = Byte2 = Byte3 = Byte4 = 0;
      Value = value;
    }

    public static implicit operator Int32(Int32Converter value)
    {
      return value.Value;
    }

    public static implicit operator Int32Converter(int value)
    {
      return new Int32Converter(value);
    }
  }

The above can now be used as follows

 Int32Converter i32 = 256;
 Console.WriteLine(i32.Byte1);
 Console.WriteLine(i32.Byte2);
 Console.WriteLine(i32.Byte3);
 Console.WriteLine(i32.Byte4);

 i32.Byte2 = 2;
 Console.WriteLine(i32.Value);

Of course the immutability police may not be excited about the last possiblity :)

This may be OT but if you are serializing a lot of primitive types or POD structures, Google Protocol Buffers for .Net might be useful to you. This addresses the endianness issue @Marc raised above, among other useful features.

If you came here from Google

Alternative answer to an older question refers to John Skeet's Library that has tools for letting you write primitive data types directly into a byte[] with an Index offset. Far better than BitConverter if you need performance.

Older thread discussing this issue here

John Skeet's Libraries are here

Just download the source and look at the MiscUtil.Conversion namespace. EndianBitConverter.cs handles everything for you.

I'm guessing Microsoft hasn't implemented this because the .NET framework is DeFacto Safe code. But it seems ridiculous that thousands of people are having to do bit-shifting or go to a 3rd party library to get such a basic need met.

Most of the answers here are either 'UnSafe" or not LittleEndian safe. BitConverter is not LittleEndian safe. So building on an example in here (see the post by PZahra) I made a LittleEndian safe version simply by reading the byte array in reverse when BitConverter.IsLittleEndian == true

void Main(){    
    Console.WriteLine(BitConverter.IsLittleEndian); 
    byte[] bytes = BitConverter.GetBytes(0xdcbaabcdfffe1608);
    //Console.WriteLine(bytes); 
    string hexStr = ByteArrayToHex(bytes);
    Console.WriteLine(hexStr);
}

public static string ByteArrayToHex(byte[] data) 
{ 
   char[] c = new char[data.Length * 2]; 
   byte b; 
  if(BitConverter.IsLittleEndian)
  {
        //read the byte array in reverse
        for (int y = data.Length -1, x = 0; y >= 0; --y, ++x) 
        { 
            b = ((byte)(data[y] >> 4)); 
            c[x] = (char)(b > 9 ? b + 0x37 : b + 0x30); 
            b = ((byte)(data[y] & 0xF)); 
            c[++x] = (char)(b > 9 ? b + 0x37 : b + 0x30); 
        }               
    }
    else
    {
        for (int y = 0, x = 0; y < data.Length; ++y, ++x) 
        { 
            b = ((byte)(data[y] >> 4)); 
            c[x] = (char)(b > 9 ? b + 0x37 : b + 0x30); 
            b = ((byte)(data[y] & 0xF)); 
            c[++x] = (char)(b > 9 ? b + 0x37 : b + 0x30); 
        }
    }
    return String.Concat("0x",new string(c));
}

It returns this:

True
0xDCBAABCDFFFE1608

which is the exact hex that went into the byte array.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!