|
| 1 | +/** |
| 2 | + * @author Daniel Temkin [http://danieltemkin.com] |
| 3 | + * @author Thomas Leplus [https://www.leplus.org] |
| 4 | + * @copyright Crown Copyright 2021 |
| 5 | + * @license Apache-2.0 |
| 6 | + */ |
| 7 | + |
| 8 | +import Operation from "../Operation.mjs"; |
| 9 | + |
| 10 | +/** |
| 11 | + * ROT8000 operation. |
| 12 | + */ |
| 13 | +class ROT8000 extends Operation { |
| 14 | + |
| 15 | + /** |
| 16 | + * ROT8000 constructor |
| 17 | + */ |
| 18 | + constructor() { |
| 19 | + super(); |
| 20 | + this.name = "ROT8000"; |
| 21 | + this.module = "Default"; |
| 22 | + this.description = "The simple Caesar-cypher encryption that replaces each Unicode character with the one 0x8000 places forward or back along the alphabet."; |
| 23 | + this.infoURL = "https://github.com/rottytooth/rot8000"; |
| 24 | + this.inputType = "string"; |
| 25 | + this.outputType = "string"; |
| 26 | + this.args = []; |
| 27 | + } |
| 28 | + |
| 29 | + /** |
| 30 | + * @param {byteArray} input |
| 31 | + * @param {Object[]} args |
| 32 | + * @returns {byteArray} |
| 33 | + */ |
| 34 | + run(input, args) { |
| 35 | + // Inspired from https://github.com/rottytooth/rot8000/blob/main/rot8000.js |
| 36 | + // these come from the valid-code-point-transitions.json file generated from the c# proj |
| 37 | + // this is done bc: 1) don't trust JS's understanging of surrogate pairs and 2) consistency with original rot8000 |
| 38 | + const validCodePoints = JSON.parse('{"33":true,"127":false,"161":true,"5760":false,"5761":true,"8192":false,"8203":true,"8232":false,"8234":true,"8239":false,"8240":true,"8287":false,"8288":true,"12288":false,"12289":true,"55296":false,"57344":true}'); |
| 39 | + const bmpSize = 0x10000; |
| 40 | + const rotList = {}; // the mapping of char to rotated char |
| 41 | + const hiddenBlocks = []; |
| 42 | + let startBlock = 0; |
| 43 | + for (const key in validCodePoints) { |
| 44 | + if (Object.prototype.hasOwnProperty.call(validCodePoints, key)) { |
| 45 | + if (validCodePoints[key] === true) |
| 46 | + hiddenBlocks.push({ start: startBlock, end: parseInt(key, 10) - 1 }); |
| 47 | + else |
| 48 | + startBlock = parseInt(key, 10); |
| 49 | + } |
| 50 | + } |
| 51 | + const validIntList = []; // list of all valid chars |
| 52 | + let currValid = false; |
| 53 | + for (let i = 0; i < bmpSize; i++) { |
| 54 | + if (validCodePoints[i] !== undefined) { |
| 55 | + currValid = validCodePoints[i]; |
| 56 | + } |
| 57 | + if (currValid) validIntList.push(i); |
| 58 | + } |
| 59 | + const rotateNum = Object.keys(validIntList).length / 2; |
| 60 | + // go through every valid char and find its match |
| 61 | + for (let i = 0; i < validIntList.length; i++) { |
| 62 | + rotList[String.fromCharCode(validIntList[i])] = |
| 63 | + String.fromCharCode(validIntList[(i + rotateNum) % (rotateNum * 2)]); |
| 64 | + } |
| 65 | + let output = ""; |
| 66 | + for (let count = 0; count < input.length; count++) { |
| 67 | + // if it is not in the mappings list, just add it directly (no rotation) |
| 68 | + if (rotList[input[count]] === undefined) { |
| 69 | + output += input[count]; |
| 70 | + continue; |
| 71 | + } |
| 72 | + // otherwise, rotate it and add it to the string |
| 73 | + output += rotList[input[count]]; |
| 74 | + } |
| 75 | + return output; |
| 76 | + } |
| 77 | + |
| 78 | + /** |
| 79 | + * Highlight ROT8000 |
| 80 | + * |
| 81 | + * @param {Object[]} pos |
| 82 | + * @param {number} pos[].start |
| 83 | + * @param {number} pos[].end |
| 84 | + * @param {Object[]} args |
| 85 | + * @returns {Object[]} pos |
| 86 | + */ |
| 87 | + highlight(pos, args) { |
| 88 | + return pos; |
| 89 | + } |
| 90 | + |
| 91 | + /** |
| 92 | + * Highlight ROT8000 in reverse |
| 93 | + * |
| 94 | + * @param {Object[]} pos |
| 95 | + * @param {number} pos[].start |
| 96 | + * @param {number} pos[].end |
| 97 | + * @param {Object[]} args |
| 98 | + * @returns {Object[]} pos |
| 99 | + */ |
| 100 | + highlightReverse(pos, args) { |
| 101 | + return pos; |
| 102 | + } |
| 103 | +} |
| 104 | + |
| 105 | +export default ROT8000; |
0 commit comments