将128位带符号的BigInteger移位为始终为正

问题描述

|| 我正在将Guid转换为BigInteger,以便可以对它进行base62编码。这很好,但是在BigInterger中我可以得到负数。如何移动BigInteger,使数字为正。我还需要能够将其移回,以便可以转换回Guid。
// GUID is a 128-bit signed integer 
Guid original = new Guid(\"{35db5c21-2d98-4456-88a0-af263ed87bc2}\");
BigInteger b = new BigInteger(original.ToByteArray());

// shift so its a postive number?
    

解决方法

注意:对于Base64的URL安全版本,请考虑对Base64使用修改后的字符集(http://en.wikipedia.org/wiki/Base64#URL_applications),而不要使用自定义Base62。 我相信您可以先将0附加到数组(将使高字节始终不包含最高位的1),然后在确实需要正BigInteger的情况下转换为BigInteger。     ,你是说base64编码?
Convert.ToBase64String(Guid.NewGuid().ToByteArray());
    ,如果您有时会得到负数,则表明您的GUID值足够大,可以填充BigInteger的所有128位,否则BigInteger byte [] ctor会这样解释数据。为确保您的字节实际上是正数,请检查您是否获得了<= 16个字节(128位),并且最后一个字节的最高有效位(因为它的字节序为Little)为零。如果您的字节数小于16,则可以简单地将零字节添加到数组中(再次添加,因为它是小尾数),以确保BigInteger ctor将其视为正数。     ,我认为本文可以为您提供解决方案: 总而言之,如果最后一个字节的最高有效位是1,则将再增加一个字节到0。
Guid original = Guid.NewGuid();
byte[] bytes = original.ToByteArray();
if ((bytes[bytes.Length - 1] & 0x80) > 0) 
{
   byte[] temp = new byte[bytes.Length];
   Array.Copy(bytes,temp,bytes.Length);
   bytes = new byte[temp.Length + 1];
   Array.Copy(temp,bytes,temp.Length);
}

BigInteger guidPositive = new BigInteger(bytes);