Порядок следования байтов в различных системах и протоколах

  • Михаил
  • 8 мин. на прочтение
  • 59
  • 10 Jun 2025
  • 10 Jun 2025

Давайте рассмотрим четыре метода преобразования массива байтов, используя порядок следования ABCD для каждого из представлений: big-endian, little-endian, big-endian swapped и little-endian swapped.

1. Big-Endian (ABCD)
В big-endian порядке байты следуют в естественном порядке от старшего к младшему:

Порядок: A B C D
Пример: Если у нас есть 4 байта: 0x12, 0x34, 0x56, 0x78, то в big-endian они остаются в том же порядке.


2. Little-Endian (DCBA)
В little-endian порядке байты следуют в обратном порядке от младшего к старшему:

Порядок: D C B A
Пример: Для тех же 4 байт: 0x12, 0x34, 0x56, 0x78, little-endian порядок будет: 0x78, 0x56, 0x34, 0x12.


3. Big-Endian Swapped (BADC)
В big-endian swapped порядке байты меняются местами попарно:

Порядок: B A D C
Пример: Для тех же 4 байт: 0x12, 0x34, 0x56, 0x78, big-endian swapped порядок будет: 0x34, 0x12, 0x78, 0x56.


4. Little-Endian Swapped (CDAB)
В little-endian swapped порядке байты также меняются местами попарно, но начиная с конца:

Порядок: C D A B
Пример: Для тех же 4 байт: 0x12, 0x34, 0x56, 0x78, little-endian swapped порядок будет: 0x56, 0x78, 0x12, 0x34.


Теперь, используя эти порядки, можно написать методы для преобразования массива байтов в C#:

using System;
public static class ByteArrayConverter
{
   public static byte[] ToBigEndian(byte[] byteArray)
   {
       // Просто возвращаем массив, так как он уже в big-endian
       return (byte[])byteArray.Clone();
   }
   public static byte[] ToLittleEndian(byte[] byteArray)
   {
       // Преобразование в little-endian
       byte[] result = new byte[byteArray.Length];
       Array.Copy(byteArray, result, byteArray.Length);
       Array.Reverse(result);
       return result;
   }
   public static byte[] ToBigEndianSwapped(byte[] byteArray)
   {
       // Преобразование в big-endian swapped
       byte[] result = new byte[byteArray.Length];
       for (int i = 0; i < byteArray.Length; i += 2)
       {
           if (i + 1 < byteArray.Length)
           {
               result[i] = byteArray[i + 1];
               result[i + 1] = byteArray[i];
           }
           else
           {
               result[i] = byteArray[i];
           }
       }
       return result;
   }
   public static byte[] ToLittleEndianSwapped(byte[] byteArray)
   {
       // Преобразование в little-endian swapped
       byte[] result = new byte[byteArray.Length];
       for (int i = 0; i < byteArray.Length; i += 2)
       {
           if (i + 1 < byteArray.Length)
           {
               result[i] = byteArray[i + 1];
               result[i + 1] = byteArray[i];
           }
           else
           {
               result[i] = byteArray[i];
           }
       }
       Array.Reverse(result);
       return result;
   }
}
public class Program
{
   public static void Main()
   {
       byte[] byteArray = { 0x12, 0x34, 0x56, 0x78 };
       byte[] bigEndian = ByteArrayConverter.ToBigEndian(byteArray);
       byte[] littleEndian = ByteArrayConverter.ToLittleEndian(byteArray);
       byte[] bigEndianSwapped = ByteArrayConverter.ToBigEndianSwapped(byteArray);
       byte[] littleEndianSwapped = ByteArrayConverter.ToLittleEndianSwapped(byteArray);
       Console.WriteLine("Big Endian: " + BitConverter.ToString(bigEndian));
       Console.WriteLine("Little Endian: " + BitConverter.ToString(littleEndian));
       Console.WriteLine("Big Endian Swapped: " + BitConverter.ToString(bigEndianSwapped));
       Console.WriteLine("Little Endian Swapped: " + BitConverter.ToString(littleEndianSwapped));
   }
}

Этот код демонстрирует, как можно преобразовать массив байтов в различные форматы, используя порядок следования ABCD.

Порядок следования байтов в различных системах и протоколах имеет специальные названия, которые зависят от способа упорядочивания:

Big-Endian (ABCD): Это порядок, при котором старший (наиболее значимый) байт хранится по наименьшему адресу. Такой порядок иногда называют "сетевым порядком байтов" (network byte order), так как он используется в сетевых протоколах, таких как TCP/IP.

Little-Endian (DCBA): В этом порядке младший (наименее значимый) байт хранится по наименьшему адресу. Это противоположность big-endian и часто используется в архитектурах процессоров, таких как x86.

Big-Endian Swapped (BADC): Это нестандартный термин, но он описывает порядок, в котором байты меняются местами попарно в рамках big-endian. Это может быть полезно в некоторых специфических приложениях или протоколах.

Little-Endian Swapped (CDAB): Аналогично, это нестандартный термин, который описывает порядок, в котором байты меняются местами попарно в рамках little-endian.

Таким образом, стандартные термины — это big-endian и little-endian. Варианты со "swapped" не являются общепринятыми терминами и используются для описания специфических случаев перестановки байтов.

using System;
using System.Linq;
public static class ByteArrayConverter
{
   public static byte[] BigToLittleEndian(byte[] byteArray)
   {
       // Преобразование из big-endian в little-endian
       byte[] result = new byte[byteArray.Length];
       Array.Copy(byteArray, result, byteArray.Length);
       Array.Reverse(result);
       return result;
   }
   public static byte[] LittleToBigEndian(byte[] byteArray)
   {
       // Преобразование из little-endian в big-endian
       byte[] result = new byte[byteArray.Length];
       Array.Copy(byteArray, result, byteArray.Length);
       Array.Reverse(result);
       return result;
   }
   public static byte[] BigEndianSwapped(byte[] byteArray)
   {
       // Преобразование в big-endian swapped
       return byteArray.Where((b, i) => i % 2 != 0).Concat(byteArray.Where((b, i) => i % 2 == 0)).ToArray();
   }
   public static byte[] LittleEndianSwapped(byte[] byteArray)
   {
       // Преобразование в little-endian swapped
       return byteArray.Where((b, i) => i % 2 != 0).Concat(byteArray.Where((b, i) => i % 2 == 0)).ToArray();
   }
   public static byte[] SwappedToBigEndian(byte[] byteArray, int length)
   {
       // Преобразование из swapped в big-endian
       byte[] swapped = new byte[length];
       int halfLength = length / 2;
       Array.Copy(byteArray.Take(halfLength).ToArray(), 0, swapped, 0, halfLength);
       Array.Copy(byteArray.Skip(halfLength).ToArray(), 0, swapped, 1, halfLength);
       return swapped;
   }
   public static byte[] SwappedToLittleEndian(byte[] byteArray, int length)
   {
       // Преобразование из swapped в little-endian
       byte[] swapped = new byte[length];
       int halfLength = length / 2;
       Array.Copy(byteArray.Skip(halfLength).ToArray(), 0, swapped, 0, halfLength);
       Array.Copy(byteArray.Take(halfLength).ToArray(), 0, swapped, 1, halfLength);
       return swapped;
   }
}
public class Program
{
   public static void Main()
   {
       byte[] byteArray = { 0x12, 0x34, 0x56, 0x78 };
       byte[] bigEndian = byteArray;
       byte[] littleEndian = ByteArrayConverter.BigToLittleEndian(byteArray);
       byte[] bigEndianSwapped = ByteArrayConverter.BigEndianSwapped(byteArray);
       byte[] littleEndianSwapped = ByteArrayConverter.LittleEndianSwapped(byteArray);
       Console.WriteLine("Big Endian: " + BitConverter.ToString(bigEndian));
       Console.WriteLine("Little Endian: " + BitConverter.ToString(littleEndian));
       Console.WriteLine("Big Endian Swapped: " + BitConverter.ToString(bigEndianSwapped));
       Console.WriteLine("Little Endian Swapped: " + BitConverter.ToString(littleEndianSwapped));
   }
}