RailFenceCipherEncode.mjs 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. /**
  2. * @author Flavio Diez [flaviofdiez+cyberchef@gmail.com]
  3. * @copyright Crown Copyright 2020
  4. * @license Apache-2.0
  5. */
  6. import Operation from "../Operation.mjs";
  7. import OperationError from "../errors/OperationError.mjs";
  8. /**
  9. * Rail Fence Cipher Encode operation
  10. */
  11. class RailFenceCipherEncode extends Operation {
  12. /**
  13. * RailFenceCipherEncode constructor
  14. */
  15. constructor() {
  16. super();
  17. this.name = "Rail Fence Cipher Encode";
  18. this.module = "Ciphers";
  19. this.description = "Encodes Strings using the Rail fence Cipher provided a key and an offset";
  20. this.infoURL = "https://wikipedia.org/wiki/Rail_fence_cipher";
  21. this.inputType = "string";
  22. this.outputType = "string";
  23. this.args = [
  24. {
  25. name: "Key",
  26. type: "number",
  27. value: 2
  28. },
  29. {
  30. name: "Offset",
  31. type: "number",
  32. value: 0
  33. }
  34. ];
  35. }
  36. /**
  37. * @param {string} input
  38. * @param {Object[]} args
  39. * @returns {string}
  40. */
  41. run(input, args) {
  42. const [key, offset] = args;
  43. const plaintext = input;
  44. if (key < 2) {
  45. throw new OperationError("Key has to be bigger than 2");
  46. } else if (key > plaintext.length) {
  47. throw new OperationError("Key should be smaller than the plain text's length");
  48. }
  49. if (offset < 0) {
  50. throw new OperationError("Offset has to be a positive integer");
  51. }
  52. const cycle = (key - 1) * 2;
  53. const rows = new Array(key).fill("");
  54. for (let pos = 0; pos < plaintext.length; pos++) {
  55. const rowIdx = key - 1 - Math.abs(cycle / 2 - (pos + offset) % cycle);
  56. rows[rowIdx] += plaintext[pos];
  57. }
  58. return rows.join("").trim();
  59. }
  60. }
  61. export default RailFenceCipherEncode;