Skip to content

[#927] added parity bit operation #1036

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/core/config/Categories.json
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,8 @@
"CRC-8 Checksum",
"CRC-16 Checksum",
"CRC-32 Checksum",
"TCP/IP Checksum"
"TCP/IP Checksum",
"Parity Bit"
]
},
{
Expand Down
50 changes: 50 additions & 0 deletions src/core/lib/ParityBit.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/**
* Parity Bit functions.
*
* @author j83305 [[email protected]]
* @copyright Crown Copyright 2020
* @license Apache-2.0
*
*/

import OperationError from "../errors/OperationError.mjs";

/**
* Function to take the user input and encode using the given arguments
* @param input string of binary
* @param args array
*/
export function calculateParityBit(input, args) {
let count1s = 0;
for (let i = 0; i < input.length; i++) {
const character = input.charAt(i);
if (character === "1") {
count1s++;
} else if (character !== args[3] && character !== "0" && character !== " ") {
throw new OperationError("unexpected character encountered: \"" + character + "\"");
}
}
let parityBit = "1";
const flipflop = args[0] === "Even Parity" ? 0 : 1;
if (count1s % 2 === flipflop) {
parityBit = "0";
}
if (args[1] === "End") {
return input + parityBit;
} else {
return parityBit + input;
}
}

/**
* just removes the parity bit to return the original data
* @param input string of binary, encoded
* @param args array
*/
export function decodeParityBit(input, args) {
if (args[1] === "End") {
return input.slice(0, -1);
} else {
return input.slice(1);
}
}
128 changes: 128 additions & 0 deletions src/core/operations/ParityBit.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
/**
* @author j83305 [[email protected]]
* @copyright Crown Copyright 2020
* @license Apache-2.0
*/

import Operation from "../Operation.mjs";
import { calculateParityBit, decodeParityBit } from "../lib/ParityBit.mjs";

/**
* Parity Bit operation
*/
class ParityBit extends Operation {

/**
* ParityBit constructor
*/
constructor() {
super();

this.name = "Parity Bit";
this.module = "Default";
this.description = "A parity bit, or check bit, is the simplest form of error detection. It is a bit which is added to a string of bits and represents if the number of 1's in the binary string is an even number or odd number.<br><br>If a delimiter is specified, the parity bit calculation will be performed on each 'block' of the input data, where the blocks are created by slicing the input at each occurence of the delimiter character";
this.infoURL = "https://wikipedia.org/wiki/Parity_bit";
this.inputType = "string";
this.outputType = "string";
this.args = [
{
name: "Mode",
type: "option",
value: [
"Even Parity",
"Odd Parity"
]
},
{
name: "Postion",
type: "option",
value: [
"Start",
"End"
]
},
{
name: "Encode or Decode",
type: "option",
value: [
"Encode",
"Decode"
]
},
{
name: "Delimiter",
type: "shortString",
value: ""
}
];
}

/**
* @param {string} input
* @param {Object[]} args
* @returns {string}
*/
run(input, args) {
if (input.length === 0) {
return input;
}
/**
* determines weather to use the encode or decode method based off args[2]
* @param input input to be encoded or decoded
* @param args array
*/
const method = (input, args) => args[2] === "Encode" ? calculateParityBit(input, args) : decodeParityBit(input, args);
if (args[3].length > 0) {
const byteStrings = input.split(args[3]);
for (let byteStringsArrayIndex = 0; byteStringsArrayIndex < byteStrings.length; byteStringsArrayIndex++) {
byteStrings[byteStringsArrayIndex] = method(byteStrings[byteStringsArrayIndex], args);
}
return byteStrings.join(args[3]);
}
return method(input, args);
}

/**
* Highlight Parity Bit
*
* @param {Object[]} pos
* @param {number} pos[].start
* @param {number} pos[].end
* @param {Object[]} args
* @returns {Object[]} pos
*/
highlight(pos, args) {
if (args[3].length === 0) {
if (args[1] === "Prepend") {
pos[0].start += 1;
pos[0].end += 1;
}
return pos;
}
// need to be able to read input to do the highlighting when there is a delimiter
}

/**
* Highlight Parity Bit in reverse
*
* @param {Object[]} pos
* @param {number} pos[].start
* @param {number} pos[].end
* @param {Object[]} args
* @returns {Object[]} pos
*/
highlightReverse(pos, args) {
if (args[3].length === 0) {
if (args[1] === "Prepend") {
if (pos[0].start > 0) {
pos[0].start -= 1;
}
pos[0].end -= 1;
}
return pos;
}
}

}

export default ParityBit;
1 change: 1 addition & 0 deletions tests/operations/index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ import "./tests/NormaliseUnicode.mjs";
import "./tests/OTP.mjs";
import "./tests/PGP.mjs";
import "./tests/PHP.mjs";
import "./tests/ParityBit.mjs";
import "./tests/ParseIPRange.mjs";
import "./tests/ParseQRCode.mjs";
import "./tests/PowerSet.mjs";
Expand Down
147 changes: 147 additions & 0 deletions tests/operations/tests/ParityBit.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
/**
* Parity Bit tests
*
* @author j83305 [[email protected]]
* @copyright Crown Copyright 2020
* @license Apache-2.0
*/
import TestRegister from "../../lib/TestRegister.mjs";

TestRegister.addTests([
{
name: "Parity bit encode in even parity, 1 block of binary of arbitrary length, prepend, even number of 1s",
input: "01010101 10101010",
expectedOutput: "001010101 10101010",
recipeConfig: [
{
"op": "Parity Bit",
"args": [
"Even Parity",
"Start",
"Encode",
""
]
}
]
},
{
name: "Parity bit encode in even parity, 1 block of binary of arbitrary length, prepend, odd number of 1s",
input: "01010101 10101011",
expectedOutput: "101010101 10101011",
recipeConfig: [
{
"op": "Parity Bit",
"args": [
"Even Parity",
"Start",
"Encode",
""
]
}
]
},
{
name: "Parity bit encode in even parity, 1 block of binary of arbitrary length, append, odd number of 1s",
input: "01010101 10101011",
expectedOutput: "01010101 101010111",
recipeConfig: [
{
"op": "Parity Bit",
"args": [
"Even Parity",
"End",
"Encode",
""
]
}
]
},
{
name: "Parity bit encode in odd parity, 1 block of binary of arbitrary length, prepend, even number of 1s",
input: "01010101 10101010",
expectedOutput: "101010101 10101010",
recipeConfig: [
{
"op": "Parity Bit",
"args": [
"Odd Parity",
"Start",
"Encode",
""
]
}
]
},
{
name: "Parity bit encode in odd parity, 1 block of binary of arbitrary length, prepend, odd number of 1s",
input: "01010101 10101011",
expectedOutput: "001010101 10101011",
recipeConfig: [
{
"op": "Parity Bit",
"args": [
"Odd Parity",
"Start",
"Encode",
""
]
}
]
},
{
name: "Parity bit encode in odd parity, 1 block of binary of arbitrary length, append, odd number of 1s",
input: "01010101 10101011",
expectedOutput: "01010101 101010110",
recipeConfig: [
{
"op": "Parity Bit",
"args": [
"Odd Parity",
"End",
"Encode",
""
]
}
]
},
{
name: "Parity bit encode in even parity, binary for 'hello world!', prepend to each byte",
input: "hello world!",
expectedOutput: "101101000 001100101 001101100 001101100 001101111 100100000 001110111 001101111 001110010 001101100 101100100 000100001",
recipeConfig: [
{
"op": "To Binary",
"args": ["Space"]
},
{
"op": "Parity Bit",
"args": [
"Even Parity",
"Start",
"Encode",
" "
]
}
]
},
{
name: "Parity bit encode in odd parity, binary for 'hello world!', append to each byte",
input: "hello world!",
expectedOutput: "011010000 011001011 011011001 011011001 011011111 001000000 011101111 011011111 011100101 011011001 011001000 001000011",
recipeConfig: [
{
"op": "To Binary",
"args": ["Space"]
},
{
"op": "Parity Bit",
"args": [
"Odd Parity",
"End",
"Encode",
" "
]
}
]
},
]);