Java BigInteger 與C# BigInteger之間的問題

最近接到一個Java代碼轉C#代碼的項目。原本就兩個函數看起來很簡單的,後來折騰了一天,終於完美收官。html

碰到的第一個問題是:java的BigInteger構造函數裏面BigInteger(string,int),是字符串和進制數,.net的確是具體的整型,數字型的。java

後來發現有個函數BigInteger.Parse裏面可使用字符串類型的,就拿來直接使用。後來發現某一部分數據對,一部分數據不對。git

BigInteger.Parse(hexStr, NumberStyles.HexNumber)

這下傻逼了,網上找資料查詢,找到一篇地址:https://majing.io/posts/10000005661225github

原文說明以下:c#

在C#十六進制轉換爲十進制:

BigInteger number = BigInteger.Parse(hexString, NumberStyles.AllowHexSpecifier);
或者

BigInteger number = BigInteger.Parse(hexString, NumberStyles.HexNumber);
HexNumber是一個組合的NumberStyles,它是由AllowHexSpecifier,AllowLeadingWhite和AllowTrailingWhite組合而成,它容許字符串先後後空格。

使用BigInteger.Parse()轉換十六進制的字符串爲十進制的數字有兩個注意點:

十六進制的字符串不能以「0x」或者「&h」爲前綴
若是十六進制字符串的前兩位的數等於或者大於0x80,那麼Parse()方法會把第一位做爲符號位,即把它存儲爲負數。若是須要把此十六進制的字符串解析爲正數,須要在字符串前加上「0」。
示例

using System;
using System.Globalization;
using System.Numerics;

public class Example
{
  public static void Main()
  {
   string[] hexStrings = { "80", "E293", "F9A2FF", "FFFFFFFF", 
               "080", "0E293", "0F9A2FF", "0FFFFFFFF",  
               "0080", "00E293", "00F9A2FF", "00FFFFFFFF" };
   foreach (string hexString in hexStrings)
   {
     BigInteger number = BigInteger.Parse(hexString, NumberStyles.AllowHexSpecifier);
     Console.WriteLine("0x{0}:{1}.", hexString, number);
   }     
  }
}
輸出結果:

0x80:-128
0xE293:-7533
0xF9A2FF:-417025
0xFFFFFFFF:-1
0x080128
0x0E29358003
0x0F9A2FF16360191
0x0FFFFFFFF4294967295
0x0080128
0x00E29358003
0x00F9A2FF16360191
0x00FFFFFFFF4294967295

第二個問題是java的byte是有符號類型(java就沒有無符號類型的數據),值域:-128~127函數

而c#的byte是無符號類型數值,值域:0~255,在作BigInteger.ToByteArray()致使獲得的數據不一致。post

 使用&與運算 int num1=byte[0]&0xff 與運算一下。原理:0xff是十六進制整形(至少16位)在直接轉化爲整形時是255,至關於0x00ff,其二進制表達爲前面8個0,後面8個1.而咱們知道任何數值與1與還等於其自己。可是0xff是整形至少16個位,byte只擁有8個位,與0x00ff的與運算就至關於吧byte擴充成至少16位的整形。轉換天然就OK了。可是不能用0xffff。這是爲何呢?若是是正數,沒有什麼問題,其實與0xff與運算分爲兩步,第一個把byte真實擴充爲至少16位的整形,擴充的方式正數前用0填位,負數用1填位。所依負數就有問題了,由於java對於8位的負數(計算機系統負數表達形式用正數的補碼標示負數,即正數取反1變0,0變1,而後最後一位加1,這時候負數的第一位確定是1)擴展位數時時前面是用1填充的,其實就變成0xff[byte]。0xff只是後面8位是1,其實就等於0x00ff,前面是0.與運算以後把負數系統自動擴展的1去掉了,就是一個變成正數了,可是用0xffff,若是是16位的整形,與負數與運算,就會保持不變。若是是32爲的整形,就會變成一個更大的值0x0000ff[byte]。spa

引用地址:https://www.cnblogs.com/edzjx/archive/2012/09/16/2687419.html.net

可是目前碰到的狀況是不能變動java這邊的代碼。因此必須得想辦法解決c#的問題。後來想到c#有個sbye是有符號的,採用sbye[]替換bye[],轉換問題得以解決。code

第三個問題,是base64的問題。

 

未完待續。

github源碼地址

 參考1:https://www.codeproject.com/Articles/276993/Base-Encoding-on-a-GPU

參考2:http://www.java2s.com/Code/CSharp/Development-Class/TheBase64utilityclassperformsbase64encodinganddecoding.htm

相關文章
相關標籤/搜索