恢复凯撒密码后的原始单词

问题描述 投票:1回答:1

我写了凯撒密码书。

因此,当我转移一个句子之后,我也想移回原来的句子。现在,当我使用自然的正数转换时,它仅适用于一个方向,但是当我尝试使用负数进行转换时,它的值继续小于小于97的ascii小写字母。

我举个例子:

word: java
key = 10
output: tkfk

现在我想移回原处,将我的单词从tkfk恢复到Java。

key = -10
output: ja\a

代替v,而是放置\

我知道从ascii表到f到负10的原因是字母'\',我想要字母v。我想我需要操纵这条线,但我不知道如何,我有点受阻,我不知道该怎么办。

char ch = (char) (((int) text[index].charAt(i) + key-97) % 26+97)

我的方法:(有点长)

public static void MakeCipherText(String[] text, int key) {
     int index =0;

    if (key > 0) {
        if( text[index] == null || text[index].equals("")) {
            System.out.println("No sentences to fix capital letters.");
        } else {
            while(text[index] != null && !text[index].equals("")) { // only if we have sentence in array or array not contain empty sentence we go through loop
                String chiPstr = "";
                for(int i=0; i<text[index].length(); i++) {//we work in every itration on 1 sentence (1 index of str array)
                    if(Character.isLowerCase(text[index].charAt(i))) {//if we have lower letter than:
                        char ch = (char) (((int) text[index].charAt(i) + key-97) % 26+97); //we put asci value + Cipher value
                        chiPstr = chiPstr + ch; //each time we add to the new sentece the result 


                    } else if(Character.isUpperCase(text[index].charAt(i))) {//same thing like here, but its work on uppercase letters.

                        char ch = (char) (((int) text[index].charAt(i) + key-65) % 26+65);
                        chiPstr = chiPstr + ch;
                    }else {// if we have space, or other characters that is no a letter, we just put him as is in a sentence.
                        chiPstr = chiPstr + text[index].charAt(i);

                    }
                }
                text[index] = chiPstr;
                index ++; 
            }
        }

    } else { // key is negetive number
        if( text[index] == null || text[index].equals("")) {
            System.out.println("No sentences to fix capital letters.");
        } else {
            while(text[index] != null && !text[index].equals("")) { // only if we have sentence in array or array not contain empty sentence we go through loop
                String chiPstr = "";
                for(int i=0; i<text[index].length(); i++) {//we work in evry itration on 1 sentence (1 index of str array)
                    if(Character.isLowerCase(text[index].charAt(i))) {//if we have lower letter than:
                        char ch = (char) (((int) text[index].charAt(i) + key-97) % 26+97); //we put asci value + Cipher value
                        chiPstr = chiPstr + ch; //each time we add to the new sentece the result 

                    } else if(Character.isUpperCase(text[index].charAt(i))) {//same thing like here, but its work on uppercase letters.

                        char ch = (char) (((int) text[index].charAt(i) + key-65) % 26+65);
                        chiPstr = chiPstr + ch;
                    }else {// if we have space, or other characters that is no a letter, we just put him as is in a sentence.
                        chiPstr = chiPstr + text[index].charAt(i);

                    }
                }
                text[index] = chiPstr;
                index ++; 
            }
        }
    }
}

有任何建议吗?

java caesar-cipher
1个回答
3
投票

正如评论所建议,您应该再次检查代码,这也将有助于您成为一个更好的程序员。但是无论如何,您认为太复杂了。

如果检查您的else部分,则为if部分的精确副本。这也就不足为奇了。要对Caesar密码进行解码,您基本上可以使用正确的密钥再次对其进行编码。

例如:

如果使用A => B进行编码,或在此示例中使用1进行编码:

test--> uftu

那么我们如何解码uftu呢?当我们使用B => A或在这种情况下使用25进行移位时。

uftu --> test

因此,如果您需要输入-1,则需要解码之前用1编码的文本。

因此,基本上,我们必须找到一种方法来将-1映射到25-2映射到24,依此类推。

关键功能是:modulo

-2 % 26 => 24
-1 % 26 => 25
...

此外,您现在甚至可以输入大于26的数字,因为:

500 % 26 => 6
-500 % 26 => 20

并且因为2%26 => 2,您甚至不需要那个if子句。您的代码最后看起来像这样:

public static void MakeCipherText(String[] text, int key) {
    int index =0;
    key = (((key % 26) + 26) % 26); // See below for explanation of this weird modulo
    if( text[index] == null || text[index].equals("")) {
        System.out.println("No sentences to fix capital letters.");
    } else {
        while(text[index] != null && !text[index].equals("")) { // only if we have sentence in array or array not contain empty sentence we go through loop
            String chiPstr = "";
            for(int i=0; i<text[index].length(); i++) {//we work in every itration on 1 sentence (1 index of str array)
                if(Character.isLowerCase(text[index].charAt(i))) {//if we have lower letter than:
                    char ch = (char) (((int) text[index].charAt(i) + key-97) % 26+97); //we put asci value + Cipher value
                    chiPstr = chiPstr + ch; //each time we add to the new sentece the result


                } else if(Character.isUpperCase(text[index].charAt(i))) {//same thing like here, but its work on uppercase letters.

                    char ch = (char) (((int) text[index].charAt(i) + key-65) % 26+65);
                    chiPstr = chiPstr + ch;
                }else {// if we have space, or other characters that is no a letter, we just put him as is in a sentence.
                    chiPstr = chiPstr + text[index].charAt(i);

                }
            }
            text[index] = chiPstr;
            index ++;
        }
    }
}

永远不要忘记使用函数,不要使用重复的代码。错误的样式和容易出错。如果您仔细考虑,该解决方案将非常容易。

信息奇怪的模函数

您看到我使用了一个奇怪的模函数。因为在Java中%不计算模,而是计算余数。 (与Python不同)。因此,要在Java中获得“真”模数,我们必须使用以下奇怪的技巧:参考:What's the difference between “mod” and “remainder”?

key = (((key % 26) + 26) % 26); 
© www.soinside.com 2019 - 2024. All rights reserved.