The*_*cer 20 .net c# java uuid guid
我需要将在.NET中生成的Guid传递给Java应用程序.我用Guid.ToByteArray()它将它作为a存储在磁盘上byte[],然后将其读入Java并将其转换为UUID.为此,我复制了UUID的(私有)构造函数的实现,该构造函数采用byte[]:
private UUID(byte[] data) {
long msb = 0;
long lsb = 0;
assert data.length == 16;
for (int i=0; i<8; i++)
msb = (msb << 8) | (data[i] & 0xff);
for (int i=8; i<16; i++)
lsb = (lsb << 8) | (data[i] & 0xff);
this.mostSigBits = msb;
this.leastSigBits = lsb;
}
Run Code Online (Sandbox Code Playgroud)
但是,当我使用UUID检查时toString(),Java UUID与.NET Guid不同.
例如,.NET Guid
888794c2-65ce-4de1-aa15-75a11342bc63
Run Code Online (Sandbox Code Playgroud)
变成Java UUID
c2948788-ce65-e14d-aa15-75a11342bc63
Run Code Online (Sandbox Code Playgroud)
似乎前三组的字节顺序是相反的,而后两组中的顺序是相同的.
既然我希望toString()Guid和UUID都能产生相同的结果,有谁知道我应该如何正确地将.NET Guid读入Java UUID?
编辑:澄清一下,实施不是我自己的.它是类的私有构造函数,java.util.UUID它采用a byte[],我将其复制用于从磁盘读取byte []到UUID.
我不想使用字符串来存储Guids,因为我存储了很多它们,这似乎是浪费空间.
Russell Troywest的链接至少澄清了为什么Guid的前几组出现逆转,而下半场保持相同的顺序.问题是,我可以依赖.NET 始终以相同的顺序生成这些字节吗?
Rus*_*est 12
你能不能只将.Net Guid存储为字符串并将其读入Java?这样您就不必担心字节顺序或任何事情.
如果没有那么这解释了如何在C#中布局字节
http://msdn.microsoft.com/en-us/library/fx22893a.aspx
Pau*_*ith 11
编辑2017-08-30:每条评论交换数组元素6和7.
我必须在C#应用程序中读取和写入来自MySQL的Guids(存储为二进制(16)),但Java应用程序也使用该数据库.以下是我用于在.NET little-endian和Java big-endian字节顺序之间进行转换的扩展方法:
public static class GuidExtensions
{
/// <summary>
/// A CLSCompliant method to convert a Java big-endian Guid to a .NET
/// little-endian Guid.
/// The Guid Constructor (UInt32, UInt16, UInt16, Byte, Byte, Byte, Byte,
/// Byte, Byte, Byte, Byte) is not CLSCompliant.
/// </summary>
[CLSCompliant(true)]
public static Guid ToLittleEndian(this Guid javaGuid) {
byte[] net = new byte[16];
byte[] java = javaGuid.ToByteArray();
for (int i = 8; i < 16; i++) {
net[i] = java[i];
}
net[3] = java[0];
net[2] = java[1];
net[1] = java[2];
net[0] = java[3];
net[5] = java[4];
net[4] = java[5];
net[6] = java[7];
net[7] = java[6];
return new Guid(net);
}
/// <summary>
/// Converts little-endian .NET guids to big-endian Java guids:
/// </summary>
[CLSCompliant(true)]
public static Guid ToBigEndian(this Guid netGuid) {
byte[] java = new byte[16];
byte[] net = netGuid.ToByteArray();
for (int i = 8; i < 16; i++) {
java[i] = net[i];
}
java[0] = net[3];
java[1] = net[2];
java[2] = net[1];
java[3] = net[0];
java[4] = net[5];
java[5] = net[4];
java[6] = net[7];
java[7] = net[6];
return new Guid(java);
}
}
Run Code Online (Sandbox Code Playgroud)
如前所述,.NET 中 GUID 的二进制编码将前三组中的字节按小端顺序(颠倒)放置 - 请参阅Guid.ToByteArray 方法。要从中创建java.util.UUID,您可以使用以下代码:
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.UUID;
public UUID toUUID(byte[] binaryEncoding) {
ByteBuffer source = ByteBuffer.wrap(binaryEncoding);
ByteBuffer target = ByteBuffer.allocate(16).
order(ByteOrder.LITTLE_ENDIAN).
putInt(source.getInt()).
putShort(source.getShort()).
putShort(source.getShort()).
order(ByteOrder.BIG_ENDIAN).
putLong(source.getLong());
target.rewind();
return new UUID(target.getLong(), target.getLong());
}
Run Code Online (Sandbox Code Playgroud)
为了响应您的编辑,不能,您不能始终依赖于以相同顺序生成的字节.运行时确定字节序.然而,C#确实提供BitConverter.isLittleEndian了这个原因.
我知道你无法改变Java实现的端点和位移.但是你可以在存储之后和发送到Java之前将C#端的位移位.
更新:
编辑:实际上,你可以指望它在第一块字节的布局中始终是小端,但从技术上讲你不能.
小智 5
GUID.toByteArray在C#中很奇怪.上半场是小端,下半场是大端.
对此页面的评论指出了这一事实:http: //msdn.microsoft.com/en-us/library/system.guid.tobytearray.aspx
返回的字节数组中的字节顺序与Guid值的字符串表示形式不同.开始的四字节组和接下来的两个双字节组的顺序相反,而最后两个字节组和结束六字节组的顺序相同.