Преобразование массива байтов из младшего в большой или наоборот

Как мне преобразовать массив байтов Byte[] из маленького в большой.

Я думаю о переносе этой программы на Mono, и мне было интересно, как лучше всего подойти. Любая помощь будет оценена по достоинству.

РЕДАКТИРОВАТЬ: Я читаю из файла как в вдовах, так и в моно.

Спасибо. Боб.


person scope_creep    schedule 10.01.2011    source источник
comment
Массив байтов содержит все, что считывается из файла.   -  person scope_creep    schedule 10.01.2011


Ответы (4)


Вы не можете «преобразовать byte[] в прямой порядок байтов», если не знаете, что находится в byte[]. Например, для 2-байтовых целых чисел необходимо поменять местами два байта, а для 4-байтовых целых чисел необходимо поменять местами 4 байта. Если массив содержит только одно целое число, то сработает перестановка элементов. Если нет, вам нужно будет обрабатывать каждую отдельную сущность, содержащуюся в массиве, отдельно.

Mono.DataConvert — это библиотека, которая может помочь здесь, если вы знаете, какие сегменты массива нужно рассматриваться как тип данных. Я настоятельно рекомендую проверить эту библиотеку; Я использую его в нескольких проектах, и это довольно изящно. Он даже лицензирован MIT и содержится в одном исходном файле, поэтому вы можете просто скомпилировать его непосредственно в любую сборку, которую вы создаете.

person cdhowie    schedule 10.01.2011
comment
Привет, cdhowie, я видел Mono.DataConvert, но не знаю, как его применить. По сути, массив содержит все, что читается в файле журнала, либо в Windows, либо в Mono, в другой системе. Я не хочу гарантировать, что все, что читается, является единым форматом с порядком байтов (по умолчанию для Windows) для всех читателей журнала, где бы оно ни находилось или читалось. - person scope_creep; 10.01.2011
comment
Не зная формата этого файла журнала, вы ничего не сможете сделать. - person cdhowie; 10.01.2011
comment
Как работает формат. Я знаю кодировку для каждого файла, который я читаю. - person scope_creep; 10.01.2011
comment
Я не уверен, что понимаю, что вы имеете в виду. Кодирование? Это текстовый файл? Если да, то какая кодировка символов? - person cdhowie; 10.01.2011
comment
Да, это текстовый файл. ASCII, но это может быть юникод или UTF32. - person scope_creep; 10.01.2011
comment
ASCII не зависит от порядков байтов, поскольку все символы представляют собой один байт. И это не могут быть ASCII и Unicode — либо одно, либо другое. Что он? - person cdhowie; 10.01.2011
comment
Я читаю из файла, формат которого определяется файлом конфигурации xml. Предположим, например, ASCII. - person scope_creep; 10.01.2011
comment
Если это ASCII, то вам вообще ничего не нужно делать, поскольку однобайтовые символы ASCII не зависят от архитектуры платформы. - person cdhowie; 10.01.2011
comment
Даже если на линуксе и винде. Как бы я сделал преобразование, если бы кодировка была UTF32 - person scope_creep; 10.01.2011
comment
Ты смущен. Операционная система не имеет ничего общего с порядком следования байтов — это имеет значение архитектура. Обе ОС работают на архитектуре с одинаковым порядком байтов, например x86, x64 и т. д.? Если это так, никакого преобразования не требуется. Кроме того, UTF32 должен записывать BOM (метку порядка байтов) в начале потока, который читатели используют для определения порядка следования байтов, с которым был закодирован поток. Так что для UTF32 вам тоже ничего не нужно делать. И вам никогда не придется ничего делать с ASCII, так как его символы однобайтовые (и, следовательно, на большинстве архитектур не влияет порядок следования байтов). - person cdhowie; 10.01.2011
comment
Я не смущен. Похоже, вы намеренно упускаете суть. Вопрос, который я задаю, полностью связан с вопросом, см. Выше, и я с самого начала задавал один и тот же вопрос: как преобразовать массив байтов из младшего в большой и наоборот. - person scope_creep; 10.01.2011
comment
Похоже, вы упускаете из виду тот факт, что вы не можете конвертировать, если не знаете, что конвертируете. Единого решения не существует, поскольку любое решение будет зависеть от того, что содержит массив байтов.< /b> Если вы не знаете формат файла, вы не можете выполнить какое-либо преобразование. Я не уверен, как я могу быть более ясным, чем это. - person cdhowie; 10.01.2011
comment
Откуда, черт возьми, тебе это в голову пришло, я не знаю формата. Я делаю. Если вы не знаете, как это сделать. Не комментируйте. - person scope_creep; 10.01.2011
comment
По крайней мере, вы должны сообщить нам формат. И, как я сказал выше, если процессоры имеют одинаковую архитектуру или порядок следования байтов (что, как я подозреваю, так и есть), преобразование не требуется. В любом случае, один из способов преобразования состоит в том, чтобы найти каждое целое число в потоке и изменить порядок байтов, составляющих это целое число. Это все, чем я могу помочь, не зная формата. - person cdhowie; 10.01.2011
comment
Все, что я знаю, это кодировка. Я читаю файл, обычно это будут какие-то строковые данные. Эта программа для чтения файлов является кросс-платформенной на моно. - person scope_creep; 13.01.2011
comment
Если файл представляет собой одну большую строку, и вы знаете кодировку, то не могли бы вы сказать нам кодировку? - person cdhowie; 14.01.2011
comment
Я принципиально ищу пример того, как преобразовать данные с прямым порядком байтов в обратный. Ридер работает на нескольких платформах, а кодировка определяется в конфигурационном файле xml. Вы сказали, что ASCII довольно прост в обращении. Каким был бы процесс, если бы он был на другом конце спектра, если бы кодировка файла была UTF32. Я пытаюсь понять, сколько работы требуется для всех возможных кодировок. Или это какая-то категория, о которой мы могли бы сказать, что эти кодировки потребуют этого преобразования, или каждая из них, вероятно, будет уникальной. - person scope_creep; 14.01.2011
comment
Каждая кодировка текста уникальна. UTF32 со спецификацией не требует специальной обработки, поскольку спецификация сообщает читателю, какой порядок байтов использовался. UTF32 без BOM не будет читаться читателями, которые ожидают другого порядка следования байтов. Работа, связанная с каждой кодировкой, будет работой, необходимой для чтения каждого символа в одной кодировке с порядком байтов и записи его в другой, и объем этой работы снова будет зависеть от кодировки. Для большинства кодировок вы должны прочитать один символ, изменить порядок байтов символа и записать эти байты обратно. Это настолько общее, насколько я могу это сделать. - person cdhowie; 14.01.2011
comment
Спасибо cdhowie. Это дало мне направление, хотя я могу задать другой, более острый вопрос, а именно эти детали. - person scope_creep; 17.01.2011

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

Для этого вы должны сначала определить байты, которые составляют указанное целое число, char и т. д., а затем перевернуть эти байты. Простое переворачивание/реверсирование всего массива может не сработать (если только весь массив не представляет одно целое число, символ и т. д.).

Используйте следующую перегрузку метода Array.Reverse(), чтобы сделать то, что ты хочешь...

public static void Reverse(
    Array array,
    int index,
    int length
)
person Autodidact    schedule 10.01.2011

Вы хотите поменять местами элементы в массиве или значение самих байтов? Если просто массив, то можно использовать Array.Reverse()

person Brian Ball    schedule 10.01.2011

В моем случае мне нужно было преобразовать заданный ключ (который уже был в формате с прямым порядком байтов) в строку с прямым порядком байтов. Это было проще, чем я сначала себе представлял, и не требовало смещения байтов. Вот простое консольное приложение, которое я использовал для тестирования:

    using System;
    using System.Text;

    public class Program
    {
        public static void Main()
        {   
            string key = "B13E745599654841172F741A662880D4";
            var guid = new Guid(key);
            string hex = HexStringFromBytes(guid.ToByteArray());
            Console.WriteLine("Original key: " + guid);
            Console.WriteLine();                
            Console.WriteLine("Big-endian version of the key: " + hex);
            Console.ReadLine();
        }

        public static string HexStringFromBytes(byte[] bytes)
        {
            var sb = new StringBuilder();
            foreach (byte b in bytes)
            {
                var hex = b.ToString("x2");
                sb.Append(hex);
            }
            return sb.ToString();
        }
    }

Данный пример печатает это в консоли:

Оригинальный ключ: B13E7455-9965-4841-172F-741A662880D4

Версия ключа с обратным порядком байтов: 55743eb165994148172f741a662880d4

Вы можете найти работающую скрипту здесь: Light Endian to Big Endian

person Damian Perez    schedule 09.05.2016