Browse Source

Rotate module converted to ESM

4 Ops:
- ROT-13
- ROT-47
- Rotate left
- Rotate right
+ module containing common functions
Matt C 7 years ago
parent
commit
4988ead918

+ 10 - 10
src/core/config/Categories.js

@@ -84,8 +84,8 @@ const Categories = [
     //         "RC2 Decrypt",
     //         "RC4",
     //         "RC4 Drop",
-    //         "ROT13",
-    //         "ROT47",
+            "ROT13",
+            "ROT47",
     //         "XOR",
     //         "XOR Brute Force",
     //         "Vigenère Encode",
@@ -116,9 +116,9 @@ const Categories = [
     //         "Object Identifier to Hex",
     //     ]
     // },
-    // {
-    //     name: "Arithmetic / Logic",
-    //     ops: [
+    {
+        name: "Arithmetic / Logic",
+        ops: [
     //         "XOR",
     //         "XOR Brute Force",
     //         "OR",
@@ -135,11 +135,11 @@ const Categories = [
     //         "Standard Deviation",
     //         "Bit shift left",
     //         "Bit shift right",
-    //         "Rotate left",
-    //         "Rotate right",
-    //         "ROT13",
-    //     ]
-    // },
+            "Rotate left",
+            "Rotate right",
+            "ROT13"
+        ]
+    },
     // {
     //     name: "Networking",
     //     ops: [

+ 77 - 1
src/core/config/OperationConfig.json

@@ -155,6 +155,44 @@
             }
         ]
     },
+    "ROT13": {
+        "module": "Default",
+        "description": "A simple caesar substitution cipher which rotates alphabet characters by the specified amount (default 13).",
+        "inputType": "byteArray",
+        "outputType": "byteArray",
+        "flowControl": false,
+        "args": [
+            {
+                "name": "Rotate lower case chars",
+                "type": "boolean",
+                "value": true
+            },
+            {
+                "name": "Rotate upper case chars",
+                "type": "boolean",
+                "value": true
+            },
+            {
+                "name": "Amount",
+                "type": "number",
+                "value": 13
+            }
+        ]
+    },
+    "ROT47": {
+        "module": "Default",
+        "description": "A slightly more complex variation of a caesar cipher, which includes ASCII characters from 33 '!' to 126 '~'. Default rotation: 47.",
+        "inputType": "byteArray",
+        "outputType": "byteArray",
+        "flowControl": false,
+        "args": [
+            {
+                "name": "Amount",
+                "type": "number",
+                "value": 47
+            }
+        ]
+    },
     "Raw Deflate": {
         "module": "Compression",
         "description": "Compresses data using the deflate algorithm with no headers.",
@@ -210,6 +248,44 @@
             }
         ]
     },
+    "Rotate left": {
+        "module": "Default",
+        "description": "Rotates each byte to the left by the number of bits specified, optionally carrying the excess bits over to the next byte. Currently only supports 8-bit values.",
+        "inputType": "byteArray",
+        "outputType": "byteArray",
+        "flowControl": false,
+        "args": [
+            {
+                "name": "Amount",
+                "type": "number",
+                "value": 1
+            },
+            {
+                "name": "Carry through",
+                "type": "boolean",
+                "value": false
+            }
+        ]
+    },
+    "Rotate right": {
+        "module": "Default",
+        "description": "Rotates each byte to the right by the number of bits specified, optionally carrying the excess bits over to the next byte. Currently only supports 8-bit values.",
+        "inputType": "byteArray",
+        "outputType": "byteArray",
+        "flowControl": false,
+        "args": [
+            {
+                "name": "Amount",
+                "type": "number",
+                "value": 1
+            },
+            {
+                "name": "Carry through",
+                "type": "boolean",
+                "value": false
+            }
+        ]
+    },
     "Show Base64 offsets": {
         "module": "Default",
         "description": "When a string is within a block of data and the whole block is Base64'd, the string itself could be represented in Base64 in three distinct ways depending on its offset within the block.<br><br>This operation shows all possible offsets for a given string so that each possible encoding can be considered.",
@@ -338,7 +414,7 @@
         "module": "Compression",
         "description": "Decompresses data using the PKZIP algorithm and displays it per file, with support for passwords.",
         "inputType": "byteArray",
-        "outputType": "byteArray",
+        "outputType": "html",
         "flowControl": false,
         "args": [
             {

+ 8 - 0
src/core/config/modules/Default.mjs

@@ -8,6 +8,10 @@
 import FromBase32 from "../../operations/FromBase32";
 import FromBase64 from "../../operations/FromBase64";
 import FromHex from "../../operations/FromHex";
+import ROT13 from "../../operations/ROT13";
+import ROT47 from "../../operations/ROT47";
+import RotateLeft from "../../operations/RotateLeft";
+import RotateRight from "../../operations/RotateRight";
 import ShowBase64Offsets from "../../operations/ShowBase64Offsets";
 import ToBase32 from "../../operations/ToBase32";
 import ToBase64 from "../../operations/ToBase64";
@@ -19,6 +23,10 @@ OpModules.Default = {
     "From Base32": FromBase32,
     "From Base64": FromBase64,
     "From Hex": FromHex,
+    "ROT13": ROT13,
+    "ROT47": ROT47,
+    "Rotate left": RotateLeft,
+    "Rotate right": RotateRight,
     "Show Base64 offsets": ShowBase64Offsets,
     "To Base32": ToBase32,
     "To Base64": ToBase64,

+ 112 - 0
src/core/lib/Rotate.mjs

@@ -0,0 +1,112 @@
+/**
+ * Bit rotation functions.
+ *
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ *
+ * @todo Support for UTF16
+ */
+
+
+/**
+ * Default values for rotation operations
+ */
+export const ROTATE_AMOUNT = 1;
+export const ROTATE_CARRY = false;
+
+
+/**
+ * Runs rotation operations across the input data.
+ *
+ * @param {byteArray} data
+ * @param {number} amount
+ * @param {function} algo - The rotation operation to carry out
+ * @returns {byteArray}
+ */
+export function rot(data, amount, algo) {
+    const result = [];
+    for (let i = 0; i < data.length; i++) {
+        let b = data[i];
+        for (let j = 0; j < amount; j++) {
+            b = algo(b);
+        }
+        result.push(b);
+    }
+    return result;
+}
+
+
+/**
+ * Rotate right bitwise op.
+ *
+ * @param {byte} b
+ * @returns {byte}
+ */
+export function rotr(b) {
+    const bit = (b & 1) << 7;
+    return (b >> 1) | bit;
+}
+
+/**
+ * Rotate left bitwise op.
+ *
+ * @param {byte} b
+ * @returns {byte}
+ */
+export function rotl(b) {
+    const bit = (b >> 7) & 1;
+    return ((b << 1) | bit) & 0xFF;
+}
+
+
+/**
+ * Rotates a byte array to the right by a specific amount as a whole, so that bits are wrapped
+ * from the end of the array to the beginning.
+ *
+ * @private
+ * @param {byteArray} data
+ * @param {number} amount
+ * @returns {byteArray}
+ */
+export function rotrCarry(data, amount) {
+    const result = [];
+    let carryBits = 0,
+        newByte;
+
+    amount = amount % 8;
+    for (let i = 0; i < data.length; i++) {
+        const oldByte = data[i] >>> 0;
+        newByte = (oldByte >> amount) | carryBits;
+        carryBits = (oldByte & (Math.pow(2, amount)-1)) << (8-amount);
+        result.push(newByte);
+    }
+    result[0] |= carryBits;
+    return result;
+}
+
+
+/**
+ * Rotates a byte array to the left by a specific amount as a whole, so that bits are wrapped
+ * from the beginning of the array to the end.
+ *
+ * @private
+ * @param {byteArray} data
+ * @param {number} amount
+ * @returns {byteArray}
+ */
+export function rotlCarry(data, amount) {
+    const result = [];
+    let carryBits = 0,
+        newByte;
+
+    amount = amount % 8;
+    for (let i = data.length-1; i >= 0; i--) {
+        const oldByte = data[i];
+        newByte = ((oldByte << amount) | carryBits) & 0xFF;
+        carryBits = (oldByte >> (8-amount)) & (Math.pow(2, amount)-1);
+        result[i] = (newByte);
+    }
+    result[data.length-1] = result[data.length-1] | carryBits;
+    return result;
+}

+ 110 - 0
src/core/operations/ROT13.mjs

@@ -0,0 +1,110 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+
+/**
+ * Default arguments for ROT13 operation
+ */
+const ROT13_AMOUNT = 13,
+    ROT13_LOWERCASE = true,
+    ROT13_UPPERCASE = true;
+
+
+/**
+ * ROT13 operation.
+ */
+class ROT13 extends Operation {
+
+    /**
+     * ROT13 constructor
+     */
+    constructor() {
+        super();
+
+        this.name = "ROT13";
+        this.module = "Default";
+        this.description = "A simple caesar substitution cipher which rotates alphabet characters by the specified amount (default 13).";
+        this.inputType = "byteArray";
+        this.outputType = "byteArray";
+        this.args = [
+            {
+                name: "Rotate lower case chars",
+                type: "boolean",
+                value: ROT13_LOWERCASE
+            },
+            {
+                name: "Rotate upper case chars",
+                type: "boolean",
+                value: ROT13_UPPERCASE
+            },
+            {
+                name: "Amount",
+                type: "number",
+                value: ROT13_AMOUNT
+            },
+        ];
+    }
+
+    /**
+     * @param {string} input
+     * @param {Object[]} args
+     * @returns {byteArray}
+     */
+    run(input, args) {
+        const output = input,
+            rot13Lowercase = args[0],
+            rot13Upperacse = args[1];
+        let amount = args[2],
+            chr;
+
+        if (amount) {
+            if (amount < 0) {
+                amount = 26 - (Math.abs(amount) % 26);
+            }
+
+            for (let i = 0; i < input.length; i++) {
+                chr = input[i];
+                if (rot13Upperacse && chr >= 65 && chr <= 90) { // Upper case
+                    chr = (chr - 65 + amount) % 26;
+                    output[i] = chr + 65;
+                } else if (rot13Lowercase && chr >= 97 && chr <= 122) { // Lower case
+                    chr = (chr - 97 + amount) % 26;
+                    output[i] = chr + 97;
+                }
+            }
+        }
+        return output;
+    }
+
+    /**
+     * Highlight ROT13
+     *
+     * @param {Object[]} pos
+     * @param {number} pos[].start
+     * @param {number} pos[].end
+     * @param {Object[]} args
+     * @returns {Object[]} pos
+     */
+    highlight(pos, args) {
+        return pos;
+    }
+
+    /**
+     * Highlight ROT13 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 ROT13;

+ 93 - 0
src/core/operations/ROT47.mjs

@@ -0,0 +1,93 @@
+/**
+ * @author Matt C [matt@artemisbot.uk]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+
+/**
+ * Default argument for ROT47 operation
+ */
+const ROT47_AMOUNT = 47;
+
+
+/**
+ * ROT47 operation.
+ */
+class ROT47 extends Operation {
+
+    /**
+     * ROT47 constructor
+     */
+    constructor() {
+        super();
+
+        this.name = "ROT47";
+        this.module = "Default";
+        this.description = "A slightly more complex variation of a caesar cipher, which includes ASCII characters from 33 '!' to 126 '~'. Default rotation: 47.";
+        this.inputType = "byteArray";
+        this.outputType = "byteArray";
+        this.args = [
+            {
+                name: "Amount",
+                type: "number",
+                value: ROT47_AMOUNT
+            },
+        ];
+    }
+
+    /**
+     * @param {string} input
+     * @param {Object[]} args
+     * @returns {byteArray}
+     */
+    run(input, args) {
+        const output = input;
+        let amount = args[0],
+            chr;
+
+        if (amount) {
+            if (amount < 0) {
+                amount = 94 - (Math.abs(amount) % 94);
+            }
+
+            for (let i = 0; i < input.length; i++) {
+                chr = input[i];
+                if (chr >= 33 && chr <= 126) {
+                    chr = (chr - 33 + amount) % 94;
+                    output[i] = chr + 33;
+                }
+            }
+        }
+        return output;
+    }
+
+    /**
+     * Highlight ROT47
+     *
+     * @param {Object[]} pos
+     * @param {number} pos[].start
+     * @param {number} pos[].end
+     * @param {Object[]} args
+     * @returns {Object[]} pos
+     */
+    highlight(pos, args) {
+        return pos;
+    }
+
+    /**
+     * Highlight ROT47 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 ROT47;

+ 80 - 0
src/core/operations/RotateLeft.mjs

@@ -0,0 +1,80 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import { rot, rotl, rotlCarry, ROTATE_AMOUNT, ROTATE_CARRY } from "../lib/Rotate";
+
+/**
+ * Rotate left operation.
+ */
+class RotateLeft extends Operation {
+
+    /**
+     * RotateLeft constructor
+     */
+    constructor() {
+        super();
+
+        this.name = "Rotate left";
+        this.module = "Default";
+        this.description = "Rotates each byte to the left by the number of bits specified, optionally carrying the excess bits over to the next byte. Currently only supports 8-bit values.";
+        this.inputType = "byteArray";
+        this.outputType = "byteArray";
+        this.args = [
+            {
+                name: "Amount",
+                type: "number",
+                value: ROTATE_AMOUNT
+            },
+            {
+                name: "Carry through",
+                type: "boolean",
+                value: ROTATE_CARRY
+            }
+        ];
+    }
+
+    /**
+     * @param {string} input
+     * @param {Object[]} args
+     * @returns {byteArray}
+     */
+    run(input, args) {
+        if (args[1]) {
+            return rotlCarry(input, args[0]);
+        } else {
+            return rot(input, args[0], rotl);
+        }
+    }
+
+    /**
+     * Highlight rotate left
+     *
+     * @param {Object[]} pos
+     * @param {number} pos[].start
+     * @param {number} pos[].end
+     * @param {Object[]} args
+     * @returns {Object[]} pos
+     */
+    highlight(pos, args) {
+        return pos;
+    }
+
+    /**
+     * Highlight rotate left 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 RotateLeft;

+ 80 - 0
src/core/operations/RotateRight.mjs

@@ -0,0 +1,80 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import { rot, rotr, rotrCarry, ROTATE_AMOUNT, ROTATE_CARRY } from "../lib/Rotate";
+
+/**
+ * Rotate right operation.
+ */
+class RotateRight extends Operation {
+
+    /**
+     * RotateRight constructor
+     */
+    constructor() {
+        super();
+
+        this.name = "Rotate right";
+        this.module = "Default";
+        this.description = "Rotates each byte to the right by the number of bits specified, optionally carrying the excess bits over to the next byte. Currently only supports 8-bit values.";
+        this.inputType = "byteArray";
+        this.outputType = "byteArray";
+        this.args = [
+            {
+                name: "Amount",
+                type: "number",
+                value: ROTATE_AMOUNT
+            },
+            {
+                name: "Carry through",
+                type: "boolean",
+                value: ROTATE_CARRY
+            }
+        ];
+    }
+
+    /**
+     * @param {string} input
+     * @param {Object[]} args
+     * @returns {byteArray}
+     */
+    run(input, args) {
+        if (args[1]) {
+            return rotrCarry(input, args[0]);
+        } else {
+            return rot(input, args[0], rotr);
+        }
+    }
+
+    /**
+     * Highlight rotate right
+     *
+     * @param {Object[]} pos
+     * @param {number} pos[].start
+     * @param {number} pos[].end
+     * @param {Object[]} args
+     * @returns {Object[]} pos
+     */
+    highlight(pos, args) {
+        return pos;
+    }
+
+    /**
+     * Highlight rotate right 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 RotateRight;

+ 8 - 0
src/core/operations/index.mjs

@@ -10,8 +10,12 @@ import FromBase64 from "./FromBase64";
 import FromHex from "./FromHex";
 import Gunzip from "./Gunzip";
 import Gzip from "./Gzip";
+import ROT13 from "./ROT13";
+import ROT47 from "./ROT47";
 import RawDeflate from "./RawDeflate";
 import RawInflate from "./RawInflate";
+import RotateLeft from "./RotateLeft";
+import RotateRight from "./RotateRight";
 import ShowBase64Offsets from "./ShowBase64Offsets";
 import ToBase32 from "./ToBase32";
 import ToBase64 from "./ToBase64";
@@ -27,8 +31,12 @@ export {
     FromHex,
     Gunzip,
     Gzip,
+    ROT13,
+    ROT47,
     RawDeflate,
     RawInflate,
+    RotateLeft,
+    RotateRight,
     ShowBase64Offsets,
     ToBase32,
     ToBase64,