1

私のc++プログラムでは、debian linuxのuuidパッケージを使用してuuid値を生成しています。これにより、uuid_t型のサイズ16のunsignedchar配列が返されます。次に、それを文字列に変換してコンソールに出力します。

次に、同じバイト配列を取得して、ネットワーク経由でWindowsマシンに送信します。Windowsマシンは.netのGUIDタイプを使用し、同じバイト配列を使用してGUIDオブジェクトを作成します。次に、GUIDのToStringメソッドを使用して、コンソールに再度出力します。驚くべきことに、Linuxと.Netでは、ほとんど同じですが、同じバイト配列の文字列表現が異なります。

次に例を示します。

バイト配列:

101,208,176,173,236,192,64,86,191,214,132,2,213,232,143,247

Linux:65d0b0ad-ecc0-4056-bfd6-8402d5e88ff7

.NET:adb0d065-c0ec-5640-bfd6-8402d5e88ff7

お気づきかもしれませんが、最後の部分は同じで、最初の部分は同じ数字を使用しており、数字の順序だけが異なります。上で説明した方法で作成したすべてのUUIDは同じパターンに従っており、バイト順序の違いがあると思います。

LinuxでUUID値を作成し、同じバイト配列を使用して同じ文字列表現を使用するにはどうすればよいですか。

4

2 に答える 2

2

これこのメッセージによると、問題は、GUID/UUIDをビッグエンディアンにするかリトルエンディアンにするかについての理解が異なることにあります。Microsoftの実装はそれらをビッグエンディアン(少なくともIntelプラットフォームでは)として扱っているように見えますが、uuid_unparseリトルエンディアンのようです。Wikiによると、GUID(MicrosoftのUUID)はRFC 4122、セクション4.1.2に準拠しており、ビッグエンディアンの順序付けが必要なようです。

したがって、これは実装間の明らかな矛盾です。回避策として、システム間で文字列形式でデータを交換することを提案します。これは、両方のシステムで一貫しているようです。

于 2012-06-04T11:01:27.937 に答える
0

残念ながら、同じバイト配列を持つことはできずGuid.ToString、Linux 文字列と一致する文字列を生成することはできません。

どちらを優先するかを決定する必要があります。

var dotNetGuid = new Guid(new byte[] { 101, 208, 176, 173, 236, 192, 64, 86,
                                       191, 214, 132, 2, 213, 232, 143, 247 });

// option 1 - keep the existing guid's byte array intact
//            and create a new ToUnixString method to display it as-required

Console.WriteLine(dotNetGuid.ToString());      // adb0d065-c0ec-5640-bfd6-8402d5e88ff7
Console.WriteLine(dotNetGuid.ToUnixString());  // 65d0b0ad-ecc0-4056-bfd6-8402d5e88ff7

// option 2 - create a new guid by re-arranging the existing guid's byte array
//            and then use the standard ToString method

var unixGuid = dotNetGuid.ChangeByteOrder();
Console.WriteLine(dotNetGuid.ToString());  // adb0d065-c0ec-5640-bfd6-8402d5e88ff7
Console.WriteLine(unixGuid.ToString());    // 65d0b0ad-ecc0-4056-bfd6-8402d5e88ff7

// ...

public static class GuidExtensions
{
    public static string ToUnixString(this Guid guid,
        string format = "D", IFormatProvider provider = null)
    {
        return guid.ChangeByteOrder().ToString(format, provider);
    }

    public static Guid ChangeByteOrder(this Guid guid)
    {
        var s = guid.ToByteArray();
        var d = new byte[]
                    {
                        s[3], s[2], s[1], s[0], s[5], s[4], s[7], s[6],
                        s[8], s[9], s[10], s[11], s[12], s[13], s[14], s[15]
                    };

        return new Guid(d);
    }
}
于 2012-06-01T14:00:06.240 に答える