1

これは私がまったく頭に入らない宿題の質問です

非常に単純な暗号化アルゴリズムです。アルファベットとして文字列から始めます。

ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!, .

次に、次のように機能する独自の文字列を入力するようにユーザーに依頼しますmap

0987654321! .,POIUYTREWQASDFGHJKLMNBVCXZ

次に、プログラムはこれを使用して を作成し、map暗号化されるテキストを入力できるようにします。

たとえば、次のMY NAME IS JOSEPHように暗号化されます.AX,0.6X2YX1PY6O3

.AX,0.6X2YX1PY6O3これはすべて非常に簡単ですが、彼はそれが 1 対 1 のマッピングであり、プログラムに戻ると抜け出すことを暗示していると述べました。MY NAME IS JOSEPH

.AX,0.6X2YX1PY6O3になるので、これは起こりませんZ0QCDZQGAQFOALDH

マッピングは、逆方向に行ったときに復号化するためにのみ機能しますが、問題は、プログラムがループして毎回 1 つのアルゴリズムを実行することを意味します。

可能性があると言う人がいたとしても、私は幸せになるだろう、可能性のある仕組みでいっぱいの紙のページがありますが、何も思いつきませんでした。アルゴリズムを逆方向に実行する唯一の解決策はありません。それをすることを許可しました。

何か案は?

編集:

残念ながら、これを機能させることはできません (軌道計算のアイデアを使用) 何が間違っていますか?

//import scanner class
import java.util.Scanner;

public class Encryption {

    static Scanner inputString = new Scanner(System.in);
    //define alphabet
    private static String alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!, .";
    private static String map;
    private static int[] encryptionMap = new int[40];//mapping int array
    private static boolean exit = false;
    private static boolean valid = true;

    public static void main(String[] args) {

        String encrypt, userInput;
        userInput = new String();

        System.out.println("This program takes a large reordered string");
        System.out.println("and uses it to encrypt your data");
        System.out.println("Please enter a mapping string of 40 length and the same characters as below but in different order:");
        System.out.println(alpha);

        //getMap();//don't get user input for map, for testing!
        map=".ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!, ";//forced input for testing only!
        do{
            if (valid == true){
                System.out.println("Enter Q to quit, otherwise enter a string:");
                userInput = getInput();
                if (userInput.charAt(0) != 'Q' ){//&& userInput.length()<2){

                    encrypt = encrypt(userInput);
                    for (int x=0; x<39; x++){//here I am trying to get the orbit computation going
                        encrypt = encrypt(encrypt);
                    }
                    System.out.println("You entered: "+userInput);
                    System.out.println("Encrypted Version: "+encrypt);
                }else if (userInput.charAt(0) == 'Q'){//&& userInput.length()<2){
                    exit = true;
                }

            }
            else if (valid == false){
                System.out.println("Error, your string for mapping is incorrect");
                valid = true;//reset condition to repeat
            }
        }while(exit == false);
        System.out.println("Good bye");
    }

    static String encrypt(String userInput){
        //use mapping array to encypt data
        String encrypt;
        StringBuffer tmp = new StringBuffer();
        char current;
        int alphaPosition;
        int temp;


        //run through the user string
        for (int x=0; x<userInput.length(); x++){
            //get character
            current = userInput.charAt(x);


            //get location of current character in alphabet
            alphaPosition = alpha.indexOf(current);
            //encryptionMap.charAt(alphaPosition)

            tmp.append(map.charAt(alphaPosition));

        }
        encrypt = tmp.toString();
        return(encrypt);
    }

    static void getMap(){
        //get a mapping string and validate from the user
        map = getInput();
        //validate code
        if (map.length() != 40){
            valid = false;
        }
        else{
            for (int x=0; x<40; x++){
                if (map.indexOf(alpha.charAt(x)) == -1){
                    valid = false;
                }
            }
        }
        if (valid == true){
            for (int x=0; x<40; x++){
                int a = (int)(alpha.charAt(x));
                int y = (int)( map.charAt(x));
                //create encryption map
                encryptionMap[x]=(a-y);
            }
        }
    }

    static String getInput(){
        //get input(this repeats)
        String input = inputString.nextLine();
        input = input.toUpperCase();
        if ("QUIT".equals(input) || "END".equals(input) || "NO".equals(input) || "N".equals(input)){
            StringBuffer tmp = new StringBuffer();
            tmp.append('Q');
            input = tmp.toString();
        }
        return(input);
    }




}
4

2 に答える 2

2

その置換を再度適用しても、(おそらく) 元の文字列は返されません。おそらく、そのような入力を作成できるからです (それらはすべて、A->B の後に B->A の場合のように動作します)。しかし、ほとんどの入力はそうしません。復号化するには、リバース マップを作成する必要があります。

ただし、前にしか進めない場合にできるトリックがあります。マッピングを適用し続けると、最終的に元の入力に戻ります。これを行う必要がある回数は、入力内容によって異なります。回数を計算するには、各文字の軌道を計算し、すべての軌道サイズの最小公倍数を取ります。入力の場合、軌道のサイズは 1 (T->T、W->W)、2 (B->9->B H->3->H U->R->U P->O->P )、4 (C->8->N->、->C)、9 (A->...->Y->A)、および 17 (E->...->V->E) )。これらすべての LCM は 612 であるため、暗号文に適用される 611 フォワード マッピングは平文に戻ります。

于 2012-09-16T07:45:06.963 に答える
0

逆マッピングを行う場合にのみ、この方法で文字列を戻すことができます。1 対 1 のマッピングとは、デフォルトのアルファベットの 1 文字が新しいアルファベットの 1 文字のみにマッピングされることを意味し、その逆も同様です。ABCDつまり、にマップできませんABBA。2 回目の暗号化を行うことで最初の文字列を取得できるという意味ではありません。

有限のアルファベットと変位を使用して文字列をエンコードすると、説明したことが実現できます。totalDisplacement mod alphabetSize == 0暗号化を何回か繰り返した後、前方にのみ文字列が返されるように、変位を選択できます。

于 2012-09-16T06:50:37.317 に答える