Convert byte array from small to big endian or vice versa
Asked Answered
H

4

6

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.

Hermann answered 10/1, 2011 at 16:59 Comment(1)
The byte array contains whatevers read in from a file.Hermann
S
4

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.

Scission answered 10/1, 2011 at 17:2 Comment(19)
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.Hermann
Without knowing the format of that log file, there is nothing at all you can do.Scission
How does the format. I know the encoding for each file i'm reading.Hermann
I'm not sure I know what you mean. Encoding? Is this a text file? If so, what is the character encoding?Scission
Yip, it is a text file. ASCII but it could easily be unicode, or UTF32.Hermann
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?Scission
I'm reading from a file, which whose format is defined by a xml configuration file. Assume ASCII for example.Hermann
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.Scission
Even if on Linux and windows. How would I do a conversion if the encoding was UTF32Hermann
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).Scission
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.Hermann
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.Scission
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.Hermann
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.Scission
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.Hermann
If the file is one big string and you know the encoding, then can't you tell us the encoding?Scission
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.Hermann
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.Scission
Thanks cdhowie. That's gave me a direction, athough I may ask another more pointed question, which these details.Hermann
H
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
)
Halitosis answered 10/1, 2011 at 17:2 Comment(0)
L
1

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

Latent answered 9/5, 2016 at 19:1 Comment(0)
B
-1

Do you want to reverse the items in the array, or the value of the bytes themselves? If just the array, then you can use Array.Reverse()

Bushhammer answered 10/1, 2011 at 17:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.