package rsaa;
import java.io.*;
import java.math.BigInteger;
import java.util.ArrayList;
public class RSA{
private long p=0;
private long q=0;
private long n = 0;
private long m = 0;
private long public_key = 0; //公匙
private long private_key = 0; //密匙
private String text ; //明文
private long secretword=0 ; //密文
private long word = 0; //解密後明文
public boolean prime(long a)//判斷是否是素數
{
long b=0;
b=(long) Math.sqrt((double) a);
int c,i;
c=0;
for(i=2;i<b;i++)
{if(a%i==0)
{
c=1;
break;
}
}
if(c==1)
return false;
else
return true;
}
public void bigprimeRandom() {//產生隨機的大素數
do{
p = (long) (Math.random() * 1000000);
}while(!this.prime(p));
do{
q=(long)(Math.random()*1000000);
}while(p==q||!this.prime(q));
}
public void pq()throws Exception{ //P Q的生成
this.bigprimeRandom();
System.out.println("自動生成的p,q分別爲:"+this.p+" "+this.q);
this.n=(long)p*q;
this.m=(long)(p-1)*(q-1);
System.out.println("p*q=" + this.n);
System.out.println("m=(p-1)(q-1)=" + this.m);
}
public long gys(long a ,long b) //求最大公約數
{
long c;
if(b==0)
c=a;
else
c=gys(b,a%b);
return c;
}
public void getPublic_key()throws Exception {//生成公鑰
do {
this.public_key=(long)(Math.random()*100000);
} while ((this.public_key >= this.m) ||
(this.gys(this.m, this.public_key) != 1));
System.out.println("生成的公鑰爲:" + this.public_key);
}
public void getPrivate_key() {//得到祕鑰
int i;
long a = 1;
for ( i = 1; ; i++) {
a = i * this.m + 1;
if ( a%this.public_key== 0 &&a/this.public_key<this.m) {
this.private_key = a / this.public_key;
break;
}
}
System.out.println("產生的密鑰爲:" + this.private_key);
}
public void getText() throws Exception//輸入明文
{
System.out.println("請輸入明文:");
BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
text = stdin.readLine();
}
public long jm(long y, long n, long key) {//加密
BigInteger yy=new BigInteger(String.valueOf(y));//將long變成字符型的
BigInteger nn=new BigInteger(String.valueOf(n));
BigInteger kkey=new BigInteger(String.valueOf(key));
return Long.parseLong(yy.modPow(kkey,nn).toString());//modpow()計算y^e mod n的函數
}
public void jmjm() throws Exception { //加密,解密
this.getText();
System.out.println("輸入明文爲: " + this.text);
ArrayList cestr=new ArrayList(); //動態數組
for (int i = 0; i < text.length(); i++) {//一個字符爲一組
this.secretword = this.jm( (long)text.charAt(i), this.n,this.public_key);
cestr.add(secretword);//將對象加在結尾處
}
System.out.println("加密後所得的密文爲:" +cestr);
//解密
StringBuffer destr=new StringBuffer();
for(int j=0;j<cestr.size();j++) {
this.word = this.jm(Long.parseLong(cestr.get(j).toString()), this.n, this.private_key);
destr.append((char)word);//在被選元素的結尾插入指定內容
}
System.out.println("解密後所得的明文爲:" +destr);
}
public static void main(String[] args) {
try {
int i;
for(i=0;i<10;i++){
RSA t = new RSA();
t.pq();
t.getPublic_key();
t.getPrivate_key();
t.jmjm();
}
}catch(Exception ex) {
System.out.println(ex.getMessage());
}
}
}