用Java中的BigIntegers进行位移 [英] BitShifting with BigIntegers in Java

查看:947
本文介绍了用Java中的BigIntegers进行位移的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用BigIntegers在Java中实现DES加密。



我通过执行BigInteger.leftShift(int n)方法将Java BigIntegers左移二进制键。 N(Kn)的关键取决于Kn-1移位的结果。我得到的问题是,我在每个密钥生成后打印出结果,并且转移不是预期的。关键在2 Cn和Dn(左和右)分开。



我具体试图这样做:
要做左移,移动每个位于左边的一个位置,除了第一个位,循环到块的末尾。



似乎根据O的结果取决于调动,转移。



结果:



c0:11110101010100110011000011110



d0:11110001111001100110101010100



c1:111101010101001100110000111100



d1:111100011110011001101010101000



c2:11110101010100110011000011110000



d2:11110001111001100110101010100000



c3 :1111010101010011001100001111000000



d3:1111000111100110011010101010000000



c4:111101010101001100110000111100000000



d4:111100011110011001101010101000000000



c5:11110101010100110011000011110000000000



d5:11110001111001100110101010100000000000



c6:1111010101010011001100001111000000000000



d6:1111000111100110011010101010000000000000



c7:111101010101001100110000111100000000000000



d7:111100011110011001101010101000000000000000



c8:1111010101010011001100001111000000000000000



d8:1111000111100110011010101010000000000000000



c9 :111101010101001100110000111100000000000000000



d9:111100011110011001101010101000000000000000000



c10:11110101010100110011000011110000000000000000000



d10:11110001111001100110101010100000000000000000000



c11:1111010101010011001100001111000000000000000000000



d11:1111000111100110011010101010000000000000000000000



c12:111101010101001100110000111100000000000000000000000



d12:111100011110011001101010101000000000000000000000000



c13:11110101010100110011000011110000000000000000000000000



d13:11110001111001100110101010100000000000000000000000000



c14:1111010101010011001100001111000000000000000000000000000000



d14:111100011 11001100110101010100000000000000000000000000000000



c15:11110101010100110011000011110000000000000000000000000000



d15:11110001111001100110101010100000000000000000000000000000

解决方案

BigInteger实现无限精度整数,所以向左移动将不会向左添加零。您需要旋转:

  private static BigInteger rotateLeft(BigInteger bi){
BigInteger ret = bi.shiftLeft(1 );
if(ret.testBit(32)){
ret = ret.clearBit(32).setBit(0);
}
return ret;
}

对于32位数字来说这将是非常低效的,所以你可能只需使用原语来旋转DES的28位半部分。我不熟悉DES算法,所以我假设你需要BigInteger的其他东西。

  private static BigInteger rotateLeftPrimitive (BigInteger bi){
int value = bi.intValue();
返回BigInteger.valueOf(((value< 1)& 0xffffffe)|((value>>> 27)& 1));
}


I am implementing DES Encryption in Java with use of BigIntegers.

I am left shifting binary keys with Java BigIntegers by doing the BigInteger.leftShift(int n) method. Key of N (Kn) is dependent on the result of the shift of Kn-1. The problem I am getting is that I am printing out the results after each key is generated and the shifting is not the expected out put. The key is split in 2 Cn and Dn (left and right respectively).

I am specifically attempting this: "To do a left shift, move each bit one place to the left, except for the first bit, which is cycled to the end of the block. "

It seems to tack on O's on the end depending on the shift. Not sure how to go about correcting this.

Results:

c0: 11110101010100110011000011110

d0: 11110001111001100110101010100

c1: 111101010101001100110000111100

d1: 111100011110011001101010101000

c2: 11110101010100110011000011110000

d2: 11110001111001100110101010100000

c3: 1111010101010011001100001111000000

d3: 1111000111100110011010101010000000

c4: 111101010101001100110000111100000000

d4: 111100011110011001101010101000000000

c5: 11110101010100110011000011110000000000

d5: 11110001111001100110101010100000000000

c6: 1111010101010011001100001111000000000000

d6: 1111000111100110011010101010000000000000

c7: 111101010101001100110000111100000000000000

d7: 111100011110011001101010101000000000000000

c8: 1111010101010011001100001111000000000000000

d8: 1111000111100110011010101010000000000000000

c9: 111101010101001100110000111100000000000000000

d9: 111100011110011001101010101000000000000000000

c10: 11110101010100110011000011110000000000000000000

d10: 11110001111001100110101010100000000000000000000

c11: 1111010101010011001100001111000000000000000000000

d11: 1111000111100110011010101010000000000000000000000

c12: 111101010101001100110000111100000000000000000000000

d12: 111100011110011001101010101000000000000000000000000

c13: 11110101010100110011000011110000000000000000000000000

d13: 11110001111001100110101010100000000000000000000000000

c14: 1111010101010011001100001111000000000000000000000000000

d14: 1111000111100110011010101010000000000000000000000000000

c15: 11110101010100110011000011110000000000000000000000000000

d15: 11110001111001100110101010100000000000000000000000000000

解决方案

BigInteger implements infinite-precision integers, so shifting to the left will keep adding zeros to the left. You need a rotate:

private static BigInteger rotateLeft(BigInteger bi) {
    BigInteger ret = bi.shiftLeft(1);
    if (ret.testBit(32)) {
        ret = ret.clearBit(32).setBit(0);
    }
    return ret;
}

That's going to be rather inefficient for 32-bit numbers, so you might as well just use primitives to rotate DES' 28-bit halves. I'm not familiar with the DES algorithm, so I'll assume you need BigInteger for something else.

private static BigInteger rotateLeftPrimitive(BigInteger bi) {
    int value = bi.intValue();
    return BigInteger.valueOf(((value << 1) & 0xffffffe) | ((value >>> 27) & 1));
}

这篇关于用Java中的BigIntegers进行位移的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆