2016-11-02 40 views
0

下面的代码是为了加密和解密消息输入当。当我对数据进行加密和解密时,它有时会起作用,而在其他时候则不起作用。以下是我遇到的问题的一个例子。在输出结束看似随机字符使用扫描仪

加密

Encryption

解密

Decryption

正如你所看到的,当我尝试解密,我的程序终止,一些乱码输出到控制台。我的代码有什么问题?

我不能确定提这会有所帮助,但我有Eclipse的文件的编码设置为UTF-8。

请原谅任何代码很差。我仍然是Java的初学者,我为此感到困惑。

import java.util.Scanner; 

public class Transcrypt { 

    static String mode = "", 
        msg, 
        key; 

    public static void main(String[] args) { 
     Scanner input = new Scanner(System.in); 

     while (!mode.equals("e") && !mode.equals("d")) { // Ask for mode until equal to "e" or "d" 
      System.out.print("Encrypt or decrypt? (e/d) "); 
      mode = input.nextLine().toLowerCase(); 
     } 

     System.out.print("Message: "); // Ask for message 
     msg = input.nextLine(); 

     System.out.print("Passkey: "); // Ask for key 
     key = input.nextLine(); 

     input.close(); 

     System.out.println(transcrypt(msg, key, mode.equals("d"))); // Transcrypt and output 
    } 

    public static String transcrypt(String msg, String key, boolean decode) { 
     String result = ""; 

     for (int i=0; i<msg.length(); i++) { 
      // Add or subtract Unicode index of key.charAt(i % key.length()) and/from msg.msg.charAt(i) and convert back to character 
      result += (char) ((int) msg.charAt(i) + ((int) key.charAt(i % key.length())) * (decode ? -1 : 1)); 
     } 

     return result; 
    } 

} 
+3

似乎是某种形式的终端问题。在终端中使用二进制字符不一定是个好主意。您可以将您的二进制字符串编码/解码为base64或hex,但要解决控制台问题。 –

+0

或者,传统的(16世纪)Vigenere只加密字母并在字母表中环绕:X + A = Y,X + B = Z,X + C = A,X + D = B。经常需要处理一些空格和非空格,比如在模糊的时候在单词之间使用X,并用单词STOP QUERY ONE TWO TH等替代。另外注意,如果用于任何重要长度的真文本,Vigenere很容易被破坏;请参阅维基百科。 –

回答

1

你的编码信息是这样的"¼ÊßàãÊãæÑ×",但实际上,它是"¼Êßàã\u0085ÊãæÑ×\u0095"

最值得注意的是,它包含了控制字符0x85在两者之间具有“新线”的语义。所以复制该字符串时,你复制它的控制字符并粘贴到在你的应用程序的信息查询控制台时,你基本上进入¼Êßàã的消息,通过“新线”控制字符犯下的输入,造成随后的密码查询消耗尾随的ÊãæÑ×字符。

Passkey:输出之后看到的垃圾,是您尝试使用该密钥ÊãæÑ×解码¼Êßàã的结果,因为是在控制台的缓冲区已经字符都没有使用新行此时进入。

通常,正如NándorElődFekete在this comment中所说的那样,您不应该将字符写入控制台,它们实际上是二进制数据,例如编码字符串。


顺便说一句,你不应该变量声明为static字段实际上是当地的一种方法,即你main方法。此外,在进行计算时,您不需要将char转换为intchar值已经是int值的子集。