【问题标题】:Guid to 128bit Integer引导至 128 位整数
【发布时间】:2018-06-04 11:10:41
【问题描述】:

我需要将 guid 转换为大整数.. 这很好,但在测试期间我强调了一些我需要向我解释的内容;)

如果我执行以下操作:

        var g = Guid.NewGuid();     // 86736036-6034-43c5-9b85-1c833837dbea
        var p = g.ToByteArray();
        var x = new BigInteger(p);  // -28104782885366703164142972435490971594

但如果我在 python 中执行此操作.. 我会得到不同的结果:

        import uuid
        x = uuid.UUID('86736036-6034-43c5-9b85-1c833837dbea')
        print x
        print x.int  # 178715616993326703606264498842288774122

有更好的python知识和.net知识的人可以帮忙解释一下吗?

【问题讨论】:

  • 我应该学会阅读问题
  • 看来C#代码把它当成有符号整数了,我觉得没有意义。
  • 我之前的说法得到The Docs的证实:“构造函数期望字节数组中的正值使用符号和大小表示,负值使用二进制补码表示。在换句话说,如果设置了 value 中最高字节的最高位,则生成的 BigInteger 值为负。"
  • this 有帮助吗?
  • GUID.ToByte() 确实 not 保留顺序,它与 python 不兼容,因为 python 的 GUID.hex does 保留字节顺序

标签: c# python-2.7


【解决方案1】:

将 GUID 编码为其组件字节是一种非标准化操作,即 dealt with differently on Windows/Microsoft platforms(IMO 以最令人困惑的方式)。

var g = Guid.Parse("86736036-6034-43c5-9b85-1c833837dbea");
var guidBytes = $"0{g:N}"; //no dashes, leading 0
var pythonicUuidIntValue = BigInteger.Parse(guidBytes, NumberStyles.HexNumber);

将为您提供 C# 中的 Python 值

.ToByteArray 失败的原因隐含在 the instructions 中:

开始的四字节组和接下来的两个二字节组的顺序相反,而最后一个二字节组和结束的六字节组的顺序相同。

知道了这一点,就有可能编写一个不涉及字符串遍历的方法。供读者练习。

【讨论】:

【解决方案2】:

只是出于好奇,在这里和那里交换一些字节:-),然后在必要时为符号添加一个额外的字节。

var g = new Guid();
var bytes = g.ToByteArray();

var bytes2 = new byte[bytes[3] >= 0x7F ? bytes.Length + 1 : bytes.Length];

bytes2[0] = bytes[15];
bytes2[1] = bytes[14];
bytes2[2] = bytes[13];
bytes2[3] = bytes[12];
bytes2[4] = bytes[11];
bytes2[5] = bytes[10];
bytes2[6] = bytes[9];
bytes2[7] = bytes[8];

bytes2[8] = bytes[6];
bytes2[9] = bytes[7];

bytes2[10] = bytes[4];
bytes2[11] = bytes[5];

bytes2[12] = bytes[0];
bytes2[13] = bytes[1];
bytes2[14] = bytes[2];
bytes2[15] = bytes[3];

var bi2 = new BigInteger(bytes2);

(我已经在 1,000,000 个随机 Guid 上进行了测试,结果与使用 @spender 方法获得的结果相同)。

【讨论】:

  • 好的,我仍然有点迷失在为什么这些东西需要交换......我会阅读支持的帖子,然后回来......非常感谢!
  • @m1nkeh 因为有人认为他们的内部格式不同。 BigInteger 是小端序,而 Guid 是大端序,但是它们不是单个大数,而是许多小数(4 个字节之一、2 个字节中的两个和一个字节中的 8 个)。
  • 顺便说一句,你的他们的线是做什么的?
  • @m1nkeh 我以“正确”的顺序复制字节,交换了其中的一些(您可以看到右侧的索引器不仅仅是 15...0,而是 15。 ..8, 6, 7, 4, 5, 0, 1, 2, 3)
  • @m1nkeh 有注解here关于微软使用的格式(第二个)
猜你喜欢
  • 2015-11-28
  • 1970-01-01
  • 2011-09-03
  • 2013-07-20
  • 2013-08-28
  • 2013-04-11
  • 1970-01-01
相关资源
最近更新 更多