2015-09-19 126 views
0

我想要解密某个文本。当我遇到字符串中的一个字母时,我想用字母表中的下一个字母替换它。然后在接下来的一轮中,我希望替换下一个字母。用其他字符替换字符

甲 - >乙

的k - >升

然后在第二轮所以应尽量

一个 - >ç

的k - >米

问题带字符的是它包含各种奇怪的字符,当你遇到az并试图替换它时,它会被一个奇怪的符号替代。

任何人都可以帮我从A-Z制作某种循环列表?在下面的代码片段中,我创建了一个包含a到z的列表。在循环中,一个字符被选中,索引被搜索和“调整”,新字符应该被恢复。但它不起作用。 (一个原因列表是不是圆形)

public static void decipher(){ 
    String cyphertext = "aVaqrprzoreoeratraWhyvhfraJnygreUbyynaqreqrgjrroebrefinaRqvguZnetbganneNzfgreqnzNaarjvytenntzrrxbzraznnezbrgabtrrarragvwqwrovwbznoyvwiraBznmnyurgzbrvyvwxuroorabzNaarabtrracnnejrxraqnnegrubhqrafpuevwsgRqvguSenaxvarraoevrsnnaTregehqAnhznaauhaiebrtrerohhezrvfwrvaSenaxshegnzZnva"; 
    char[] plaintext = new char[cyphertext.length()]; 

    List<Character> a2z = new ArrayList<Character>(26); 
    for (char c = 'A'; c <= 'Z'; c++){ 
     a2z.add(Character.valueOf(c)); 
    } 

    for(int i = 1; i < 26; i++){ 
     for(int j = 0; j < cyphertext.length(); j++){ 
      char currentChar = cyphertext.charAt(j); 
      int newCharIndex = a2z.indexOf(currentChar)+i; 
      plaintext[j] = a2z.get(newCharIndex); 
     } 
    } 
} 

回答

0

您不需要循环列表来处理边缘情况。此外,您应该记住,字符A-Z的ascii值介于65-90和a-z之间97-122。您可以创建两个圆形的名单,但不是在需要的时候,因为边缘的情况下很容易处理:

public static void main(String[] args) { 
    String cyphertext = "aVaqrprzoreoeratraWhyvhfraJnygreUbyynaqreqrgjrroebrefinaRqvguZnetbganneNzfgreqnzNaarjvytenntzrrxbzraznnezbrgabtrrarragvwqwrovwbznoyvwiraBznmnyurgzbrvyvwxuroorabzNaarabtrracnnejrxraqnnegrubhqrafpuevwsgRqvguSenaxvarraoevrsnnaTregehqAnhznaauhaiebrtrerohhezrvfwrvaSenaxshegnzZnva"; 
    char[] plaintext = new char[cyphertext.length()]; 

    // first shift 
    shiftLetters(cyphertext, plaintext, 1); 
    // update cyphertext with the intermediate result 
    cyphertext = new String(plaintext); 
    // second shift 
    shiftLetters(cyphertext, plaintext, 2); 
    // print result 
    System.out.println(new String(plaintext)); 

} 

private static void shiftLetters(String cyphertext, char[] plaintext, int shifts) { 
    for (int i=0; i<cyphertext.length(); i++){ 
     int tmp = cyphertext.charAt(i) + shifts; 
     tmp = handleEdgeCases(tmp); 
     plaintext[i] = (char)(tmp); 
    } 
} 

// here we handle the "circular" cases 
private static int handleEdgeCases(int tmp) { 
    if (tmp > 90 && tmp < 97) { 
     tmp = tmp - 90 + 65; 
    } else if (tmp > 122) { 
     tmp = tmp - 122 + 97; 
    } 
    return tmp; 
} 
+0

但是,如果您将资本V转移了12次,那么它的价值会从86转移到98,然后程序认为它是小写b。 – Nils

+0

插件/编辑:(使用循环时)但其余的工作。 – Nils

+0

另一个小小的增加,我认为-90 + 65导致-25应该是-26。否则:一个ascii值为122,用1移动的'z'变为123.然后在边缘方法中,减去25得到98,即'b'。但它需要成为'a'。 – Nils

0

的问题是在这里:

int newCharIndex = a2z.indexOf(currentChar)+i; 
plaintext[j] = a2z.get(newCharIndex); 

这里的解码字符0 25之间和ASCII的AZ去从65到90你要移到该指数在a2z的范围从A到Z:

plaintext[j] = a2z.get(newCharIndex) + 'A'; 
+0

我不知道,如果是这种情况,因为的indexOf(A)应该返回0 ,那么+我把它作为例子1,然后得到(1)应该返回一个B作为一个新的字符,它的作用。问题是当v移到z之外。 – Nils

1

如果我理解你的权利,你想要的替代密码,以用N升档字母,从包装0到A,做大写和小写字母,并保持所有其他字符不变。

E.g.如果N是2:

a → c b → d ... x → z y → a z → b 
A → C B → D ... X → Z Y → A Z → B 

是这样的?

char[] text = "aVaqrprzoreoeratraWhyvhfraJnygreUbyynaqreqrgjrroebrefinaRqvguZnetbganneNzfgreqnzNaarjvytenntzrrxbzraznnezbrgabtrrarragvwqwrovwbznoyvwiraBznmnyurgzbrvyvwxuroorabzNaarabtrracnnejrxraqnnegrubhqrafpuevwsgRqvguSenaxvarraoevrsnnaTregehqAnhznaauhaiebrtrerohhezrvfwrvaSenaxshegnzZnva".toCharArray(); 
for (int n = 1; n < 26; n++) { 
    for (int i = 0; i < text.length; i++) { 
     char c = text[i]; 
     if (c >= 'A' && c <= 'Z') 
      text[i] = (char)('A' + (c - 'A' + n) % 26); 
     else if (c >= 'a' && c <= 'z') 
      text[i] = (char)('a' + (c - 'a' + n) % 26); 
    } 
} 
System.out.println(new String(text)); 

输出

nIndecemberbrengenJuliusenWalterHollanderdetweebroersvanEdithMargotnaarAmsterdamAnnewilgraagmeekomenmaarmoetnogeeneentijdjebijomablijvenOmazalhetmoeilijkhebbenomAnnenogeenpaarwekendaartehoudenschrijftEdithFrankineenbriefaanGertrudNaumannhunvroegerebuurmeisjeinFrankfurtamMain 

当然,你认识到,通过1移位,然后通过2,然后通过3,...并最终通过26,是相同的如同移动一次(1 + 2 + 3 + ... + 26),即351和351 % 26 = 13

而由13移位意味着编码和解码是相同的操作。


说明

如果通过26移位,你移位恰好一个完整的圆,即a → a b → b ...,以免移这是相同的,因此,任何的N换挡> = 26是与N%26相同,例如N = 28N = 2相同。

移位由1 a → b然后通过2 b → d然后通过3 d → g,是与由1 + 2 + 3 = 6 a → g移位。因此,移动1 + 2 + ... + 26 = 351与移位351%相同26 = 13.

如果变量c是大写字母(AZ),那么c - 'A'是0和25.添加一个6的例子,你得到一个数字6-31。 26(% 26)做其余为您提供了6-25,0-5然后+ 'A'给你G-Z,A-F,这意味着A → G B → H ... Y → E Z → F,每个信6.

同为小写字母移位。

+0

我想我会想移动1,然后按2等来打印所有的中间结果。所以要检查实际输出的结果是否合理。我真的不明白为什么移位(351)26的总和等于所使用的移位量。 – Nils

+0

我也没有真正获得if if语句中的部分。 – Nils

相关问题