使用BigInteger进行大数运算

文章介绍了在Java中使用BigInteger进行大数运算时常见的两个问题:字节数组转换和16进制转换。使用newBigInteger(1,byte[])构造函数能正确处理字节数组的正负号,而将大数转换为16进制串时,可能需要先转为字节数组以确保偶数字节。
摘要由CSDN通过智能技术生成

        BigInteger是Java程序员在密码学中进行大数运算基础工具,使用过程中经常出现的错误是正负数问题和16进制转换问题。具体来说就是:

        一)大数最高位为1的情况下,字节数组与BigInteger的转换问题

        以以下例子说明,比如:

        byte[] data new byte[1];

        data[0] = (byte)0xC7

        使用new BigInteger(byte[] data)方法把byte数组转换为BigInteger,并不处理符号,最高位是1时做负数处理:

        BigInteger bi = new BigInteger(data);

        //以下输出为-39

        System.out.println(bi.toString(16));  /

        //以下输出为xw==。也就是0xC7的base64编码        

        System.out.println(Base64.getEncoder().encodeToString(bi.toByteArray())); 

        为了解决以上问题,需要使用new BigInteger(int sign, byte[] data)进行转换,针对最高位为1的情况,会自动进行补0处理。

        BigInteger bi = new BigInteger(1,data);

        //以下输出为C7,也就是说转换成16进制串时,会自动去除表示正数的00

        System.out.println(bi.toString(16));  

        //以下输出为AMc=。也就是0x00C7的base64编码        

        System.out.println(Base64.getEncoder().encodeToString(bi.toByteArray())); 

         所以,从字节数组转换为BigInteger时,使用BigInteger第二个构造函数,并且sign=1。

        二)BigInteger与16进制数转换

        使用BigInteger(String data, 16),可以把16进制数转换为大数,并且自动处理最高位为1的情况。比如:

        String data = "C7";

        //以下输出为C7,自动在最高位补0,处理正负数。
        System.out.println(new BigInteger(data, 16).toString(16));

        //以下代码可以验证是否做了补0处理。输出仍为AMc=

        System.out.println(Base64.getEncoder().encodeToString(new BigInteger(data, 16).toByteArray()));
 

        BigInteger.toString(16),可以把大数转换为16进制串。使用该转换存在一个问题,就是并不做偶数位对齐,比如:

        String data = "07";

        //以下输出为7

       System.out.println(new BigInteger(data, 16).toString(16));

       一般国密算法中的二进制串都是偶数字节的,所以如果出现奇数字节的二进制数,使用BigInteger就会出现很多错误。为了保证输出的是偶数字节,就需要使用toByteArray方法,比如:

        //以下输出为Bw==,也就是07的base64编码

        System.out.println(Base64.getEncoder().encodeToString(new BigInteger(data, 16).toByteArray()));

        综合以上常见问题,在使用BigInteger进行大数运算时注意以下两点:

        1)从字节数组转换为大数时,要使用双参的构造函数,并且设置符号参数sign为1

        2)从大数转换成16进制数时,先转换为字节数组,然后再从中剔除高位的补0。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值