C#でリトルエンディアンをビッグエンディアンに変換する

タイトルの通り変換をするための操作の紹介をしたいと思います。

まず、誤解を恐れずに言うと、ネットワークにデータを流すときは「ビッグエンディアン」形式、いつも使ってるPCは「リトルエンディアン」形式が使われています。

更に、ネットワーク上にデータを流すときは「ビッグエンディアン」形式と暗黙的に決まっています。従って、2バイト以上の変数の内容はエンディアンを変換してから送信する必要があります。*1(相手がHTTPでJSONとかではこのような事は意識する必要ないのですが、対向システムがC/C++なTCPソケット通信の場合必要になったりします。)

// uint(=符号なし32ビット整数)の変換の例
元データ = 0xA1B2C3D4
変換後データ = 0xD4C3B2A1

// double(64 ビット浮動小数点)の変換の例
元データ = 0.002560xF1 68 E3 88 B5 F8 64 3F)
変換後データ = -2.0258655953055083E+2380x3F 64 F8 B5 88 E3 68 F1)

// ★変数の中で1バイトごとに並び順が入れ替わっています。

1バイトごとに全部逆になってればOKです。というわけで、各型で変換するユーティリティを作成しました。

public static class EndianUtil
{
    public static int Reverse(int data)
    {
        return BitConverter.ToInt32(BitConverter.GetBytes(data).Reverse().ToArray(), 0);
    }

    public static uint Reverse(uint data)
    {
        return BitConverter.ToUInt32(BitConverter.GetBytes(data).Reverse().ToArray(), 0);
    }

    public static float Reverse(float data)
    {
        return BitConverter.ToSingle(BitConverter.GetBytes(data).Reverse().ToArray(), 0);
    }

    public static double Reverse(double data)
    {
        return BitConverter.ToDouble(BitConverter.GetBytes(data).Reverse().ToArray(), 0);
    }
}

使い方は、変換したい値を引数に指定して戻り値で受けるだけです。戻り値を受けた変数の内容はエンディアンが変換されたものになります。

public static void Main(string[] args)
{
    uint src = 0xA1B2C3D4;
    uint dest = EndianUtil.Reverse(src);

    double dsrc = 0.00256;
    double d = EndianUtil.Reverse(dsrc);
}

また、ネットワークから受けた変数も上記のメソッドを通すことによって「ビッグエンディアン」から「リトルエンディアン」に戻ることができます。

*1:エンディアンの概念や詳細はほかサイトを参照ください。