class Calculate
{
double gcd(double a, double b)
{
if (b == 0)
{
return a;
}
return gcd(b, a % b);
}
Calculate()
{
Scanner sc = new Scanner(System.in);
System.out.print("Enter values of p : ");
double p = sc.nextDouble();
System.out.print("\nEnter value of q : ");
double q = sc.nextDouble();
System.out.print("\nEnter Message: ");
double m = sc.nextDouble(); // message
double n = p * q;
System.out.println("n = " + n); // first part of the public key
double phi = (p - 1) * (q - 1);
System.out.println("phi = " + phi);
// assuming e = 3
double e = 3; // second part of the public key
// e must be relatively prime and smaller than phi
while (e < phi)
{
if (gcd(e, phi) == 1)
{
break;
}
else
{
e++;
}
}
// to find d
// method : (k * phi + 1) / e = quotient should be 0 ( perfectly divisible)
double k = 1;
double d;
while (true)
{
double temp = 1 + (k * phi);
if (temp % e == 0)
{
d = temp / e;
break;
}
else
{
k++;
}
}
System.out.println("d = " + d);
// encryption
double c = 0; // cypher text
double x = Math.pow(m, e);
c = x % n;
System.out.println("Encrypted Data: " + c);
// decryption
BigDecimal pt; // plain text
double y = Math.pow(c, d);
BigDecimal Y = BigDecimal.valueOf(y);
BigDecimal N = BigDecimal.valueOf(n);
pt = Y.remainder(N);
System.out.println("Decrypted Data: " + pt);
}
}
p = 11
q = 5
m = 9
手工计算得出的值:
n = 55
phi = 40
d = 27
加密文本= 14.0
这些是正确的值。
但是即使公式正确,我的解密值也仍然错误。
解密的文本= 25.0 //错误的值。应该是9。
首先,我认为double在计算纯文本时不足以表示较大的值。
所以我用了BigDecimal(我是新手)
用于计算解密文本的公式是正确的。我不明白程序有什么问题。
答案 0 :(得分:0)
我认为您忘记做.mod(N)而不是.remainder()。
// decryption
BigInteger N = BigDecimal.valueOf(n).toBigInteger();
//converting double value of c to BigInteger
BigInteger C = BigDecimal.valueOf(c).toBigInteger();
int dint = (int) Math.round(d);
BigInteger msgback = (C.pow(dint)).mod(N);
System.out.println("Decrypted Data: " + msgback);
这是一个稍作修改的版本,我将double d转换为整数,因此可以调用pow。祝你好运!