简单的家庭作业加密算法。没有让解密工作正常

时间:2012-09-16 06:41:44

标签: algorithm encryption

这是一个家庭作业问题,我根本无法理解

它是一种非常简单的加密算法。你可以从一串字符开始作为你的字母:

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




}

2 个答案:

答案 0 :(得分:2)

如果再次应用该替换,您(可能)将不会返回原始字符串。我之所以说可能是因为你可以构建这样的输入(它们都可以做,比如A-> B然后是B-> A)。但大多数投入都不会这样做。你必须构造反向映射来解密。

然而,如果你只允许前进,你可以做一些技巧。继续应用映射,您最终将返回到原始输入。您必须执行此操作的次数取决于您的输入。要弄清楚多少次,计算每个角色的orbit,并采用所有轨道大小的最小公倍数。对于您的输入,轨道的大小为1(T-> T,W-> W),2(B-> 9-> B H-> 3-> H-> R-> U P-> O-> P),4(C-> 8-> N-,-> C),9(A-> - > Y-> A )和17(E-> - > V-> E)。所有这些的LCM是612,因此应用于密文的611个正向映射将返回到明文。

答案 1 :(得分:0)

嗯,只有在进行反向映射时,才能以这种方式恢复字符串。一对一映射意味着您的默认字母表中的单个字母仅映射到新字母表中的一个字母,反之亦然。即您无法将ABCD映射到ABBA。这并不意味着您可以通过第二轮加密来获取初始字符串。

如果您使用有限字母和位移来编码字符串,则可以实现您所描述的内容。你可以选择一个位移,以便在经过多轮加密totalDisplacement mod alphabetSize == 0之后,你的字符串只会向前移动。