将 GUID 转换为 BCL HI/LO 时出现问题

问题描述 投票:0回答:2

我在将 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
    
    
这些 GUID 会产生负值

hi

无法正确计算回来:

  • c0dbb1b2-0a21-40fb-925b-472d3c19d677
    ➡️你好:
    4682347377667584434
    ,嗨:
    -3098910154901023072
    
    
  • 88e052a2-8873-42b8-a62a-e858abef10e5
    ➡️你好:
    4807742632017023650
    ,嗨:
    -1940787920186627418
    
    
有什么想法吗?

c# grpc guid protobuf-net
2个回答
0
投票
我确实找到了解决方案,因为@JonasH 为我指明了正确的方向:

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));
    

0
投票
如果您想要 UUID(hi, lo) 兼容的 hi 和 lo 值。

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--; } } }
    
© www.soinside.com 2019 - 2024. All rights reserved.