SQL Server Java兼容GUID / UUID(Big Endian UniqueIdentifier)

时间:2013-03-26 18:06:56

标签: java .net sql-server uniqueidentifier endianness

我正在尝试将128位二进制文​​件转换为sql中的uniqueidentifier,与.net和java中的相同。

我知道java使用大端,所以我想把它作为基础。

我可以在.net中获得正确的endianess,但我真的在SQL Server中苦苦挣扎。

爪哇:

        byte[] bytesOfMessage = "google.com".getBytes("UTF-8");

        MessageDigest md = MessageDigest.getInstance("MD5");
        byte[] md5 = md.digest(bytesOfMessage);
        ByteBuffer bb = ByteBuffer.wrap(md5);
        LongBuffer ig = bb.asLongBuffer();
        return new UUID(ig.get(0), ig.get(1));

返回1d5920f4-b44b-27a8-02bd-77c4f0536f5a

    System.Security.Cryptography.MD5 c = System.Security.Cryptography.MD5.Create();
    byte[] b = c.ComputeHash(Encoding.UTF8.GetBytes("google.com"));
    int z = System.Net.IPAddress.HostToNetworkOrder(BitConverter.ToInt32(b, 0));
    short y = System.Net.IPAddress.HostToNetworkOrder(BitConverter.ToInt16(b, 4));
    short x = System.Net.IPAddress.HostToNetworkOrder(BitConverter.ToInt16(b, 6));
    Guid g = new Guid(z, y, x, b.Skip(8).ToArray());
    return g;

返回1d5920f4-b44b-27a8-02bd-77c4f0536f5a

SQL

DECLARE @s VARCHAR(MAX) = 'google.com' --'goolge.com'

DECLARE @md5 BINARY(16) = HASHBYTES
        (
            'MD5',
            @s
        )

DECLARE @a BINARY(4) = 
        CONVERT
        (
            BINARY(4),
            REVERSE
            (
                CONVERT
                (
                    BINARY(4),
                    LEFT(@md5, 4)
                )
            )
        )

DECLARE @b BINARY(2) = 
        CONVERT
        (
            BINARY(2),
            REVERSE
            (
                CONVERT
                (
                    BINARY(2),
                    RIGHT(@md5, 12)
                )
            )
        )

DECLARE @c BINARY(2) = 
        CONVERT
        (
            BINARY(2),
            REVERSE
            (
                CONVERT
                (
                    BINARY(2),
                    RIGHT(@md5, 10)
                )
            )
        )

DECLARE @d BINARY(8) = 
        CONVERT
        (
            BINARY(8),
            RIGHT(@md5, 8)
        )

SELECT  
    CONVERT
    (
        UNIQUEIDENTIFIER,
        @a + @b + @c + @d
    )

返回D86B5A7F-7A25-4895-A6D0-63BA3A706627

转换为int64时,我能够让所有三个产生相同的值,但是GUID让我感到困惑。

Original Issue

Original Answer

2 个答案:

答案 0 :(得分:1)

SQL Server不支持UTF-8编码。见Description of storing UTF-8 data in SQL Server。使用Michael Harmon的建议将您的.NET函数添加到SQLServer以进行转换。有关如何将.NET函数添加到SQLServer的说明,请参阅How to encode...

或者,不要在Java和.NET代码中指定UTF-8。我相信SQL Server将使用与Java和.NET相同的256位编码。 (但不完全确定这一点。)

答案 1 :(得分:1)

如果您更正了SQL示例中google的拼写(在帖子中为goolge),则会得到正确的结果。