diff --git a/src/core/config/Categories.js b/src/core/config/Categories.js
index 77eafb4bc3..b74e932a5b 100755
--- a/src/core/config/Categories.js
+++ b/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: [
diff --git a/src/core/config/OperationConfig.json b/src/core/config/OperationConfig.json
index 1486c66d23..2f18363dab 100644
--- a/src/core/config/OperationConfig.json
+++ b/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.
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": [
{
diff --git a/src/core/config/modules/Default.mjs b/src/core/config/modules/Default.mjs
index 34043043e5..8648aa8aa4 100644
--- a/src/core/config/modules/Default.mjs
+++ b/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,
diff --git a/src/core/lib/Rotate.mjs b/src/core/lib/Rotate.mjs
new file mode 100644
index 0000000000..97c4b1df4d
--- /dev/null
+++ b/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;
+}
diff --git a/src/core/operations/ROT13.mjs b/src/core/operations/ROT13.mjs
new file mode 100644
index 0000000000..3bac332ab3
--- /dev/null
+++ b/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;
diff --git a/src/core/operations/ROT47.mjs b/src/core/operations/ROT47.mjs
new file mode 100644
index 0000000000..0421438be5
--- /dev/null
+++ b/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;
diff --git a/src/core/operations/RotateLeft.mjs b/src/core/operations/RotateLeft.mjs
new file mode 100644
index 0000000000..84a145654d
--- /dev/null
+++ b/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;
diff --git a/src/core/operations/RotateRight.mjs b/src/core/operations/RotateRight.mjs
new file mode 100644
index 0000000000..2018c6fc0e
--- /dev/null
+++ b/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;
diff --git a/src/core/operations/index.mjs b/src/core/operations/index.mjs
index 55a8e79aa1..5b7359638b 100644
--- a/src/core/operations/index.mjs
+++ b/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,
diff --git a/src/core/operations/legacy/Rotate.js b/src/core/operations/legacy/Rotate.js
deleted file mode 100755
index 9125e57576..0000000000
--- a/src/core/operations/legacy/Rotate.js
+++ /dev/null
@@ -1,244 +0,0 @@
-/**
- * Bit rotation operations.
- *
- * @author n1474335 [n1474335@gmail.com]
- * @copyright Crown Copyright 2016
- * @license Apache-2.0
- *
- * @namespace
- *
- * @todo Support for UTF16
- */
-const Rotate = {
-
- /**
- * @constant
- * @default
- */
- ROTATE_AMOUNT: 1,
- /**
- * @constant
- * @default
- */
- ROTATE_CARRY: false,
-
- /**
- * Runs rotation operations across the input data.
- *
- * @private
- * @param {byteArray} data
- * @param {number} amount
- * @param {function} algo - The rotation operation to carry out
- * @returns {byteArray}
- */
- _rot: function(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 operation.
- *
- * @param {byteArray} input
- * @param {Object[]} args
- * @returns {byteArray}
- */
- runRotr: function(input, args) {
- if (args[1]) {
- return Rotate._rotrCarry(input, args[0]);
- } else {
- return Rotate._rot(input, args[0], Rotate._rotr);
- }
- },
-
-
- /**
- * Rotate left operation.
- *
- * @param {byteArray} input
- * @param {Object[]} args
- * @returns {byteArray}
- */
- runRotl: function(input, args) {
- if (args[1]) {
- return Rotate._rotlCarry(input, args[0]);
- } else {
- return Rotate._rot(input, args[0], Rotate._rotl);
- }
- },
-
-
- /**
- * @constant
- * @default
- */
- ROT13_AMOUNT: 13,
- /**
- * @constant
- * @default
- */
- ROT13_LOWERCASE: true,
- /**
- * @constant
- * @default
- */
- ROT13_UPPERCASE: true,
-
- /**
- * ROT13 operation.
- *
- * @param {byteArray} input
- * @param {Object[]} args
- * @returns {byteArray}
- */
- runRot13: function(input, args) {
- let amount = args[2],
- output = input,
- chr,
- rot13Lowercase = args[0],
- rot13Upperacse = args[1];
-
- 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;
- },
-
-
- /**
- * @constant
- * @default
- */
- ROT47_AMOUNT: 47,
-
- /**
- * ROT47 operation.
- *
- * @author Matt C [matt@artemisbot.uk]
- * @param {byteArray} input
- * @param {Object[]} args
- * @returns {byteArray}
- */
- runRot47: function(input, args) {
- let amount = args[0],
- output = input,
- 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;
- },
-
-
- /**
- * Rotate right bitwise op.
- *
- * @private
- * @param {byte} b
- * @returns {byte}
- */
- _rotr: function(b) {
- const bit = (b & 1) << 7;
- return (b >> 1) | bit;
- },
-
-
- /**
- * Rotate left bitwise op.
- *
- * @private
- * @param {byte} b
- * @returns {byte}
- */
- _rotl: function(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}
- */
- _rotrCarry: function(data, amount) {
- let carryBits = 0,
- newByte,
- result = [];
-
- 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}
- */
- _rotlCarry: function(data, amount) {
- let carryBits = 0,
- newByte,
- result = [];
-
- 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;
- },
-
-};
-
-export default Rotate;
diff --git a/test/index.mjs b/test/index.mjs
index bd3f27ba3b..82b3c08161 100644
--- a/test/index.mjs
+++ b/test/index.mjs
@@ -45,6 +45,7 @@ import "./tests/operations/Base64";
// import "./tests/operations/NetBIOS.js";
// import "./tests/operations/OTP.js";
// import "./tests/operations/Regex.js";
+import "./tests/operations/Rotate.mjs";
// import "./tests/operations/StrUtils.js";
// import "./tests/operations/SeqUtils.js";
diff --git a/test/tests/operations/Rotate.mjs b/test/tests/operations/Rotate.mjs
new file mode 100644
index 0000000000..e48373d4ef
--- /dev/null
+++ b/test/tests/operations/Rotate.mjs
@@ -0,0 +1,214 @@
+/**
+ * Base64 tests.
+ *
+ * @author Matt C [matt@artemisbot.uk]
+ *
+ * @copyright Crown Copyright 2018
+ * @license Apache-2.0
+ */
+import TestRegister from "../../TestRegister";
+
+TestRegister.addTests([
+ {
+ name: "Rotate left: nothing",
+ input: "",
+ expectedOutput: "",
+ recipeConfig: [
+ {
+ op: "From Hex",
+ args: ["Space"]
+ },
+ {
+ op: "Rotate left",
+ args: [1, false],
+ },
+ {
+ op: "To Hex",
+ args: ["Space"]
+ }
+ ],
+ },
+ {
+ name: "Rotate left: normal",
+ input: "61 62 63 31 32 33",
+ expectedOutput: "c2 c4 c6 62 64 66",
+ recipeConfig: [
+ {
+ op: "From Hex",
+ args: ["Space"]
+ },
+ {
+ op: "Rotate left",
+ args: [1, false],
+ },
+ {
+ op: "To Hex",
+ args: ["Space"]
+ }
+ ],
+ },
+ {
+ name: "Rotate left: carry",
+ input: "61 62 63 31 32 33",
+ expectedOutput: "85 89 8c c4 c8 cd",
+ recipeConfig: [
+ {
+ op: "From Hex",
+ args: ["Space"]
+ },
+ {
+ op: "Rotate left",
+ args: [2, true],
+ },
+ {
+ op: "To Hex",
+ args: ["Space"]
+ }
+ ],
+ },
+ {
+ name: "Rotate right: nothing",
+ input: "",
+ expectedOutput: "",
+ recipeConfig: [
+ {
+ op: "From Hex",
+ args: ["Space"]
+ },
+ {
+ op: "Rotate right",
+ args: [1, false],
+ },
+ {
+ op: "To Hex",
+ args: ["Space"]
+ }
+ ],
+ },
+ {
+ name: "Rotate right: normal",
+ input: "61 62 63 31 32 33",
+ expectedOutput: "b0 31 b1 98 19 99",
+ recipeConfig: [
+ {
+ op: "From Hex",
+ args: ["Space"]
+ },
+ {
+ op: "Rotate right",
+ args: [1, false],
+ },
+ {
+ op: "To Hex",
+ args: ["Space"]
+ }
+ ],
+ },
+ {
+ name: "Rotate right: carry",
+ input: "61 62 63 31 32 33",
+ expectedOutput: "d8 58 98 cc 4c 8c",
+ recipeConfig: [
+ {
+ op: "From Hex",
+ args: ["Space"]
+ },
+ {
+ op: "Rotate right",
+ args: [2, true],
+ },
+ {
+ op: "To Hex",
+ args: ["Space"]
+ }
+ ],
+ },
+ {
+ name: "ROT13: nothing",
+ input: "",
+ expectedOutput: "",
+ recipeConfig: [
+ {
+ op: "ROT13",
+ args: [true, true, 13]
+ },
+ ],
+ },
+ {
+ name: "ROT13: normal",
+ input: "The Quick Brown Fox Jumped Over The Lazy Dog.",
+ expectedOutput: "Gur Dhvpx Oebja Sbk Whzcrq Bire Gur Ynml Qbt.",
+ recipeConfig: [
+ {
+ op: "ROT13",
+ args: [true, true, 13]
+ },
+ ],
+ },
+ {
+ name: "ROT13: full loop",
+ input: "The Quick Brown Fox Jumped Over The Lazy Dog.",
+ expectedOutput: "The Quick Brown Fox Jumped Over The Lazy Dog.",
+ recipeConfig: [
+ {
+ op: "ROT13",
+ args: [true, true, 26]
+ },
+ ],
+ },
+ {
+ name: "ROT13: lowercase only",
+ input: "The Quick Brown Fox Jumped Over The Lazy Dog.",
+ expectedOutput: "Tur Qhvpx Bebja Fbk Jhzcrq Oire Tur Lnml Dbt.",
+ recipeConfig: [
+ {
+ op: "ROT13",
+ args: [true, false, 13]
+ },
+ ],
+ },
+ {
+ name: "ROT13: uppercase only",
+ input: "The Quick Brown Fox Jumped Over The Lazy Dog.",
+ expectedOutput: "Ghe Duick Orown Sox Wumped Bver Ghe Yazy Qog.",
+ recipeConfig: [
+ {
+ op: "ROT13",
+ args: [false, true, 13]
+ },
+ ],
+ },
+ {
+ name: "ROT47: nothing",
+ input: "",
+ expectedOutput: "",
+ recipeConfig: [
+ {
+ op: "ROT47",
+ args: [47]
+ },
+ ],
+ },
+ {
+ name: "ROT47: normal",
+ input: "The Quick Brown Fox Jumped Over The Lazy Dog.",
+ expectedOutput: "%96 \"F:4< qC@H? u@I yF>A65 ~G6C %96 {2KJ s@8]",
+ recipeConfig: [
+ {
+ op: "ROT47",
+ args: [47]
+ },
+ ],
+ },
+ {
+ name: "ROT47: full loop",
+ input: "The Quick Brown Fox Jumped Over The Lazy Dog.",
+ expectedOutput: "The Quick Brown Fox Jumped Over The Lazy Dog.",
+ recipeConfig: [
+ {
+ op: "ROT47",
+ args: [94]
+ },
+ ],
+ },
+]);