代码之家  ›  专栏  ›  技术社区  ›  m1nkeh

guid到128位整数

  •  1
  • m1nkeh  · 技术社区  · 6 年前

    我需要将一个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的人能帮助解释这一点吗?

    2 回复  |  直到 6 年前
        1
  •  3
  •   xanatos    6 年前

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

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

    (我随机测试了100万次 Guid 结果与用@spender方法得到的结果相当)。

        2
  •  4
  •   spender    6 年前

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

    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得到的蟒蛇值#

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

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

    知道了这一点,也许可以编写一个不涉及字符串遍历的方法。给读者的练习。