Подтвердить что ты не робот

Int в байтовый массив

Я думал, что у .NET есть какой-то простой метод преобразования, который можно использовать для преобразования int в массив байтов? Я сделал быстрый поиск, и все решения бит маскируют/сдвигают один байт за раз, например "хорошие дни". Нет ли метода ToByteArray() где-нибудь?

4b9b3361

Ответ 1

byte[] bytes = BitConverter.GetBytes(i);

хотя обратите внимание также на то, что вы можете проверить BitConverter.IsLittleEndian, чтобы увидеть, какой путь будет отображаться!

Обратите внимание, что если вы делаете это повторно, вы можете избежать всех этих короткоживущих распределений массивов, написав их самостоятельно с помощью операций сдвига (>>/<<) или с помощью кода unsafe. Операции переключения также имеют то преимущество, что они не подвержены влиянию вашей платформы; вы всегда получаете байты в том порядке, в котором вы их ожидаете.

Ответ 2

Ответ Marc - это, конечно, правильный ответ. Но поскольку он упомянул операторы сдвига и небезопасный код в качестве альтернативы. Я хотел бы поделиться менее распространенной альтернативой. Использование структуры с макетом Explicit. В принципе это аналогично C/С++ union.

Вот пример структуры, которая может использоваться для доступа к байтам компонента типа данных Int32, и хорошо, что это два пути, вы можете манипулировать байтовыми значениями и видеть влияние на 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);
    }
  }

Вышеприведенное может быть использовано следующим образом

 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);

Конечно, полиция неизменности может быть не в восторге от последней возможности:)

Ответ 3

Это может быть OT, но если вы сериализуете множество примитивных типов или структур POD, Буферы протокола Google для .Net могут быть полезны для вы. Это относится к проблеме endianness @Marc, поднятой выше, среди других полезных функций.

Ответ 4

Если вы пришли сюда из Google

Альтернативный ответ на старый вопрос относится к библиотеке Джона Скита, в которой есть инструменты, позволяющие записывать примитивные типы данных непосредственно в байт [] со смещением индекса. Намного лучше, чем BitConverter, если вам нужна производительность.

Старые темы обсуждают эту проблему здесь

Библиотеки Джона Скита здесь

Просто скачайте исходный код и посмотрите на пространство имен MiscUtil.Conversion. EndianBitConverter.cs обрабатывает все для вас.

Ответ 5

Большинство ответов здесь либо "UnSafe", либо не LittleEndian safe. BitConverter не является безопасным для LittleEndian. Поэтому, опираясь на пример в здесь (см. Сообщение от PZahra), я сделал безопасную версию LittleEndian просто, читая массив байтов в обратном порядке, когда 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));
}

Он возвращает это:

True
0xDCBAABCDFFFE1608

который является точным шестнадцатеричным, который попал в массив байтов.