Euler059:如何从解密的可能性中选择有效的消息?

时间:2019-01-15 05:07:34

标签: java

我正在经历Euler项目Problem 059
如何从that textfile的解密可能性中找到有效消息?

将输入转换为数组后,使用三个字母的键执行XOR并将结果强制转换(char),所有消息都无法通过isLegible检查。

    try {
        // Read the contents of the provided text file
        // and convert them into an int[] array of encrypted ASCII codes
        Scanner fileRead = new Scanner(new File("p059_cipher.txt"));
        StringBuilder input = new StringBuilder();
        while (fileRead.hasNext()) {
            input.append(fileRead.next());
        }
        String[] parts = input.toString().split("[,]");
        int[] elements = new int[parts.length];
        for (int i = 0; i < parts.length; i++)
            elements[i] = Integer.parseInt(parts[i]);

        char[] key;
        char[] convertedParts;

        // Loop through possible keys,
        // from ['a', 'a', 'a'] to ['z', 'z', 'z']
        for (char lc1 = 'a'; lc1 <= 'z'; lc1++) {
            for (char lc2 = 'a'; lc2 <= 'z'; lc2++) {
                for (char lc3 = 'a'; lc3 <= 'z'; lc3++) {
                    key = new char[]{lc1, lc2, lc3};

                    // XOR each of the ASCII code chars,
                    // using the appropriate key letter
                    convertedParts = new char[elements.length];
                    for (int done = 0; done < elements.length; done++) {
                        convertedParts[done] =
                                (char) (elements[done] ^ key[done%3]);
                    }

                    // If the decrypted message counts as an answer,
                    // print out the sum of ASCII values
                    // of decrypted characters
                    if (isLegible(convertedParts))
                        System.out.println(getAsciiSum(convertedParts));
                }
            }
        }
    } catch (java.io.FileNotFoundException e) {
        e.printStackTrace();
    }
}
// Check whether or not the decoded message
// consists only of valid characters
private static boolean isLegible(char[] characters) {
    // 32-34: SPACE, '!', '"'
    // 40-41: '(', ')'
    // 44-46: '.', '-', ','
    // 48-59: '0'-'9', ':', ';'
    // 63: '?'
    // 65-90: 'A'-'Z'
    for (char character : characters) {
        int value = (int) character;
        if ( ! ( (value >= 32 && value <= 34)
                || (value >= 40 && value <= 41)
                || (value >= 44 && value <= 46)
                || (value >= 48 && value <= 59)
                || (value == 63)
                || (value >= 65 && value <= 90) ) ) {
            return false;
        }
    }
    return true;
}
// Sums up the ASCII values of characters
private static long getAsciiSum(char[] characters) {
    long sum = 0;
    for (char character : characters)
        sum += (int)(character);
    return sum;
}

我希望输出内容清晰易懂,但在循环进行解密时找不到任何内容。

0 个答案:

没有答案