[英]Java BigInteger Out of memory, possibly from long conversion
我正在嘗試將此KeeLoq算法從C轉換為Java,但是我的解密方法似乎為Java的BigInteger使用了過多的內存。 我想知道是否存在與Java的BigInteger一起使用的等效操作。
index和bitVal變量的原始計算在下面注釋。
我用作示例的原始源代碼可以在這里找到: https : //github.com/franksmicro/Arduino/blob/master/libraries/Keeloq/Keeloq.cpp
任何幫助將非常感激。
package keeloq;
/**
*
* @author
*/
import java.math.BigInteger;
public class KeeLoq {
BigInteger _keyHigh, _keyLow, keyHigh, keyLow;
int KeeLoq_code = 0x3A5C742E;
BigInteger KeeLoq_NLF = new BigInteger(Integer.toString(KeeLoq_code));
public KeeLoq() {
}
public KeeLoq(BigInteger keyHigh, BigInteger keyLow) {
_keyHigh = keyHigh;
_keyLow = keyLow;
}
public BigInteger bitRead(BigInteger x, int n) {
BigInteger temp = x.shiftRight(n);
return temp;
}
public BigInteger multiplyBig(BigInteger x, BigInteger n) {
BigInteger temp = x.multiply(n);
return temp;
}
public BigInteger Encrypt(BigInteger data) {
BigInteger x = data;
int keyBitNo;
long index;
long position1, position2, position3, position4, position5;
BigInteger keyBitVal, bitVal;
BigInteger b1, b2, b3, b4, b5;
for (int r = 0; r < 528; r++) {
keyBitNo = r & 63;
if (keyBitNo < 32) {
keyBitVal = bitRead(_keyLow, keyBitNo);
} else {
keyBitVal = bitRead(_keyHigh, keyBitNo - 32);
}
position1 = bitRead(x, 1).longValue() * 1;
position2 = bitRead(x, 9).longValue() * 2;
position3 = bitRead(x, 20).longValue() * 4;
position4 = bitRead(x, 26).longValue() * 8;
position5 = bitRead(x, 31).longValue() * 16;
index = position1 + position2 + position3 + position4 + position5;
System.out.println("the encrypted index is " + index);
b1 = bitRead(x, 0);
b2 = bitRead(x, 16);
int intIndex = (int) index;
b3 = bitRead(KeeLoq_NLF, intIndex);
b4 = keyBitVal;
bitVal = b1.xor(b2).xor(b3).xor(b4);
BigInteger tempx = x.shiftRight(1);
x = tempx.xor(bitVal);
//bitVal = bitRead(x,0) ^ bitRead(x, 16) ^ bitRead(KeeLoq_NLF,index) ^ keyBitVal;
//x = (x>>1) ^ bitVal<<31;
}
return x;
}
BigInteger Decrypt(BigInteger data) {
BigInteger x = data;
int keyBitNo;
long index;
long position1, position2, position3, position4, position5;
BigInteger keyBitVal, bitVal;
BigInteger b1, b2, b3, b4, b5;
for (int r = 0; r < 528; r++) {
keyBitNo = (15 - r) & 63;
if (keyBitNo < 32) {
keyBitVal = bitRead(_keyLow, keyBitNo);
} else {
keyBitVal = bitRead(_keyHigh, keyBitNo - 32);
}
position1 = bitRead(x, 0).longValue() * 1;
position2 = bitRead(x, 8).longValue() * 2;
position3 = bitRead(x, 19).longValue() * 4;
position4 = bitRead(x, 25).longValue() * 8;
position5 = bitRead(x, 30).longValue() * 16;
index = position1 + position2 + position3 + position4 + position5;
System.out.println("The Decrypted index is " + index);
b1 = bitRead(x, 31);
b2 = bitRead(x, 15);
int intIndex = (int) index;
b3 = bitRead(KeeLoq_NLF, intIndex);
b4 = keyBitVal;
bitVal = b1.xor(b2).xor(b3).xor(b4);
BigInteger tempx = x.shiftLeft(1);
x = tempx.xor(bitVal);
//index = 1 * bitRead(x,0) + 2 * bitRead(x,8) + 4 * bitRead(x,19) + 8 * bitRead(x,25) + 16 * bitRead(x,30);
// bitVal = bitRead(x,31) ^ bitRead(x, 15) ^ bitRead(KeeLoq_NLF,index) ^ keyBitVal;
// x = (x<<1) ^ bitVal;
}
return x;
}
public static void main(String[] args) {
BigInteger highKey = new BigInteger(Integer.toString(66));
BigInteger lowKey = new BigInteger(Integer.toString(35));
KeeLoq KeeLoq_file = new KeeLoq(highKey, lowKey);
System.out.println("The KeeLoq Code is " + KeeLoq_file.KeeLoq_code);
BigInteger EncryptedBigInt = KeeLoq_file.Encrypt(KeeLoq_file.KeeLoq_NLF);
System.out.println("The Encrypted BigIntegerValue is " + EncryptedBigInt);
System.out.println("The Encrypted integer value is " + EncryptedBigInt.intValue());
BigInteger DecryptedBigInt = KeeLoq_file.Decrypt(EncryptedBigInt);
System.out.println("The Decrypted BigIntegerValue is " + DecryptedBigInt);
System.out.println("The Decrypted integer value is " + DecryptedBigInt.intValue());
}
}
編輯:我想我明白了! (或至少一部分)
問題至少部分在此行中:(首先錯了一行,對不起)
int intIndex = (int) index;
當index
足夠大時, (int) index
將溢出到較大的負值。 猜猜當您將其傳遞給bitRead()
時會發生什么?
現在,為什么這種溢出發生在Decrypt()
而不是Encrypt()
,我不確定...等更多的休息后再看,但希望這是一個開始。
您可以通過使用-Xmx標志運行程序來增加可用的內存空間。 例如,要以最大4 GB的內存運行,您可以使用-Xmx4G
在Eclipse中,可以通過右鍵單擊文件進行設置,方法是轉到“屬性”->“運行/調試設置”->單擊啟動配置->“編輯”->“參數”選項卡->“ VM參數”->輸入標志。
如果Java的BigInteger
類用盡了內存,我不確定如果數字真的那么大,那么使用任何其他任意精度庫會使您走得很遠。
您在bitRead函數中有一個錯誤:這是arduino的文檔:
語法bitRead(x,n)
參數x:要讀取的數字
n:要讀取的位,從最低有效(最右邊)位的0開始
返回該位的值(0或1)。
您的函數將返回較大的值,例如3824712。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.