我试图将128位二进制文件转换为sql中的uniqueidentifier,与.net和java中的相同。
我知道java使用大端,所以我想把它作为基础。
我可以在.net中获得正确的endianess,但我真的在SQL Server中苦苦挣扎。
Java的:
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令我感到困惑。
如果你在SQL示例中更正了google
的拼写(你的帖子中是goolge
),你会得到正确的结果。
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位编码。 (但不完全确定。)