C# - 为什么 System.Guid 翻转字节数组中的字节?

C# - why does System.Guid flip the bytes in a byte array?

将以下代码输入 C# 立即数 window 时,会产生一些异常结果,我只能假设这是因为在内部,System.Guid 翻转了某些字节:

当使用从0到15的有序字节数组时

new Guid(new byte[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15})
[03020100-0504-0706-0809-0a0b0c0d0e0f]

当使用值为 0 到 15 的非有序字节数组时

new Guid(new byte[] {3, 2, 1, 0, 5, 4, 7, 6, 8, 9, 10, 11, 12, 13, 14, 15})
[00010203-0405-0607-0809-0a0b0c0d0e0f]

为什么前3组翻转了?

Wikipedia 上找到关于 UUID。

Other systems, notably Microsoft's marshalling of UUIDs in their COM/OLE libraries, use a mixed-endian format, whereby the first three components of the UUID are little-endian, and the last two are big-endian.

For example, 00112233-4455-6677-8899-aabbccddeeff is encoded as the bytes 33 22 11 00 55 44 77 66 88 99 aa bb cc dd ee ff

第一个 4 字节块属于 Int32 值,接下来的 2 个块属于 Int16 值,由于 byte order. Perhaps you should try the other constructor 具有匹配的整数数据类型作为参数并给出一个反向分配给 Guid更直观的排序:

Guid g = new Guid(0xA, 0xB, 0xC, 
                  new Byte[] { 0, 1, 2, 3, 4, 5, 6, 7 } );
Console.WriteLine("{0:B}", g);
// The example displays the following output:
//        {0000000a-000b-000c-0001-020304050607}

查看source code of Guid.cs可以看出其背后的结构:

// Represents a Globally Unique Identifier.
public struct Guid : IFormattable, IComparable,
                     IComparable<Guid>, IEquatable<Guid> {
    //  Member variables
    private int         _a; // <<== First group,  4 bytes
    private short       _b; // <<== Second group, 2 bytes
    private short       _c; // <<== Third group,  2 bytes
    private byte       _d;
    private byte       _e;
    private byte       _f;
    private byte       _g;
    private byte       _h;
    private byte       _i;
    private byte       _j;
    private byte       _k;
    ...
}

如您所见,Guid 内部由一个 32 位整数、两个 16 位整数和 8 个单独的字节组成。在 little-endian architectures 上,第一个 int 和后面两个 short 的字节以相反的顺序存储。其余八个字节顺序不变