From 317215ab9d3a41689d78adb785bd1842f1e8d792 Mon Sep 17 00:00:00 2001 From: Flavio Diez Date: Tue, 28 Jan 2020 12:56:26 +0100 Subject: [PATCH] Implemented offset and added tests --- ...erDecode.mjs => RailFenceCipherDecode.mjs} | 63 +++++-------- ...erEncode.mjs => RailFenceCipherEncode.mjs} | 57 ++++-------- tests/operations/tests/Ciphers.mjs | 89 +++++++++++++++++-- 3 files changed, 123 insertions(+), 86 deletions(-) rename src/core/operations/{RailFenceCypherDecode.mjs => RailFenceCipherDecode.mjs} (50%) rename src/core/operations/{RailFenceCypherEncode.mjs => RailFenceCipherEncode.mjs} (50%) diff --git a/src/core/operations/RailFenceCypherDecode.mjs b/src/core/operations/RailFenceCipherDecode.mjs similarity index 50% rename from src/core/operations/RailFenceCypherDecode.mjs rename to src/core/operations/RailFenceCipherDecode.mjs index 20a8a4f2..5280bb1a 100644 --- a/src/core/operations/RailFenceCypherDecode.mjs +++ b/src/core/operations/RailFenceCipherDecode.mjs @@ -7,19 +7,19 @@ import Operation from "../Operation.mjs"; /** - * Rail Fence Cypher Decode operation + * Rail Fence Cipher Decode operation */ -class RailFenceCypherDecode extends Operation { +class RailFenceCipherDecode extends Operation { /** - * RailFenceCypherDecode constructor + * RailFenceCipherDecode constructor */ constructor() { super(); - this.name = "Rail Fence Cypher Decode"; + this.name = "Rail Fence Cipher Decode"; this.module = "Ciphers"; - this.description = "Decodes Strings that were created using the Rail fence Cypher provided a key and an offset"; + this.description = "Decodes Strings that were created using the Rail fence Cipher provided a key and an offset"; this.infoURL = "https://en.wikipedia.org/wiki/Rail_fence_cipher"; this.inputType = "string"; this.outputType = "string"; @@ -43,8 +43,7 @@ class RailFenceCypherDecode extends Operation { * @returns {string} */ run(input, args) { - const [key] = args; - // const [key, offset] = args; + const [key, offset] = args; let cipher = input; @@ -54,51 +53,35 @@ class RailFenceCypherDecode extends Operation { return "Key should be smaller than the cipher's length"; } + if (offset < 0) { + return "Offset has to be a positive integer"; + } + + const cycle = (key - 1) * 2; + const rest = cipher.length % key; if (rest !== 0) { - cipher = cipher + (" ".repeat(key-rest)); + cipher = cipher + (" ".repeat(key - rest)); } - const blockLen = cipher.length / key; + const plaintext = new Array(cipher.length); - let plaintext = ""; + let j = 0; + let x, y; - for (let i = 0; i < blockLen; i++) { - for (let j = 0; j < key; j++) { - plaintext += cipher[i + (j * blockLen)]; + for (y = 0; y < key; y++) { + for (x = 0; x < cipher.length; x++) { + if ((y + x + offset) % cycle === 0 || (y - x - offset) % cycle === 0) { + plaintext[x] = cipher[j++]; + } } } - return plaintext; + return plaintext.join("").trim(); } - /** - * Highlight Rail Fence Cypher Decode - * - * @param {Object[]} pos - * @param {number} pos[].start - * @param {number} pos[].end - * @param {Object[]} args - * @returns {Object[]} pos - */ - highlight(pos, args) { - return pos; - } - - /** - * Highlight Rail Fence Cypher Decode in reverse - * - * @param {Object[]} pos - * @param {number} pos[].start - * @param {number} pos[].end - * @param {Object[]} args - * @returns {Object[]} pos - */ - highlightReverse(pos, args) { - return pos; - } } -export default RailFenceCypherDecode; +export default RailFenceCipherDecode; diff --git a/src/core/operations/RailFenceCypherEncode.mjs b/src/core/operations/RailFenceCipherEncode.mjs similarity index 50% rename from src/core/operations/RailFenceCypherEncode.mjs rename to src/core/operations/RailFenceCipherEncode.mjs index 8da1830b..5d9d5eb1 100644 --- a/src/core/operations/RailFenceCypherEncode.mjs +++ b/src/core/operations/RailFenceCipherEncode.mjs @@ -7,19 +7,19 @@ import Operation from "../Operation.mjs"; /** - * Rail Fence Cypher Encode operation + * Rail Fence Cipher Encode operation */ -class RailFenceCypherEncode extends Operation { +class RailFenceCipherEncode extends Operation { /** - * RailFenceCypherEncode constructor + * RailFenceCipherEncode constructor */ constructor() { super(); - this.name = "Rail Fence Cypher Encode"; + this.name = "Rail Fence Cipher Encode"; this.module = "Ciphers"; - this.description = "Encodes Strings using the Rail fence Cypher provided a key and an offset"; + this.description = "Encodes Strings using the Rail fence Cipher provided a key and an offset"; this.infoURL = "https://en.wikipedia.org/wiki/Rail_fence_cipher"; this.inputType = "string"; this.outputType = "string"; @@ -43,54 +43,31 @@ class RailFenceCypherEncode extends Operation { * @returns {string} */ run(input, args) { - const [key] = args; - // const [key, offset] = args; + const [key, offset] = args; const plaintext = input; - if (key < 2) { return "Key has to be bigger than 2"; } else if (key > plaintext.length) { return "Key should be smaller than the plain text's length"; } - let cipher = ""; - - for (let block = 0; block < key; block++) { - for (let pos = block; pos < plaintext.length; pos += key) { - cipher += plaintext[pos]; - } + if (offset < 0) { + return "Offset has to be a positive integer"; } - return cipher; - } + const cycle = (key - 1) * 2; + const rows = new Array(key).fill(""); - /** - * Highlight Rail Fence Cypher Encode - * - * @param {Object[]} pos - * @param {number} pos[].start - * @param {number} pos[].end - * @param {Object[]} args - * @returns {Object[]} pos - */ - highlight(pos, args) { - return pos; - } + for (let pos = 0; pos < plaintext.length; pos++) { + const rowIdx = key - 1 - Math.abs(cycle / 2 - (pos + offset) % cycle); - /** - * Highlight Rail Fence Cypher Encode in reverse - * - * @param {Object[]} pos - * @param {number} pos[].start - * @param {number} pos[].end - * @param {Object[]} args - * @returns {Object[]} pos - */ - highlightReverse(pos, args) { - return pos; + rows[rowIdx] += plaintext[pos]; + } + + return rows.join("").trim(); } } -export default RailFenceCypherEncode; +export default RailFenceCipherEncode; diff --git a/tests/operations/tests/Ciphers.mjs b/tests/operations/tests/Ciphers.mjs index 0232a14d..a853db5a 100644 --- a/tests/operations/tests/Ciphers.mjs +++ b/tests/operations/tests/Ciphers.mjs @@ -420,36 +420,113 @@ TestRegister.addTests([ ], }, { - name: "Rail Fence Cypher Decode: normal", + name: "Rail Fence Cipher Decode: normal", input: "Cytgah sTEAto rtn rsligcdsrporpyi H r fWiigo ovn oe", expectedOutput: "Cryptography is THE Art of Writing or solving codes", recipeConfig: [ { - "op": "Rail Fence Cypher Decode", + "op": "Rail Fence Cipher Decode", "args": [2, 0] } ], }, { - name: "Rail Fence Cypher Decode: key has to be bigger than 2", + name: "Rail Fence Cipher Decode: key has to be bigger than 2", input: "Cytgah sTEAto rtn rsligcdsrporpyi H r fWiigo ovn oe", expectedOutput: "Key has to be bigger than 2", recipeConfig: [ { - "op": "Rail Fence Cypher Decode", + "op": "Rail Fence Cipher Decode", "args": [1, 0] } ], }, { - name: "Rail Fence Cypher Decode: key has to be smaller than input's length", + name: "Rail Fence Cipher Decode: key has to be smaller than input's length", input: "shortinput", expectedOutput: "Key should be smaller than the cipher's length", recipeConfig: [ { - "op": "Rail Fence Cypher Decode", + "op": "Rail Fence Cipher Decode", "args": [22, 0] } ], }, + { + name: "Rail Fence Cipher Decode: offset should be positive", + input: "shortinput", + expectedOutput: "Offset has to be a positive integer", + recipeConfig: [ + { + "op": "Rail Fence Cipher Decode", + "args": [2, -1] + } + ], + }, + { + name: "Rail Fence Cipher Decode: Normal with Offset non-null", + input: "51746026813793592840", + expectedOutput: "12345678901234567890", + recipeConfig: [ + { + "op": "Rail Fence Cipher Decode", + "args": [4, 2] + } + ], + }, + { + name: "Rail Fence Cipher Encode: normal", + input: "Cryptography is THE Art of Writing or solving codes", + expectedOutput: "Cytgah sTEAto rtn rsligcdsrporpyi H r fWiigo ovn oe", + recipeConfig: [ + { + "op": "Rail Fence Cipher Encode", + "args": [2, 0] + } + ], + }, + { + name: "Rail Fence Cipher Encode: key has to be bigger than 2", + input: "Cryptography is THE Art of Writing or solving codes", + expectedOutput: "Key has to be bigger than 2", + recipeConfig: [ + { + "op": "Rail Fence Cipher Encode", + "args": [1, 0] + } + ], + }, + { + name: "Rail Fence Cipher Encode: key has to be smaller than input's length", + input: "shortinput", + expectedOutput: "Key should be smaller than the plain text's length", + recipeConfig: [ + { + "op": "Rail Fence Cipher Encode", + "args": [22, 0] + } + ], + }, + { + name: "Rail Fence Cipher Encode: offset should be positive", + input: "shortinput", + expectedOutput: "Offset has to be a positive integer", + recipeConfig: [ + { + "op": "Rail Fence Cipher Encode", + "args": [2, -1] + } + ], + }, + { + name: "Rail Fence Cipher Encode: Normal with Offset non-null", + input: "12345678901234567890", + expectedOutput: "51746026813793592840", + recipeConfig: [ + { + "op": "Rail Fence Cipher Encode", + "args": [4, 2] + } + ], + }, ]);