我在将 GUID 转换为 gRPC/protobuf-net bcl-Guids 时遇到问题(带有 Guid 定义的 bcl.proto)。
我确实找到了两篇文章,例如: 将 protobuf-net bcl.Guid 的 HI/LO 与 sql uniqueidentifiers 协调起来以进行相关子查询? 或 https://stackoverflow.com/a/6670210/109951 但事实证明,这些答案对于某些人来说无法正常工作 指导。
这是我在 .NET Framework 4.7.2 中的代码:
private void SetHighLow(Guid guid)
{
long[] longs = new long[2];
byte[] bytes = guid.ToByteArray();
longs[0] = BitConverter.ToInt64(bytes, 0);
longs[1] = BitConverter.ToInt64(bytes, 8);
textBoxGuidLo.Text = longs[0].ToString();
textBoxGuidHi.Text = longs[1].ToString();
}
这些 GUID 工作正常例如:
63b6ce49-51a6-45b0-8304-cd2b64644419
➡️你好:
5021603359597448777
,嗨:
1820690530758886531
34fd7e06-6f44-4fc3-925b-472d3c19d677
➡️你好:
5747559888192372230
,嗨:
8635117081777888146
hi
且无法正确计算回来:
c0dbb1b2-0a21-40fb-925b-472d3c19d677
➡️你好:
4682347377667584434
,嗨:
-3098910154901023072
88e052a2-8873-42b8-a62a-e858abef10e5
➡️你好:
4807742632017023650
,嗨:
-1940787920186627418
private void SetHighLow(Guid guid)
{
byte[] bytes = guid.ToByteArray();
ulong[] longs = new ulong[2];
longs[0] = BitConverter.ToUInt64(bytes, 0);
longs[1] = BitConverter.ToUInt64(bytes, 8);
textBoxGuidLo.Text = longs[0].ToString();
textBoxGuidHi.Text = longs[1].ToString();
textBoxGuidGrpc.Text = String.Format(HiLoJsonFormat, longs[0], longs[1]);
}
使用 ToUInt64 而不是 ToInt64 确实达到了目的。对于那些寻找其他方向的人:
ulong low = Convert.ToUInt64(textBoxGuidLo.Text);
ulong high = Convert.ToUInt64(textBoxGuidHi.Text);
uint a = (uint)(low >> 32), b = (uint)low, c = (uint)(high >> 32), d = (uint)high;
return new Guid((int)b, (short)a, (short)(a >> 16),
(byte)d, (byte)(d >> 8), (byte)(d >> 16), (byte)(d >> 24),
(byte)c, (byte)(c >> 8), (byte)(c >> 16), (byte)(c >> 24));
using System;
public class HelloWorld
{
public static void Main(string[] args)
{
// Define the GUID
Guid guid = new Guid("723ea1a0-c720-4574-a909-95a7c9d83aeb");
// Convert the GUID to bytes
byte[] bytes = guid.ToByteArray();
// Print the bytes in hexadecimal format (little-endian)
Console.WriteLine("Bytes (little-endian):");
foreach (byte b in bytes)
{
Console.Write(b.ToString("X2") + " ");
}
Console.WriteLine();
// Reverse the byte order for each 8-byte chunk (big-endian)
ReverseBytes(bytes, 0, 3);
ReverseBytes(bytes, 4, 5);
ReverseBytes(bytes, 6, 7);
ReverseBytes(bytes, 0, 7);
ReverseBytes(bytes, 8, 15);
// Extract most significant bits (high) and least significant bits (low)
ulong high = BitConverter.ToUInt64(bytes, 0);
ulong low = BitConverter.ToUInt64(bytes, 8);
// Print the high and low components
Console.WriteLine("High: " + high);
Console.WriteLine("Low: " + low);
}
// Helper method to reverse bytes in a byte array for a specified range
static void ReverseBytes(byte[] bytes, int startIndex, int endIndex)
{
while (startIndex < endIndex)
{
byte temp = bytes[startIndex];
bytes[startIndex] = bytes[endIndex];
bytes[endIndex] = temp;
startIndex++;
endIndex--;
}
}
}