fork download
  1. import java.util.*;
  2.  
  3. public class Main {
  4. public static void main(String[] args) {
  5. int[] ciphertext = {
  6. 102, 141, 142, 161, 148, 131, 158, 157, 120, 131,
  7. 126, 153, 130, 143, 154, 135, 118, 137, 148, 111,
  8. 116, 145, 134, 133, 118, 103, 136, 107, 138, 127,
  9. 102, 131, 194, 99, 114, 200, 202, 127, 120, 105,
  10. 126, 202, 108, 194, 198, 214, 222, 204, 116, 224,
  11. 194, 198, 202, 230, 166, 222, 216, 234, 232, 210,
  12. 222, 220, 210, 230, 194, 230, 198, 210, 210, 230,
  13. 234, 218, 222, 204, 194, 216, 216, 224, 216, 194,
  14. 210, 220, 232, 202, 240, 232, 198, 208, 194, 228, 230
  15. };
  16.  
  17. List<String> possibleSolutions = decryptAll(ciphertext);
  18.  
  19. System.out.println("\nTop possible solutions:");
  20. for (String solution : possibleSolutions) {
  21. System.out.println(solution);
  22. }
  23. }
  24.  
  25. public static List<String> decryptAll(int[] ct) {
  26. int length = ct.length;
  27. List<String> solutions = new ArrayList<>();
  28. Map<Integer, String> keyToText = new HashMap<>();
  29.  
  30. System.out.println("Testing all possible keys...");
  31.  
  32. for (int initialKey = length/2; initialKey <= length; initialKey++) {
  33. StringBuilder plaintext = new StringBuilder();
  34. boolean valid = true;
  35. int currentKey = initialKey;
  36.  
  37. for (int encrypted : ct) {
  38. boolean found = false;
  39. // Try all ASCII characters (0-255)
  40. for (int c = 0; c <= 255; c++) {
  41. if (c + (c % currentKey) == encrypted) {
  42. plaintext.append((char)c);
  43. found = true;
  44. break;
  45. }
  46. }
  47.  
  48. if (!found) {
  49. valid = false;
  50. break;
  51. }
  52.  
  53. currentKey++;
  54. }
  55.  
  56. if (valid) {
  57. String solution = plaintext.toString();
  58. solutions.add(solution);
  59. keyToText.put(initialKey, solution);
  60. }
  61. }
  62.  
  63. // Score solutions by English-like characteristics
  64. solutions.sort((a, b) -> {
  65. int scoreA = englishScore(a);
  66. int scoreB = englishScore(b);
  67. return Integer.compare(scoreB, scoreA);
  68. });
  69.  
  70. return solutions.subList(0, Math.min(5, solutions.size()));
  71. }
  72.  
  73. private static int englishScore(String text) {
  74. int score = 0;
  75. String commonLetters = "etaoinshrdlu ETAOINSHRDLU";
  76.  
  77. for (char c : text.toCharArray()) {
  78. if (commonLetters.indexOf(c) >= 0) score += 2;
  79. else if (c >= 32 && c <= 126) score += 1;
  80. if (Character.isLetterOrDigit(c) )score += 1;
  81. }
  82.  
  83. return score;
  84. }
  85. }
Success #stdin #stdout 0.18s 55868KB
stdin
Standard input is empty
stdout
Testing all possible keys...

Top possible solutions:
3hismess<g?sAoMl;nJb:tCo;aDdEo3rac9des<i?e6ackof:pacesSolutionisasciisumofallplaintextchars
3ghrldrr<f?rAnMk;mJa:sCn;`DcEn3q‘b9Ǘr<h?e6ack¦f:pacesSolutionisasciisumofallplaintextchars
3fgqkcqq<e?qAmsj;lJ`:rCm;_DbEm3pa9Ŗq<g?e6acÖ¥f:ßaceæSolutionisasciisumofallplaintextchars
3efpjbpp<d?pAlri;kJ_:qCl;^DaEl3o`9Õp<f?Ê6acÔ¤f:ÝaceäSolêtionisasciisumofallplaintextchars
3deoiaoo<c?oAkqh;jJ^:pCk;]D`Ek3nŽ_9Á”o<e?È6acÒ£f:ÛaceâSolè®ionisasciisumofallplaintextchars