Browse Source

inital move of two ops

d98762625 7 years ago
parent
commit
f491461a57

+ 7 - 5
src/core/config/Categories.js

@@ -116,9 +116,11 @@ const Categories = [
     //         "Object Identifier to Hex",
     //     ]
     // },
-    // {
-    //     name: "Arithmetic / Logic",
-    //     ops: [
+    {
+        name: "Arithmetic / Logic",
+        ops: [
+            "Set Union",
+            "Set Intersection"
     //         "XOR",
     //         "XOR Brute Force",
     //         "OR",
@@ -138,8 +140,8 @@ const Categories = [
     //         "Rotate left",
     //         "Rotate right",
     //         "ROT13",
-    //     ]
-    // },
+        ]
+    },
     // {
     //     name: "Networking",
     //     ops: [

+ 59 - 2
src/core/config/OperationConfig.json

@@ -156,7 +156,7 @@
         ]
     },
     "Raw Deflate": {
-        "module": "Compression",
+        "module": "Default",
         "description": "Compresses data using the deflate algorithm with no headers.",
         "inputType": "byteArray",
         "outputType": "byteArray",
@@ -210,6 +210,63 @@
             }
         ]
     },
+    "Set Intersection": {
+        "module": "Default",
+        "description": "Get the intersection of two sets",
+        "inputType": "string",
+        "outputType": "string",
+        "flowControl": false,
+        "args": [
+            {
+                "name": "Sample delimiter",
+                "type": "binaryString",
+                "value": "\n\n"
+            },
+            {
+                "name": "Item delimiter",
+                "type": "binaryString",
+                "value": ","
+            }
+        ]
+    },
+    "": {
+        "module": "Default",
+        "description": "",
+        "inputType": "string",
+        "outputType": "string",
+        "flowControl": false,
+        "args": [
+            {
+                "name": "Sample delimiter",
+                "type": "binaryString",
+                "value": "\n\n"
+            },
+            {
+                "name": "Item delimiter",
+                "type": "binaryString",
+                "value": ","
+            }
+        ]
+    },
+    "Set Union": {
+        "module": "Default",
+        "description": "Get the union of two sets",
+        "inputType": "string",
+        "outputType": "string",
+        "flowControl": false,
+        "args": [
+            {
+                "name": "Sample delimiter",
+                "type": "binaryString",
+                "value": "\n\n"
+            },
+            {
+                "name": "Item delimiter",
+                "type": "binaryString",
+                "value": ","
+            }
+        ]
+    },
     "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 +395,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": [
             {

+ 0 - 2
src/core/config/modules/Compression.mjs

@@ -7,7 +7,6 @@
 */
 import Gunzip from "../../operations/Gunzip";
 import Gzip from "../../operations/Gzip";
-import RawDeflate from "../../operations/RawDeflate";
 import RawInflate from "../../operations/RawInflate";
 import Unzip from "../../operations/Unzip";
 import Zip from "../../operations/Zip";
@@ -19,7 +18,6 @@ const OpModules = typeof self === "undefined" ? {} : self.OpModules || {};
 OpModules.Compression = {
     "Gunzip": Gunzip,
     "Gzip": Gzip,
-    "Raw Deflate": RawDeflate,
     "Raw Inflate": RawInflate,
     "Unzip": Unzip,
     "Zip": Zip,

+ 0 - 1
src/core/config/modules/Default.js

@@ -30,7 +30,6 @@ import Tidy from "../../operations/Tidy.js";
 import Unicode from "../../operations/Unicode.js";
 import UUID from "../../operations/UUID.js";
 import XKCD from "../../operations/XKCD.js";
-import SetOps from "../../operations/SetOperations.js";
 
 
 /**

+ 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 RawDeflate from "../../operations/RawDeflate";
+import SetIntersection from "../../operations/SetIntersection";
+import SetOps from "../../operations/SetOps";
+import SetUnion from "../../operations/SetUnion";
 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,
+    "Raw Deflate": RawDeflate,
+    "Set Intersection": SetIntersection,
+    "": SetOps,
+    "Set Union": SetUnion,
     "Show Base64 offsets": ShowBase64Offsets,
     "To Base32": ToBase32,
     "To Base64": ToBase64,

+ 1 - 1
src/core/operations/RawDeflate.mjs

@@ -28,7 +28,7 @@ class RawDeflate extends Operation {
         super();
 
         this.name = "Raw Deflate";
-        this.module = "Compression";
+        this.module = "Default";
         this.description = "Compresses data using the deflate algorithm with no headers.";
         this.inputType = "byteArray";
         this.outputType = "byteArray";

+ 33 - 0
src/core/operations/SetIntersection.mjs

@@ -0,0 +1,33 @@
+import SetOp from "./SetOps";
+
+/**
+ * 
+ */
+class SetIntersection extends SetOp {
+
+    /**
+     * 
+     */
+    constructor() {
+        super();
+        this.setOp = this.runIntersection;
+
+        this.name = "Set Intersection";
+        this.description = "Get the intersection of two sets";
+    }
+
+    /**
+     * Get the intersection of the two sets.
+     *
+     * @param {Object[]} a
+     * @param {Object[]} b
+     * @returns {Object[]}
+     */
+    runIntersection(a, b) {
+        return a.filter((item) => {
+            return b.indexOf(item) > -1;
+        }).join(this.itemDelimiter);
+    }
+}
+
+export default SetIntersection;

+ 0 - 202
src/core/operations/SetOperations.js

@@ -1,202 +0,0 @@
-import Utils from "../Utils.js";
-
-/**
- * Set operations.
- *
- * @author d98762625 [d98762625@gmail.com]
- * @copyright Crown Copyright 2018
- * @license APache-2.0
- *
- * @namespace
- */
-class SetOps {
-
-    /**
-     * Set default options for operation
-     */
-    constructor() {
-        this._sampleDelimiter = "\\n\\n";
-        this._operation = ["Union", "Intersection", "Set Difference", "Symmetric Difference", "Cartesian Product", "Power Set"];
-        this._itemDelimiter = ",";
-    }
-
-    /**
-     * Get operations array
-     * @returns {String[]}
-     */
-    get OPERATION() {
-        return this._operation;
-    }
-
-    /**
-     * Get sample delimiter
-     * @returns {String}
-     */
-    get SAMPLE_DELIMITER() {
-        return this._sampleDelimiter;
-    }
-
-    /**
-     * Get item delimiter
-     * @returns {String}
-     */
-    get ITEM_DELIMITER() {
-        return this._itemDelimiter;
-    }
-
-
-    /**
-     * Run the configured set operation.
-     *
-     * @param {String} input
-     * @param {String[]} args
-     * @returns {html}
-     */
-    runSetOperation(input, args) {
-        const [sampleDelim, itemDelimiter, operation] = args;
-        const sets = input.split(sampleDelim);
-
-        if (!sets || (sets.length !== 2 && operation !== "Power Set") || (sets.length !== 1 && operation === "Power Set")) {
-            return "Incorrect number of sets, perhaps you need to modify the sample delimiter or add more samples?";
-        }
-
-        if (this._operation.indexOf(operation) === -1) {
-            return "Invalid 'Operation' option.";
-        }
-
-        let result = {
-            "Union": this.runUnion,
-            "Intersection": this.runIntersect,
-            "Set Difference": this.runSetDifference,
-            "Symmetric Difference": this.runSymmetricDifference,
-            "Cartesian Product": this.runCartesianProduct,
-            "Power Set": this.runPowerSet.bind(undefined, itemDelimiter),
-        }[operation]
-            .apply(this, sets.map(s => s.split(itemDelimiter)));
-
-            // Formatting issues due to the nested characteristics of power set.
-        if (operation === "Power Set") {
-            result = result.map(i => `${i}\n`).join("");
-        } else {
-            result = result.join(itemDelimiter);
-        }
-
-        return Utils.escapeHtml(result);
-    }
-
-    /**
-     * Get the union of the two sets.
-     *
-     * @param {Object[]} a
-     * @param {Object[]} b
-     * @returns {Object[]}
-     */
-    runUnion(a, b) {
-
-        const result = {};
-
-        /**
-         * Only add non-existing items
-         * @param {Object} hash
-         */
-        const addUnique = (hash) => (item) => {
-            if (!hash[item]) {
-                hash[item] = true;
-            }
-        };
-
-        a.map(addUnique(result));
-        b.map(addUnique(result));
-
-        return Object.keys(result);
-    }
-
-    /**
-     * Get the intersection of the two sets.
-     *
-     * @param {Object[]} a
-     * @param {Object[]} b
-     * @returns {Object[]}
-     */
-    runIntersect(a, b) {
-        return a.filter((item) => {
-            return b.indexOf(item) > -1;
-        });
-    }
-
-    /**
-     * Get elements in set a that are not in set b
-     *
-     * @param {Object[]} a
-     * @param {Object[]} b
-     * @returns {Object[]}
-     */
-    runSetDifference(a, b) {
-        return a.filter((item) => {
-            return b.indexOf(item) === -1;
-        });
-    }
-
-    /**
-     * Get elements of each set that aren't in the other set.
-     *
-     * @param {Object[]} a
-     * @param {Object[]} b
-     * @return {Object[]}
-     */
-    runSymmetricDifference(a, b) {
-        return this.runSetDifference(a, b)
-            .concat(this.runSetDifference(b, a));
-    }
-
-    /**
-     * Return the cartesian product of the two inputted sets.
-     *
-     * @param {Object[]} a
-     * @param {Object[]} b
-     * @returns {String[]}
-     */
-    runCartesianProduct(a, b) {
-        return Array(Math.max(a.length, b.length))
-            .fill(null)
-            .map((item, index) => `(${a[index] || undefined},${b[index] || undefined})`);
-    }
-
-    /**
-     * Return the power set of the inputted set.
-     *
-     * @param {Object[]} a
-     * @returns {Object[]}
-     */
-    runPowerSet(delimiter, a) {
-        // empty array items getting picked up
-        a = a.filter(i => i.length);
-        if (!a.length) {
-            return [];
-        }
-
-        /**
-         * Decimal to binary function
-         * @param {*} dec
-         */
-        const toBinary = (dec) => (dec >>> 0).toString(2);
-        const result = new Set();
-        // Get the decimal number to make a binary as long as the input
-        const maxBinaryValue = parseInt(Number(a.map(i => "1").reduce((p, c) => p + c)), 2);
-        // Make an array of each binary number from 0 to maximum
-        const binaries = [...Array(maxBinaryValue + 1).keys()]
-            .map(toBinary)
-            .map(i => i.padStart(toBinary(maxBinaryValue).length, "0"));
-
-        // XOR the input with each binary to get each unique permutation
-        binaries.forEach((binary) => {
-            const split = binary.split("");
-            result.add(a.filter((item, index) => split[index] === "1"));
-        });
-
-        // map for formatting & put in length order.
-        return [...result].map(r => r.join(delimiter)).sort((a, b) => a.length - b.length);
-    }
-}
-
-export default new SetOps();

+ 84 - 0
src/core/operations/SetOps.mjs

@@ -0,0 +1,84 @@
+import Operation from "../Operation";
+import Utils from "../Utils";
+
+/**
+ * 
+ */
+class SetOp extends Operation {
+
+    /**
+     * 
+     * @param {*} runOp
+     */
+    constructor(runOp) {
+        super();
+
+        this.module = "Default";
+        this.inputType = "string";
+        this.outputType = "string";
+        this.args = [
+            {
+                name: "Sample delimiter",
+                type: "binaryString",
+                value: "\n\n"
+            },
+            {
+                name: "Item delimiter",
+                type: "binaryString",
+                value: ","
+            },
+        ];
+
+        this.runOp = runOp;
+    }
+
+    /**
+     * 
+     * @param sets 
+     */
+    validateSampleNumbers(sets) {
+        if (!sets || (sets.length !== 2)) {
+            throw "Incorrect number of sets, perhaps you need to modify the sample delimiter or add more samples?";
+        }
+    }
+
+    /**
+     *
+     * @param {*} input
+     * @param {*} args
+     */
+    run(input, args) {
+
+        [this.sampleDelim, this.itemDelimiter] = args;
+        const sets = input.split(this.sampleDelim);
+
+        try {
+            this.validateSampleNumbers(sets);
+        } catch (e) {
+            return e;
+        }
+
+        const result = this.setOp.apply(this, sets.map(s => s.split(this.itemDelimiter)));
+
+        // let result = {
+        //     "Union": this.runUnion,
+        //     "Intersection": this.runIntersect,
+        //     "Set Difference": this.runSetDifference,
+        //     "Symmetric Difference": this.runSymmetricDifference,
+        //     "Cartesian Product": this.runCartesianProduct,
+        //     "Power Set": this.runPowerSet.bind(undefined, itemDelimiter),
+        // }[operation]
+        //     .apply(this, sets.map(s => s.split(itemDelimiter)));
+
+        // Formatting issues due to the nested characteristics of power set.
+        // if (operation === "Power Set") {
+            // result = result.map(i => `${i}\n`).join("");
+        // } else {
+            // result = result.join(itemDelimiter);
+        // }
+
+        return Utils.escapeHtml(result);
+    }
+}
+
+export default SetOp;

+ 46 - 0
src/core/operations/SetUnion.mjs

@@ -0,0 +1,46 @@
+import SetOp from "./SetOps";
+
+/**
+ * 
+ */
+class SetUnion extends SetOp {
+
+    /**
+     * 
+     */
+    constructor() {
+        super();
+        this.setOp = this.runUnion;
+
+        this.name = "Set Union";
+        this.description = "Get the union of two sets";
+    }
+
+    /**
+     * Get the union of the two sets.
+     *
+     * @param {Object[]} a
+     * @param {Object[]} b
+     * @returns {Object[]}
+     */
+    runUnion(a, b) {
+        const result = {};
+
+        /**
+         * Only add non-existing items
+         * @param {Object} hash
+         */
+        const addUnique = (hash) => (item) => {
+            if (!hash[item]) {
+                hash[item] = true;
+            }
+        };
+
+        a.map(addUnique(result));
+        b.map(addUnique(result));
+
+        return Object.keys(result).join(this.itemDelimiter);
+    }
+}
+
+export default SetUnion;

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

@@ -12,6 +12,9 @@ import Gunzip from "./Gunzip";
 import Gzip from "./Gzip";
 import RawDeflate from "./RawDeflate";
 import RawInflate from "./RawInflate";
+import SetIntersection from "./SetIntersection";
+import SetOps from "./SetOps";
+import SetUnion from "./SetUnion";
 import ShowBase64Offsets from "./ShowBase64Offsets";
 import ToBase32 from "./ToBase32";
 import ToBase64 from "./ToBase64";
@@ -29,6 +32,9 @@ export {
     Gzip,
     RawDeflate,
     RawInflate,
+    SetIntersection,
+    SetOps,
+    SetUnion,
     ShowBase64Offsets,
     ToBase32,
     ToBase64,