How do I make BigInteger see the binary representation of this Hex string correctly?

旧时模样 提交于 2019-12-23 03:05:29

问题


The problem

I have a byte[] that is converted to a hex string, and then that string is parsed like this BigInteger.Parse(thatString,NumberSyles.Hexnumber).

This seems wasteful since BigInteger is able to accept a byte[], as long as the two's complement is accounted for.


An working (inefficient) example

According to MSDN the most significant bit of the last byte should be zero in order for the following hex number be a positive one. The following is an example of a hex number that has this issue:

byte[] ripeHashNetwork = GetByteHash();
foreach (var item in ripeHashNetwork)
{
   Console.Write(item + "," );
} 

// Output:  
//      0,1,9,102,119,96,6,149,61,85,103,67,158,94,57,248,106,13,39,59,238,214,25,103,246

// Convert to Hex string using this http://stackoverflow.com/a/624379/328397
// Output: 
//       00010966776006953D5567439E5E39F86A0D273BEED61967F6` 

Okay, let's pass that string into the static method of BigInteger:

 BigInteger bi2 = BigInt.Parse(thatString,NumberSyles.Hexnumber);

// Output bi2.ToString() ==
//                {25420294593250030202636073700053352635053786165627414518}

Now that I have a baseline of data, and known conversions that work, I want to make it better/faster/etc.


A not working (efficient) example

Now my goal is to round-trip a byte[] into BigInt and make the result look like 25420294593250030202636073700053352635053786165627414518. Let's get started:

So according to MSDN I need a zero in my last byte to avoid my number from being seen as a two's compliment. I'll add the zero and print it out to be sure:

foreach (var item in ripeHashNetwork)
{
   Console.Write(item + "," );
} 

// Output:                            
//    0,1,9,102,119,96,6,149,61,85,103,67,158,94,57,248,106,13,39,59,238,214,25,103,246,0 

Okay, let's pass that byte[] into the constructor of BigInteger:

 BigInteger bi2 = new BigInteger(ripeHashNetwork);

// Output bi2.ToString() ==
//                {1546695054495833846267861247985902403343958296074401935327488}

What I skipped over is the sample of what bigInt does to my byte array if I don't add the trailing zero. What happens is that I get a negative number which is wrong. I'll post that if you want.

So what am I doing wrong?


回答1:


When you are going via the hex string, the first byte of your array is becoming the most significant byte of the resulting BigInteger.

When you are adding a trailing zero, the last bye of your array is the most significant.

I'm not sure which case is right for you, but that's why you're getting different answers.




回答2:


From MSDN "The individual bytes in the value array should be in little-endian order, from lowest-order byte to highest-order byte". So the mistake is the order of bytes:

BigInteger bi2 = new BigInteger(ripeHashNetwork.Reverse().ToArray<byte>());


来源:https://stackoverflow.com/questions/13938483/how-do-i-make-biginteger-see-the-binary-representation-of-this-hex-string-correc

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!