Polibius密码

  1. /// Encode an ASCII string into its location in a Polybius square.
  2. /// Only alphabetical characters are encoded.
  3. pub fn encode_ascii(string: &str) -> String {
  4. string
  5. .chars()
  6. .map(|c| match c {
  7. 'a' | 'A' => "11",
  8. 'b' | 'B' => "12",
  9. 'c' | 'C' => "13",
  10. 'd' | 'D' => "14",
  11. 'e' | 'E' => "15",
  12. 'f' | 'F' => "21",
  13. 'g' | 'G' => "22",
  14. 'h' | 'H' => "23",
  15. 'i' | 'I' | 'j' | 'J' => "24",
  16. 'k' | 'K' => "25",
  17. 'l' | 'L' => "31",
  18. 'm' | 'M' => "32",
  19. 'n' | 'N' => "33",
  20. 'o' | 'O' => "34",
  21. 'p' | 'P' => "35",
  22. 'q' | 'Q' => "41",
  23. 'r' | 'R' => "42",
  24. 's' | 'S' => "43",
  25. 't' | 'T' => "44",
  26. 'u' | 'U' => "45",
  27. 'v' | 'V' => "51",
  28. 'w' | 'W' => "52",
  29. 'x' | 'X' => "53",
  30. 'y' | 'Y' => "54",
  31. 'z' | 'Z' => "55",
  32. _ => "",
  33. })
  34. .collect()
  35. }
  36. /// Decode a string of ints into their corresponding
  37. /// letters in a Polybius square.
  38. ///
  39. /// Any invalid characters, or whitespace will be ignored.
  40. pub fn decode_ascii(string: &str) -> String {
  41. string
  42. .chars()
  43. .filter(|c| !c.is_whitespace())
  44. .collect::<String>()
  45. .as_bytes()
  46. .chunks(2)
  47. .map(|s| match std::str::from_utf8(s) {
  48. Ok(v) => v.parse::<i32>().unwrap_or(0),
  49. Err(_) => 0,
  50. })
  51. .map(|i| match i {
  52. 11 => 'A',
  53. 12 => 'B',
  54. 13 => 'C',
  55. 14 => 'D',
  56. 15 => 'E',
  57. 21 => 'F',
  58. 22 => 'G',
  59. 23 => 'H',
  60. 24 => 'I',
  61. 25 => 'K',
  62. 31 => 'L',
  63. 32 => 'M',
  64. 33 => 'N',
  65. 34 => 'O',
  66. 35 => 'P',
  67. 41 => 'Q',
  68. 42 => 'R',
  69. 43 => 'S',
  70. 44 => 'T',
  71. 45 => 'U',
  72. 51 => 'V',
  73. 52 => 'W',
  74. 53 => 'X',
  75. 54 => 'Y',
  76. 55 => 'Z',
  77. _ => ' ',
  78. })
  79. .collect::<String>()
  80. .replace(" ", "")
  81. }
  82. #[cfg(test)]
  83. mod tests {
  84. use super::{decode_ascii, encode_ascii};
  85. #[test]
  86. fn encode_empty() {
  87. assert_eq!(encode_ascii(""), "");
  88. }
  89. #[test]
  90. fn encode_valid_string() {
  91. assert_eq!(encode_ascii("This is a test"), "4423244324431144154344");
  92. }
  93. #[test]
  94. fn encode_emoji() {
  95. assert_eq!(encode_ascii("🙂"), "");
  96. }
  97. #[test]
  98. fn decode_empty() {
  99. assert_eq!(decode_ascii(""), "");
  100. }
  101. #[test]
  102. fn decode_valid_string() {
  103. assert_eq!(
  104. decode_ascii("44 23 24 43 24 43 11 44 15 43 44 "),
  105. "THISISATEST"
  106. );
  107. }
  108. #[test]
  109. fn decode_emoji() {
  110. assert_eq!(decode_ascii("🙂"), "");
  111. }
  112. #[test]
  113. fn decode_string_with_whitespace() {
  114. assert_eq!(
  115. decode_ascii("44\n23\t\r24\r\n43 2443\n 11 \t 44\r \r15 \n43 44"),
  116. "THISISATEST"
  117. );
  118. }
  119. #[test]
  120. fn decode_unknown_string() {
  121. assert_eq!(decode_ascii("94 63 64 83 64 48 77 00 05 47 48 "), "");
  122. }
  123. #[test]
  124. fn decode_odd_length() {
  125. assert_eq!(decode_ascii("11 22 33 4"), "AGN");
  126. }
  127. #[test]
  128. fn encode_and_decode() {
  129. let string = "Do you ever wonder why we're here?";
  130. let encode = encode_ascii(string);
  131. assert_eq!(
  132. "1434543445155115425234331415425223545215421523154215",
  133. encode,
  134. );
  135. assert_eq!("DOYOUEVERWONDERWHYWEREHERE", decode_ascii(&encode));
  136. }
  137. }