什么';我的希尔密码怎么了?(Java Android)

什么';我的希尔密码怎么了?(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

我在javaandroid中实现hill密码算法时遇到了一些问题。它在某些条件下运行良好,但在其他条件下运行不足

这是跑步应用程序

1。在以下条件下运行正常

2。在以下情况下会出现意外结果

我只是想问题来自负面的结果。我用行列式和乘法逆来求矩阵逆

这是我的项目代码

MainActivity.java

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;
}