Convert byte array from small to big endian or vice versa

18,802

Solution 1

You cannot "convert a byte[] to big endian" unless you know what is in the byte[]. For example, 2-byte integers will need to have their two bytes swapped, while 4-byte integers will need to have their 4 bytes reversed. If the array only contains one integer then reversing the elements will work. If not you will need to process each distinct entity contained in the array separately.

Mono.DataConvert is a library that can help here, if you know what segments of the array need to be treated as what kind of data type. I highly recommend checking out this library; I'm using it in several projects and it's pretty nifty. It's even MIT licensed and is contained within one source file, so you can just compile it directly into whatever assembly you are building.

Solution 2

Hmm I think there is a problem here. A byte array is seldom inherently big endian or little endian. A byte is almost always endian independent. What you probably want is to correct the endianness of the integers, chars etc. contained in the byte array.

In order to do so you must first identify the bytes which constitute the said integer, char etc. and then flip those bytes. Simply flipping/reversing the whole array may not work (unless the whole array represents one single integer, char etc.)

Use the following overload of the Array.Reverse() method to do what you want...

public static void Reverse(
    Array array,
    int index,
    int length
)

Solution 3

In my case, I needed to convert from a given key (that was already in little endian format) to big endian string. It was easier than I first imagined, and did not require shifting bytes. Here's a simple console application I used to test it:

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

The given example prints this in the console:

Original key: B13E7455-9965-4841-172F-741A662880D4

Big-endian version of the key: 55743eb165994148172f741a662880d4

You can find a working fiddle here: Little Endian to Big Endian

Share:
18,802
scope_creep
Author by

scope_creep

Updated on June 18, 2022

Comments

  • scope_creep
    scope_creep almost 2 years

    How would I convert a byte array, Byte[] from small to big endian.

    I'm thinking of porting this program to Mono and was wondering the best approach. Any help would be appreciated.

    EDIT: I'm reading from a file both on widows and mono.

    Thanks. Bob.

  • scope_creep
    scope_creep over 13 years
    Hi cdhowie, I saw the Mono.DataConvert but don't know how to apply it. Essentially the array contains whatever is read in a log file, either on windows or on Mono, on another system. I wan't to ensure that whatever is read is a a single endian format (windows default) for all log readers, where ever it resides or reads.
  • cdhowie
    cdhowie over 13 years
    Without knowing the format of that log file, there is nothing at all you can do.
  • scope_creep
    scope_creep over 13 years
    How does the format. I know the encoding for each file i'm reading.
  • cdhowie
    cdhowie over 13 years
    I'm not sure I know what you mean. Encoding? Is this a text file? If so, what is the character encoding?
  • scope_creep
    scope_creep over 13 years
    Yip, it is a text file. ASCII but it could easily be unicode, or UTF32.
  • cdhowie
    cdhowie over 13 years
    ASCII is endian-neutral since all characters are one byte. And it can't be "ASCII and Unicode" -- it's one or the other. Which is it?
  • scope_creep
    scope_creep over 13 years
    I'm reading from a file, which whose format is defined by a xml configuration file. Assume ASCII for example.
  • cdhowie
    cdhowie over 13 years
    If it's ASCII then you don't have to do anything at all, since ASCII's single byte characters are not affected by the platform's architecture.
  • scope_creep
    scope_creep over 13 years
    Even if on Linux and windows. How would I do a conversion if the encoding was UTF32
  • cdhowie
    cdhowie over 13 years
    You are confused. Operating system has nothing to do with endianness -- it's architecture that does. Are both OSes running on an architecture with the same endianness, like x86, x64, etc? If so, no conversion is necessary. Also, UTF32 should write a BOM (Byte-Order Mark) at the start of the stream, which readers use to detect which endianness the stream was encoded with. So for UTF32 you should have to do exactly nothing as well. And you will never have to do anything with ASCII, since its characters are single-byte (and therefore not affected by endianness on most architectures).
  • scope_creep
    scope_creep over 13 years
    I'm not confused. You seem to be intentially missing the point. The question i'm asking is all in the question, see above, and i've been asking the same question from the beginnning - How to convert an byte array from small to big endian and vice versa.
  • cdhowie
    cdhowie over 13 years
    You seem to be missing the point that you can't convert unless you know what you are converting. There is no single solution, since any solution will depend on what the byte array contains. If you don't know the format of the file then you cannot perform any conversion. I'm not sure how I can be more clear than that.
  • scope_creep
    scope_creep over 13 years
    Where the hell have you got it into yout head I don't know the format. I do. If you don't how to do it. Don't comment.
  • cdhowie
    cdhowie over 13 years
    Well, you should at least let us know the format. And as I said above, if the processor architectures are the same, or have the same endianness (which I suspect is the case), no conversion is necessary. At any rate, one way to convert is to find each integer in the stream and reverse the order of the bytes that compose that integer. That's as much as I can help without knowing the format.
  • scope_creep
    scope_creep over 13 years
    All I know is the encoding. I'm reading a file, generally it will be some kind of string data. This file reader is cross platform on mono.
  • cdhowie
    cdhowie over 13 years
    If the file is one big string and you know the encoding, then can't you tell us the encoding?
  • scope_creep
    scope_creep over 13 years
    I'm fundamentally looking for an example of how to convert big endian data to small endian. The reader works on several platforms, and the encoding is defined in a xml configuration file. ASCII you have said is fairly simple to handle. What would be the process if it was at the other end of the spectrum, if the encoding of a file was UTF32. I'm trying to get a idea of how much work is involved for all possible encodings. Or is their some kind of category, that we could say, these encodings would require this conversion, or is each one likely to be unique.
  • cdhowie
    cdhowie over 13 years
    Each text encoding is unique. UTF32 with a BOM requires no special treatment, since the BOM will tell the reader what byte-ordering was used. UTF32 without a BOM will not be readable by readers that expect a different endianness. The work involved for each encoding will be the work required to read in each character in one endian encoding and write it in another, and how much work that is will again depend on the encoding. For most encodings, you would read one character, reverse the order of the bytes of the character, and write those bytes back out. That's as generic as I can make it.
  • scope_creep
    scope_creep over 13 years
    Thanks cdhowie. That's gave me a direction, athough I may ask another more pointed question, which these details.