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

This commit is contained in:
n1474335 2017-09-05 14:26:09 +00:00
parent 5fcc259efb
commit 1b628ac213
7 changed files with 143 additions and 14 deletions

View File

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

View File

@ -1595,7 +1595,7 @@ const OperationConfig = {
args: [] args: []
}, },
"Rotate right": { "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, run: Rotate.runRotr,
highlight: true, highlight: true,
highlightReverse: true, highlightReverse: true,
@ -1603,19 +1603,19 @@ const OperationConfig = {
outputType: "byteArray", outputType: "byteArray",
args: [ args: [
{ {
name: "Number of bits", name: "Amount",
type: "number", type: "number",
value: Rotate.ROTATE_AMOUNT value: Rotate.ROTATE_AMOUNT
}, },
{ {
name: "Rotate as a whole", name: "Carry through",
type: "boolean", type: "boolean",
value: Rotate.ROTATE_WHOLE value: Rotate.ROTATE_CARRY
} }
] ]
}, },
"Rotate left": { "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, run: Rotate.runRotl,
highlight: true, highlight: true,
highlightReverse: true, highlightReverse: true,
@ -1623,14 +1623,14 @@ const OperationConfig = {
outputType: "byteArray", outputType: "byteArray",
args: [ args: [
{ {
name: "Number of bits", name: "Amount",
type: "number", type: "number",
value: Rotate.ROTATE_AMOUNT value: Rotate.ROTATE_AMOUNT
}, },
{ {
name: "Rotate as a whole", name: "Carry through",
type: "boolean", 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; export default OperationConfig;

View File

@ -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. * XOR bitwise calculation.
* *

View File

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

View File

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

View File

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

View File

@ -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"] }
]
},
]);