BifidCipherDecode.mjs 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. /**
  2. * @author Matt C [matt@artemisbot.uk]
  3. * @copyright Crown Copyright 2018
  4. * @license Apache-2.0
  5. */
  6. import Operation from "../Operation.mjs";
  7. import { genPolybiusSquare } from "../lib/Ciphers.mjs";
  8. import OperationError from "../errors/OperationError.mjs";
  9. /**
  10. * Bifid Cipher Decode operation
  11. */
  12. class BifidCipherDecode extends Operation {
  13. /**
  14. * BifidCipherDecode constructor
  15. */
  16. constructor() {
  17. super();
  18. this.name = "Bifid Cipher Decode";
  19. this.module = "Ciphers";
  20. this.description = "The Bifid cipher is a cipher which uses a Polybius square in conjunction with transposition, which can be fairly difficult to decipher without knowing the alphabet keyword.";
  21. this.infoURL = "https://wikipedia.org/wiki/Bifid_cipher";
  22. this.inputType = "string";
  23. this.outputType = "string";
  24. this.args = [
  25. {
  26. "name": "Keyword",
  27. "type": "string",
  28. "value": ""
  29. }
  30. ];
  31. }
  32. /**
  33. * @param {string} input
  34. * @param {Object[]} args
  35. * @returns {string}
  36. *
  37. * @throws {OperationError} if invalid key
  38. */
  39. run(input, args) {
  40. const keywordStr = args[0].toUpperCase().replace("J", "I"),
  41. keyword = keywordStr.split("").unique(),
  42. alpha = "ABCDEFGHIKLMNOPQRSTUVWXYZ",
  43. structure = [];
  44. let output = "",
  45. count = 0,
  46. trans = "";
  47. if (!/^[A-Z]+$/.test(keywordStr) && keyword.length > 0)
  48. throw new OperationError("The key must consist only of letters in the English alphabet");
  49. const polybius = genPolybiusSquare(keywordStr);
  50. input.replace("J", "I").split("").forEach((letter) => {
  51. const alpInd = alpha.split("").indexOf(letter.toLocaleUpperCase()) >= 0;
  52. let polInd;
  53. if (alpInd) {
  54. for (let i = 0; i < 5; i++) {
  55. polInd = polybius[i].indexOf(letter.toLocaleUpperCase());
  56. if (polInd >= 0) {
  57. trans += `${i}${polInd}`;
  58. }
  59. }
  60. if (alpha.split("").indexOf(letter) >= 0) {
  61. structure.push(true);
  62. } else if (alpInd) {
  63. structure.push(false);
  64. }
  65. } else {
  66. structure.push(letter);
  67. }
  68. });
  69. structure.forEach(pos => {
  70. if (typeof pos === "boolean") {
  71. const coords = [trans[count], trans[count+trans.length/2]];
  72. output += pos ?
  73. polybius[coords[0]][coords[1]] :
  74. polybius[coords[0]][coords[1]].toLocaleLowerCase();
  75. count++;
  76. } else {
  77. output += pos;
  78. }
  79. });
  80. return output;
  81. }
  82. /**
  83. * Highlight Bifid Cipher Decode
  84. *
  85. * @param {Object[]} pos
  86. * @param {number} pos[].start
  87. * @param {number} pos[].end
  88. * @param {Object[]} args
  89. * @returns {Object[]} pos
  90. */
  91. highlight(pos, args) {
  92. return pos;
  93. }
  94. /**
  95. * Highlight Bifid Cipher Decode in reverse
  96. *
  97. * @param {Object[]} pos
  98. * @param {number} pos[].start
  99. * @param {number} pos[].end
  100. * @param {Object[]} args
  101. * @returns {Object[]} pos
  102. */
  103. highlightReverse(pos, args) {
  104. return pos;
  105. }
  106. }
  107. export default BifidCipherDecode;