最近接到一个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 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()致使获得的数据不一致。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的问题。
未完待续。
参考1:https://www.codeproject.com/Articles/276993/Base-Encoding-on-a-GPU
参考2:http://www.java2s.com/Code/CSharp/Development-Class/TheBase64utilityclassperformsbase64encodinganddecoding.htm