1

这是一个我完全无法理解的家庭作业问题

它是一个非常简单的加密算法。您以一串字符作为字母表开始:

ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!, .

然后要求用户输入自己的字符串,map例如:

0987654321! .,POIUYTREWQASDFGHJKLMNBVCXZ

然后程序使用它来制作一个map并允许您输入被加密的文本。

例如MY NAME IS JOSEPH将被加密为.AX,0.6X2YX1PY6O3

这一切都很容易,但是他说这是一对一的映射,因此暗示如果我.AX,0.6X2YX1PY6O3重新进入程序,我就会退出MY NAME IS JOSEPH

这不会发生,因为.AX,0.6X2YX1PY6O3变成Z0QCDZQGAQFOALDH

该映射仅在您向后退时解密,但问题意味着程序每次都只是循环并运行一个算法。

即使有人会说我可能会很高兴,我有一页又一页的纸填满了可能的工作原理,但我什么也没想出来,唯一的解决方案是向后运行算法我不认为我们是允许这样做。

有任何想法吗?

编辑:

不幸的是我不能让它工作(使用轨道计算的想法)我做错了什么?

//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

好吧,只有在进行反向映射时,才能以这种方式取回字符串。一对一映射意味着默认字母表中的单个字母仅映射到新字母表中的一个字母,反之亦然。即你不能映射ABCDABBA. 这并不意味着您可以通过进行第二轮加密来获得初始字符串。

如果您使用有限的字母表和位移来编码您的字符串,则可以实现您所描述的事情。您可以选择位移,这样在经过多轮加密之后,totalDisplacement mod alphabetSize == 0您将只能向前返回字符串。

于 2012-09-16T06:50:37.317 回答