最近接到一個Java代碼轉C#代碼的項目。本來就兩個函數看起來很簡單的,後來折騰了一天,終於完美收官。
碰到的第一個問題是:java的BigInteger構造函數裏面BigInteger(string,int),是字符串和進制數,.net的確是具體的整型,數字型的。
後來發現有個函數BigInteger.Parse裏面可以使用字符串類型的,就拿來直接使用。後來發現某一部分數據對,一部分數據不對。
BigInteger.Parse(hexStr, NumberStyles.HexNumber)
這下傻逼了,網上找資料查詢,找到一篇地址:https://majing.io/posts/10000005661225
原文說明如下:
在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 0x080:128 0x0E293:58003 0x0F9A2FF:16360191 0x0FFFFFFFF:4294967295 0x0080:128 0x00E293:58003 0x00F9A2FF:16360191 0x00FFFFFFFF:4294967295
第二個問題是java的byte是有符號類型(java就沒有無符號類型的數據),值域:-128~127
而c#的byte是無符號類型數值,值域:0~255,在做BigInteger.ToByteArray()導致得到的數據不一致。
使用&與運算 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]。
引用地址:https://www.cnblogs.com/edzjx/archive/2012/09/16/2687419.html
但是目前碰到的情況是不能變更java這邊的代碼。所以必須得想辦法解決c#的問題。後來想到c#有個sbye是有符號的,採用sbye[]替換bye[],轉換問題得以解決。
第三個問題,是base64的問題。
未完待續。
參考1:https://www.codeproject.com/Articles/276993/Base-Encoding-on-a-GPU
參考2:http://www.java2s.com/Code/CSharp/Development-Class/TheBase64utilityclassperformsbase64encodinganddecoding.htm