什么';我的希尔密码怎么了?(Java Android)
我在javaandroid中实现hill密码算法时遇到了一些问题。它在某些条件下运行良好,但在其他条件下运行不足 这是跑步应用程序 1。在以下条件下运行正常 2。在以下情况下会出现意外结果 我只是想问题来自负面的结果。我用行列式和乘法逆来求矩阵逆 这是我的项目代码 MainActivity.java什么';我的希尔密码怎么了?(Java Android),java,android,cryptography,Java,Android,Cryptography,我在javaandroid中实现hill密码算法时遇到了一些问题。它在某些条件下运行良好,但在其他条件下运行不足 这是跑步应用程序 1。在以下条件下运行正常 2。在以下情况下会出现意外结果 我只是想问题来自负面的结果。我用行列式和乘法逆来求矩阵逆 这是我的项目代码 MainActivity.java package com.andri.hilltest; import java.util.Arrays; import android.os.Bundle; import android.a
package com.andri.hilltest;
import java.util.Arrays;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends Activity implements OnClickListener {
EditText txtPlain, txtKey, txtCipher, txtDecrypt;
Button btnEncrypt, btnCheck, btnDecrypt;
String char_db = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 ?!.,";
//String char_db = "ABCDEFGHIJKLMNOPQRSTUVWXYZabc";
int[] array_angka, array_angka2;
int[] array_angka_cipher, array_angka_decrypted;
int[][] M_key = new int[2][2];
int[][] M_inverse = new int [2][2];
int i;
String key_input, ciphertext, plaintext;
int db_length = char_db.length();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
txtPlain = (EditText) findViewById(R.id.txtPlain);
txtKey = (EditText) findViewById(R.id.txtKey);
txtCipher = (EditText) findViewById(R.id.txtCipher);
txtDecrypt = (EditText) findViewById(R.id.txtDecrypt);
btnEncrypt = (Button) findViewById(R.id.btnEncrypt);
btnDecrypt = (Button) findViewById(R.id.btnDecrypt);
btnCheck = (Button) findViewById(R.id.btnCheck);
btnEncrypt.setOnClickListener(this);
btnCheck.setOnClickListener(this);
btnDecrypt.setOnClickListener(this);
}
@Override
public void onClick(View v) {
if(v == btnEncrypt){
String plainTextInput = txtPlain.getText().toString();
char[] array_huruf = plainTextInput.toCharArray();
if(array_huruf.length%2!=0)
array_angka = new int[array_huruf.length+1];
else
array_angka = new int[array_huruf.length];
for (i=0 ; i < array_huruf.length ; i++){
int posisi_huruf = char_db.indexOf(array_huruf[i]);
//Toast.makeText(this, "Tombol ditekan " + posisi_huruf , Toast.LENGTH_SHORT).show();
array_angka[i] = posisi_huruf; //if I disable this line the code should run well
}
//jika panjang array ganjil letakkan spasi diakhir array
if(array_huruf.length % 2 != 0 ){
array_angka[array_huruf.length] = 62;
}
array_angka_cipher = new int[array_angka.length];
array_angka_cipher = encrypt_hill(M_key, array_angka);
ciphertext = to_char(array_angka_cipher);
txtCipher.setText(Arrays.toString(array_angka) +"\n\n" + Arrays.toString(array_angka_cipher) + "\n\n" + to_char(array_angka_cipher) );
}
else if (v == btnCheck){
key_input = txtKey.getText().toString();
if (key_input.length() < 4)
Toast.makeText(this, "panjang kunci harus 4 karakter!" , Toast.LENGTH_SHORT).show();
else{
check_kunci(key_input);
}
}
else if(v == btnDecrypt){
char[] array_cipher = ciphertext.toCharArray();
array_angka2 = new int[array_cipher.length];
for (i=0 ; i < array_cipher.length ; i++){
int posisi_huruf = char_db.indexOf(array_cipher[i]);
array_angka2[i] = posisi_huruf;
}
array_angka_decrypted = new int[array_cipher.length];
array_angka_decrypted = decrypt_hill(M_inverse, array_angka2);
plaintext = to_char(array_angka_decrypted);
txtDecrypt.setText(Arrays.toString(array_angka2) + "\n\n" + Arrays.toString(array_angka_decrypted) + "\n\n" + plaintext);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public void check_kunci(String kunci){
Toast.makeText(this, kunci , Toast.LENGTH_SHORT).show();
char[] array_kunci = kunci.toCharArray();
int j = 0;
while ( j < array_kunci.length){
//masukkan masing-masing nilai ke matriks kunci
for (int x=0; x < 2; x++){
for (int y=0; y<2; y++){
M_key[x][y] = char_db.indexOf(array_kunci[j]);
j = j+1;
}
}
}
Toast.makeText(this, "hello " + M_key[0][0] + " " + M_key[0][1] + " " + M_key[1][0] + " " + M_key[1][1] , Toast.LENGTH_SHORT).show();
int det = determinant(M_key);
Toast.makeText(this, " determinant = " + det , Toast.LENGTH_SHORT).show();
if (det == 0){
Toast.makeText(this, "Kunci invalid karena determinant = 0" , Toast.LENGTH_SHORT).show();
} else if (det%67==0){
Toast.makeText(this, "Kunci invalid karena determinan memiliki persamaan faktor dgn 67" , Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "Kunci Valid, multiplication inverse " + mi(det) , Toast.LENGTH_SHORT).show();
M_inverse = getInverse(M_key, mi(det));
Toast.makeText(this, "Inverse berhasil" + M_inverse[0][0] + " " + M_inverse[0][1] + " " + M_inverse[1][0] + " " + M_inverse[1][1] , Toast.LENGTH_SHORT).show();
String tampil_banding = M_key[0][0] + " " + M_key[0][1] + " " + M_key[1][0] + " " + M_key[1][1] +"\n\n" + M_inverse[0][0] + " " + M_inverse[0][1] + " " + M_inverse[1][0] + " " + M_inverse[1][1];
txtCipher.setText(tampil_banding);
}
}
public int[] encrypt_hill(int[][] key, int[] p){
int str_length;
str_length = txtPlain.length();
if(str_length%2!=0)
str_length = str_length+1;
int[] c = new int[str_length];
int i = 0;
int zz = 0;
for (int b=0; b< str_length/2 ; b++){
for(int j=0; j<2; j++){
for(int x=0; x<2 ; x++){
c[i] += key[j][x]*p[x+zz];
}
i++;
}
zz += 2;
}
return c;
}
private String to_char(int[] num_cipher){
int[] mod_result = new int[num_cipher.length];
char[] parse_cipher = new char[num_cipher.length];
for(int i=0;i<num_cipher.length;i++){
mod_result[i] = Math.abs(num_cipher[i]%67);
parse_cipher[i] = char_db.charAt(mod_result[i]);
}
String cipher_result = new String(parse_cipher);
return cipher_result;
}
public int determinant(int[][] A){
int res;
res = A[0][0]*A[1][1] - A[1][0]*A[0][1];
return res;
}
public int[][] getInverse(int key[][], int mi){
int[][] key_inv = new int[2][2];
key_inv[0][0] = ((key[1][1]*mi)%67);
key_inv[0][1] = (((-1*key[0][1])*mi)%67);
key_inv[1][0] = (((-1*key[1][0])*mi)%67);
key_inv[1][1] = ((key[0][0]*mi)%67);
return key_inv;
}
public int mi(int d)
{
int q,r1,r2,r,t1,t2,t;
r1=67;
r2=d;
t1=0;
t2=1;
while(r1!=1&&r2!=0)
{
q=r1/r2;
r=r1%r2;
t=t1-(t2*q);
r1=r2;
r2=r;
t1=t2;
t2=t;
}
return (t1+t2);
}
public int[] decrypt_hill(int[][] key_invers, int[] p){
int str_length;
str_length = txtPlain.length();
if(str_length%2!=0)
str_length = str_length+1;
int[] c = new int[str_length];
int i = 0;
int zz = 0;
for (int b=0; b< str_length/2 ; b++){
for(int j=0; j<2; j++){
for(int x=0; x<2 ; x++){
c[i] += key_invers[j][x]*p[x+zz];
}
i++;
}
zz += 2;
}
return c;
}
package com.andri.hilltest;
导入java.util.array;
导入android.os.Bundle;
导入android.app.Activity;
导入android.view.Menu;
导入android.view.view;
导入android.view.view.OnClickListener;
导入android.widget.Button;
导入android.widget.EditText;
导入android.widget.Toast;
公共类MainActivity扩展活动实现OnClickListener{
EditText txtPlain、txtKey、txtCipher、txtDecrypt;
按钮Btnecrypt、btnCheck、Btnecrypt;
字符串char_db=“abcdefghijklmnopqrstuvxyzabcdefghijklmnopqrstuvxyzo123456789?!,”;
//字符串char_db=“abcdefghijklmnopqrstuvxyzabc”;
int[]数组_angka,数组_angka2;
int[]数组加密,数组解密;
int[]M_key=新int[2][2];
int[]M_逆=新的int[2][2];
int i;
字符串键输入,密文,明文;
int db_length=char_db.length();
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
txtplane=(EditText)findViewById(R.id.txtplane);
txtKey=(EditText)findViewById(R.id.txtKey);
txtCipher=(EditText)findViewById(R.id.txtCipher);
txtdefcrypt=(EditText)findViewById(R.id.txtdefcrypt);
btnEncrypt=(按钮)findviewbyd(R.id.btnEncrypt);
btnDecrypt=(按钮)findViewById(R.id.btnDecrypt);
btnCheck=(按钮)findViewById(R.id.btnCheck);
btnEncrypt.setOnClickListener(此);
btnCheck.setOnClickListener(此);
btnDecrypt.setOnClickListener(这个);
}
@凌驾
公共void onClick(视图v){
if(v==BtneCrypt){
字符串plainTextInput=txtplane.getText().toString();
char[]数组_huruf=plainTextInput.toCharArray();
if(数组长度%2!=0)
array_angka=newint[array_huruf.length+1];
其他的
array_angka=newint[array_huruf.length];
对于(i=0;i
并非所有矩阵都有逆矩阵(参见可逆矩阵)。当且仅当矩阵的行列式不为零且与模基没有任何公因子时,矩阵才会有一个逆矩阵。因此,如果我们如上所述使用模26,则行列式必须为非零,且不能被2或13整除。如果行列式为0,或与模基有公因子,则矩阵不能用于希尔密码,必须选择另一个矩阵(否则将无法解密)。幸运的是,满足希尔密码中使用条件的矩阵相当常见
“abay”不是希尔密码的有效密钥
很抱歉没有仔细阅读您的代码
尝试改变
mod_result[i] = Math.abs(num_cipher[i]%67);
到
或
mod_result[i]=num_cipher[i]%67;
if(mod_result[i]谢谢你的回答,伙计。但是在这种情况下,我不是在研究模26,我使用了67个字符,因为我们知道它是一个素数。它是否具有相同的条件?或者你能告诉我它一定不能被什么数字整除才能成为一个有效的键。。。
mod_result[i] = (((num_cipher[i]%67) + 67)%67);
mod_result[i] = num_cipher[i]%67;
if(mod_result[i] <0){
mod_result[i] += 67;
}