C # - Преобразование uint в байт [] - PullRequest
10 голосов
/ 03 августа 2010

Так что я использовал BitConverter.GetBytes () для преобразования uint32 в byte [], но мой порядок в массиве, похоже, обратный.http://msdn.microsoft.com/en-us/library/1184xdy4.aspx (показывает, что это byte [], кажется, с прямым порядком байтов).

Есть ли лучший способ справиться с этим, чем просто использовать linq для обращения байтовых массивов?

Ответы [ 5 ]

5 голосов
/ 03 августа 2010

Если вы собираетесь перемещаться между архитектурами платформ, простое изменение массива может быть правильным на одной платформе, но не на той платформе, которая уже использует big endian.

Вы используете функции IPAddress.HostToNetworkOrder , которые гарантируют, что данные всегда будут в сетевом порядке (порядковый номер).

uint number = 234234233;
uint bigEndian = (uint)IPAddress.HostToNetworkOrder((int)number);
byte[] b = BitConverter.GetBytes(bigEndian);
5 голосов
/ 03 августа 2010

Array.Reverse для изменения порядка байтов.

4 голосов
/ 03 августа 2010

Microsoft обсуждает проблему с прямым и прямым порядком байтов с помощью метода GetBytes () на странице документации для BitConverter .

2 голосов
/ 05 августа 2010

Итак, я выяснил, что большая часть моей путаницы связана с этим: Поле IsLittleEndian сообщает о ложном значении, но оно должно быть Little-Endian?

В итоге я обернул все вызовы BitConverter вызовом, который принял дополнительный параметр для указания порядка байтов, затем добавил функцию, которая вызывается для проверки необходимости почитать байты.

public static class BitEndianConverter
{
    public static byte[] GetBytes(bool value, bool littleEndian)
    {
        return ReverseAsNeeded(BitConverter.GetBytes(value), littleEndian);
    }

    public static byte[] GetBytes(char value, bool littleEndian)
    {
        return ReverseAsNeeded(BitConverter.GetBytes(value), littleEndian);
    }
    public static byte[] GetBytes(double value, bool littleEndian)
    {
        return ReverseAsNeeded(BitConverter.GetBytes(value), littleEndian);
    }
    public static byte[] GetBytes(float value, bool littleEndian)
    {
        return ReverseAsNeeded(BitConverter.GetBytes(value), littleEndian);
    }
    public static byte[] GetBytes(int value, bool littleEndian)
    {
        return ReverseAsNeeded(BitConverter.GetBytes(value), littleEndian);
    }
    public static byte[] GetBytes(long value, bool littleEndian)
    {
        return ReverseAsNeeded(BitConverter.GetBytes(value), littleEndian);
    }
    public static byte[] GetBytes(short value, bool littleEndian)
    {
        return ReverseAsNeeded(BitConverter.GetBytes(value), littleEndian);
    }
    public static byte[] GetBytes(uint value, bool littleEndian)
    {
        return ReverseAsNeeded(BitConverter.GetBytes(value), littleEndian);
    }
    public static byte[] GetBytes(ulong value, bool littleEndian)
    {
        return ReverseAsNeeded(BitConverter.GetBytes(value), littleEndian);
    }
    public static byte[] GetBytes(ushort value, bool littleEndian)
    {
        return ReverseAsNeeded(BitConverter.GetBytes(value), littleEndian);
    }

    private static byte[] ReverseAsNeeded(byte[] bytes, bool wantsLittleEndian)
    {
        if (wantsLittleEndian == BitConverter.IsLittleEndian)
            return bytes;
        else
            return (byte[])bytes.Reverse().ToArray();
    }
}
1 голос
/ 07 сентября 2013

Ниже приведен метод для быстрого получения массива байтов с прямым порядком байтов.

    public static byte[] GetBigEndianBytes(UInt32 val, bool isLittleEndian)
    {
        UInt32 bigEndian = val;
        if (isLittleEndian)
        {
            bigEndian = (val & 0x000000FFU) << 24 | (val & 0x0000FF00U) << 8 |
                 (val & 0x00FF0000U) >> 8 | (val & 0xFF000000U) >> 24;
        }
        return BitConverter.GetBytes(bigEndian);
    }

Эта перегрузка может быть полезной, хотя следует соблюдать осторожность при работе на машинах с разными порядковыми номерами .

    public static byte[] GetBigEndianBytes(UInt32 val)
    {
        return GetBigEndianBytes(val, BitConverter.IsLittleEndian);
    }
...