我有两个空数组和一些变量:
static int p = 41;
static int q = 67;
static int d = 83;
static int n = p * q;
static int[] encryptedBlocks = new int[charArray.length];
static int[] decryptedArray = new int[charArray.length];
其中第一个填充了以下内容(我已经检查过,确实如此):
1573
1978
385
1092
1022
857
856
1387
225
606
2293
1339
1630
第二个数组我试图在for循环中填充方程的结果:
for (int i = 0; i < encryptedBlocks.length; i++) {
int M = (int)Math.pow(encryptedBlocks[i], d) % n;
decryptedArray[i] = M;
}
问题是我为每次迭代得到了M
的相同结果。我对于发生了什么完全无能为力:
2662
2662
2662
2662
2662
2662
2662
2662
2662
2662
2662
2662
2662
以防万一我检查encryptedBlocks[i]
确实是每次迭代的下一个值,它就是。我遗漏了与使用int
和Math.pow()
相关的内容吗?
encryptedBlocks[i]
,d
和n
的前两个迭代值:
1573 83 2747
1978 83 2747
答案 0 :(得分:2)
在您的代码行中
int M = (int)Math.pow(encryptedBlocks[i], d) % n;
您正在计算Math.pow(encryptedBlocks [i],d),然后将其转换为int,然后在int结果上使用modulo m。您可能想要做的只是在完成所有数学运算后才转换为int:
int M = (int) (Math.pow(encryptedBlocks[i], d) % n);
产生:
1147
2564
1457
2351
2414
982
1073
2480
923
1526
704
427
235
用于给定的输入数据。
答案 1 :(得分:2)
如上所述here:
转换优先于除法运算
因此,正如我在评论中提到的,你必须替换它:
int M = (int)Math.pow(encryptedBlocks[i], d) % n;
有了这个:
int M = (int)(Math.pow(encryptedBlocks[i], d) % n);
答案 2 :(得分:1)
只是优先级错误
将此int M = (int)Math.pow(encryptedBlocks[i], d) % n;
更改为int M = (int)(Math.pow(encryptedBlocks[i], d) % n);
答案 3 :(得分:1)
是的,你正在向早期转换为int,这导致输出始终相同。您可以在下面的输出中查看。
package test;
public class MathPow {
static int p = 41;
static int q = 67;
static int d = 83;
static int n = p * q;
static int[] encryptedBlocks = {1573,
1978,
385,
1092,
1022,
857,
856,
1387,
225,
606,
2293,
1339,
1630};
static int[] decryptedArray = new int[13];
public static void main (String []args){
for (int i = 0; i < encryptedBlocks.length; i++) {
double power = Math.pow(encryptedBlocks[i], d);
System.out.println("Power : "+power);
double pwer = power % n;
int M = (int)pwer;
decryptedArray[i] = M;
System.out.println("M : "+M);
}
}
}
在最后完成转换为int时的输出。
Power : 2.1305119658955046E265
M : 1147
Power : 3.8617294369074443E273
M : 2564
Power : 3.9195891716526933E214
M : 1457
Power : 1.4875753889539146E252
M : 2351
Power : 6.087295034019223E249
M : 2414
Power : 2.7378409793777127E243
M : 982
Power : 2.4849775423187883E243
M : 1073
Power : 6.199351610800489E260
M : 2480
Power : 1.702742606656262E195
M : 923
Power : 8.815111415893474E230
M : 1526
Power : 8.194765730142982E278
M : 704
Power : 3.332636081546012E259
M : 427
Power : 4.0885674380373943E266
M : 235
在Math.pow操作之后完成转换时输出。
Power : 2.147483647E9
M : 2662
Power : 2.147483647E9
M : 2662
Power : 2.147483647E9
M : 2662
Power : 2.147483647E9
M : 2662
Power : 2.147483647E9
M : 2662
Power : 2.147483647E9
M : 2662
Power : 2.147483647E9
M : 2662
Power : 2.147483647E9
M : 2662
Power : 2.147483647E9
M : 2662
Power : 2.147483647E9
M : 2662
Power : 2.147483647E9
M : 2662
Power : 2.147483647E9
M : 2662
Power : 2.147483647E9
M : 2662
您可以看到功率运算结果相同,因此M也相同。
答案 4 :(得分:1)
电源操作的结果太大而无法存储在整数中。仅1573 ^ 83
是一个122位数字,你在计算功率后正在进行mod操作,因此它已经溢出。
如果不考虑性能,可以使用BigInteger类。这应该有效:
BigInteger bigN = BigInteger.valueOf(n);
for (int i = 0; i < encryptedBlocks.length; i++) {
BigInteger M = BigInteger.valueOf(encryptedBlocks[i]).pow(d).mod( bigN );
decryptedArray[i] = Integer.valueOf(M.toString());
}
for(int i : decryptedArray) System.out.println(i);
但是,BigInteger
操作有点慢。如果您更喜欢更快的解决方案,您可以实现自己的电源功能,这样您就可以在接近溢出整数值时执行mod操作。
答案 5 :(得分:1)
您的问题在括号中。这就是编译器看到你写的内容的方式:
((int) Math.pow(encryptedBlocks[i], d)) % n
这是微妙的,但是在采用模数之前,它正在向int
施放。通常情况下,这不会产生任何影响,但在您的情况下,Math.pow
返回如此大的数字,将其转换为int
将其截断为2147483647
int可以存储的最大值,然后它将返回将返回2662
的模块。
现在,要获得正确答案,我们需要做的就是确保它首先计算模数:
(int) (Math.pow(encryptedBlocks[i], d) % n)