Explorar o código

Added 'Bit shift left' and 'Bit shift right' operations

n1474335 %!s(int64=7) %!d(string=hai) anos
pai
achega
1b628ac213

+ 2 - 0
src/core/config/Categories.js

@@ -122,6 +122,8 @@ const Categories = [
             "AND",
             "ADD",
             "SUB",
+            "Bit shift left",
+            "Bit shift right",
             "Rotate left",
             "Rotate right",
             "ROT13",

+ 44 - 8
src/core/config/OperationConfig.js

@@ -1595,7 +1595,7 @@ const OperationConfig = {
         args: []
     },
     "Rotate right": {
-        description: "Rotates each byte to the right by the number of bits specified. Currently only supports 8-bit values.",
+        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.",
         run: Rotate.runRotr,
         highlight: true,
         highlightReverse: true,
@@ -1603,19 +1603,19 @@ const OperationConfig = {
         outputType: "byteArray",
         args: [
             {
-                name: "Number of bits",
+                name: "Amount",
                 type: "number",
                 value: Rotate.ROTATE_AMOUNT
             },
             {
-                name: "Rotate as a whole",
+                name: "Carry through",
                 type: "boolean",
-                value: Rotate.ROTATE_WHOLE
+                value: Rotate.ROTATE_CARRY
             }
         ]
     },
     "Rotate left": {
-        description: "Rotates each byte to the left by the number of bits specified. Currently only supports 8-bit values.",
+        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.",
         run: Rotate.runRotl,
         highlight: true,
         highlightReverse: true,
@@ -1623,14 +1623,14 @@ const OperationConfig = {
         outputType: "byteArray",
         args: [
             {
-                name: "Number of bits",
+                name: "Amount",
                 type: "number",
                 value: Rotate.ROTATE_AMOUNT
             },
             {
-                name: "Rotate as a whole",
+                name: "Carry through",
                 type: "boolean",
-                value: Rotate.ROTATE_WHOLE
+                value: Rotate.ROTATE_CARRY
             }
         ]
     },
@@ -3600,6 +3600,42 @@ const OperationConfig = {
         ]
 
     },
+    "Bit shift left": {
+        description: "Shifts the bits in each byte towards the left by the specified amount.",
+        run: BitwiseOp.runBitShiftLeft,
+        inputType: "byteArray",
+        outputType: "byteArray",
+        highlight: true,
+        highlightReverse: true,
+        args: [
+            {
+                name: "Amount",
+                type: "number",
+                value: 1
+            },
+        ]
+    },
+    "Bit shift right": {
+        description: "Shifts the bits in each byte towards the right by the specified amount.<br><br><i>Logical shifts</i> replace the leftmost bits with zeros.<br><i>Arithmetic shifts</i> preserve the most significant bit (MSB) of the original byte keeping the sign the same (positive or negative).",
+        run: BitwiseOp.runBitShiftRight,
+        inputType: "byteArray",
+        outputType: "byteArray",
+        highlight: true,
+        highlightReverse: true,
+        args: [
+            {
+                name: "Amount",
+                type: "number",
+                value: 1
+            },
+            {
+                name: "Type",
+                type: "option",
+                value: BitwiseOp.BIT_SHIFT_TYPE
+            }
+        ]
+    },
+
 };
 
 export default OperationConfig;

+ 40 - 0
src/core/operations/BitwiseOp.js

@@ -228,6 +228,46 @@ const BitwiseOp = {
     },
 
 
+    /**
+     * Bit shift left operation.
+     *
+     * @param {byteArray} input
+     * @param {Object[]} args
+     * @returns {byteArray}
+     */
+    runBitShiftLeft: function(input, args) {
+        const amount = args[0];
+
+        return input.map(b => {
+            return (b << amount) & 0xff;
+        });
+    },
+
+
+    /**
+     * @constant
+     * @default
+     */
+    BIT_SHIFT_TYPE: ["Logical shift", "Arithmetic shift"],
+
+    /**
+     * Bit shift right operation.
+     *
+     * @param {byteArray} input
+     * @param {Object[]} args
+     * @returns {byteArray}
+     */
+    runBitShiftRight: function(input, args) {
+        const amount = args[0],
+            type = args[1],
+            mask = type === "Logical shift" ? 0 : 0x80;
+
+        return input.map(b => {
+            return (b >>> amount) ^ (b & mask);
+        });
+    },
+
+
     /**
      * XOR bitwise calculation.
      *

+ 1 - 1
src/core/operations/ByteRepr.js

@@ -196,7 +196,7 @@ const ByteRepr = {
 
 
     /**
-     * Highlight to hex
+     * Highlight from hex
      *
      * @param {Object[]} pos
      * @param {number} pos[].start

+ 5 - 5
src/core/operations/Rotate.js

@@ -20,7 +20,7 @@ const Rotate = {
      * @constant
      * @default
      */
-    ROTATE_WHOLE: false,
+    ROTATE_CARRY: false,
 
     /**
      * Runs rotation operations across the input data.
@@ -53,7 +53,7 @@ const Rotate = {
      */
     runRotr: function(input, args) {
         if (args[1]) {
-            return Rotate._rotrWhole(input, args[0]);
+            return Rotate._rotrCarry(input, args[0]);
         } else {
             return Rotate._rot(input, args[0], Rotate._rotr);
         }
@@ -69,7 +69,7 @@ const Rotate = {
      */
     runRotl: function(input, args) {
         if (args[1]) {
-            return Rotate._rotlWhole(input, args[0]);
+            return Rotate._rotlCarry(input, args[0]);
         } else {
             return Rotate._rot(input, args[0], Rotate._rotl);
         }
@@ -197,7 +197,7 @@ const Rotate = {
      * @param {number} amount
      * @returns {byteArray}
      */
-    _rotrWhole: function(data, amount) {
+    _rotrCarry: function(data, amount) {
         let carryBits = 0,
             newByte,
             result = [];
@@ -223,7 +223,7 @@ const Rotate = {
      * @param {number} amount
      * @returns {byteArray}
      */
-    _rotlWhole: function(data, amount) {
+    _rotlCarry: function(data, amount) {
         let carryBits = 0,
             newByte,
             result = [];

+ 1 - 0
test/index.js

@@ -13,6 +13,7 @@ import "babel-polyfill";
 import TestRegister from "./TestRegister.js";
 import "./tests/operations/Base58.js";
 import "./tests/operations/BCD.js";
+import "./tests/operations/BitwiseOp.js";
 import "./tests/operations/ByteRepr.js";
 import "./tests/operations/CharEnc.js";
 import "./tests/operations/Cipher.js";

+ 50 - 0
test/tests/operations/BitwiseOp.js

@@ -0,0 +1,50 @@
+/**
+ * BitwiseOp tests
+ *
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2017
+ * @license Apache-2.0
+ */
+import TestRegister from "../../TestRegister.js";
+
+TestRegister.addTests([
+    {
+        name: "Bit shift left",
+        input: "01010101 10101010 11111111 00000000 11110000 00001111 00110011 11001100",
+        expectedOutput: "10101010 01010100 11111110 00000000 11100000 00011110 01100110 10011000",
+        recipeConfig: [
+            { "op": "From Binary",
+                "args": ["Space"] },
+            { "op": "Bit shift left",
+                "args": [1] },
+            { "op": "To Binary",
+                "args": ["Space"] }
+        ]
+    },
+    {
+        name: "Bit shift right: Logical shift",
+        input: "01010101 10101010 11111111 00000000 11110000 00001111 00110011 11001100",
+        expectedOutput: "00101010 01010101 01111111 00000000 01111000 00000111 00011001 01100110",
+        recipeConfig: [
+            { "op": "From Binary",
+                "args": ["Space"] },
+            { "op": "Bit shift right",
+                "args": [1, "Logical shift"] },
+            { "op": "To Binary",
+                "args": ["Space"] }
+        ]
+    },
+    {
+        name: "Bit shift right: Arithmetic shift",
+        input: "01010101 10101010 11111111 00000000 11110000 00001111 00110011 11001100",
+        expectedOutput: "00101010 11010101 11111111 00000000 11111000 00000111 00011001 11100110",
+        recipeConfig: [
+            { "op": "From Binary",
+                "args": ["Space"] },
+            { "op": "Bit shift right",
+                "args": [1, "Arithmetic shift"] },
+            { "op": "To Binary",
+                "args": ["Space"] }
+        ]
+    },
+]);