Add Bacon cipher decoding

This commit is contained in:
Karsten Silkenbäumer 2019-03-02 15:00:42 +01:00
parent 8148c1a8a8
commit 77b098c5fe
5 changed files with 393 additions and 0 deletions

View file

@ -85,6 +85,7 @@
"Vigenère Decode",
"To Morse Code",
"From Morse Code",
"Bacon Cipher Decode",
"Bifid Cipher Encode",
"Bifid Cipher Decode",
"Affine Cipher Encode",

37
src/core/lib/Bacon.mjs Normal file
View file

@ -0,0 +1,37 @@
/**
* Bacon resources.
*
* @author Karsten Silkenbäumer [kassi@users.noreply.github.com]
* @copyright Karsten Silkenbäumer 2019
* @license Apache-2.0
*/
/**
* Bacon definitions.
*/
export const BACON_ALPHABET_REDUCED = "ABCDEFGHIKLMNOPQRSTUWXYZ";
export const BACON_ALPHABET_COMPLETE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
export const BACON_TRANSLATION_01 = "0/1";
export const BACON_TRANSLATION_AB = "A/B";
export const BACON_TRANSLATION_CASE = "Case";
export const BACON_TRANSLATION_AMNZ = "A-M/N-Z first letter";
export const BACON_TRANSLATIONS = [
BACON_TRANSLATION_01,
BACON_TRANSLATION_AB,
BACON_TRANSLATION_CASE,
BACON_TRANSLATION_AMNZ,
];
export const BACON_CLEARER_MAP = {
[BACON_TRANSLATIONS[0]]: /[^01]/g,
[BACON_TRANSLATIONS[1]]: /[^ABab]/g,
[BACON_TRANSLATIONS[2]]: /[^A-Za-z]/g,
};
export const BACON_NORMALIZE_MAP = {
[BACON_TRANSLATIONS[1]]: {
"A": "0",
"B": "1",
"a": "0",
"b": "1"
},
};

View file

@ -0,0 +1,108 @@
/**
* BaconCipher operation.
*
* @author kassi [kassi@users.noreply.github.com]
* @copyright Karsten Silkenbäumer 2019
* @license Apache-2.0
*/
import Operation from "../Operation";
import {
BACON_ALPHABET_REDUCED, BACON_ALPHABET_COMPLETE,
BACON_TRANSLATION_CASE, BACON_TRANSLATION_AMNZ, BACON_TRANSLATIONS, BACON_CLEARER_MAP, BACON_NORMALIZE_MAP
} from "../lib/Bacon";
/**
* BaconCipherDecode operation
*/
class BaconCipherDecode extends Operation {
/**
* BaconCipherDecode constructor
*/
constructor() {
super();
this.name = "Bacon Cipher Decode";
this.module = "Default";
this.description = "Bacon's cipher or the Baconian cipher is a method of steganography(a method of hiding a secret message as opposed to just a cipher) devised by Francis Bacon in 1605.[1][2][3] A message is concealed in the presentation of text, rather than its content.";
this.infoURL = "https://en.wikipedia.org/wiki/Bacon%27s_cipher";
this.inputType = "string";
this.outputType = "string";
this.args = [
{
"name": "Alphabet",
"type": "option",
"value": [BACON_ALPHABET_REDUCED, BACON_ALPHABET_COMPLETE]
},
{
"name": "Translation",
"type": "option",
"value": BACON_TRANSLATIONS
},
{
"name": "Invert Translation",
"type": "boolean",
"value": false
}
];
}
/**
* @param {String} input
* @param {Object[]} args
* @returns {String}
*/
run(input, args) {
const [alphabet, translation, invert] = args;
// split text into groups of 5 characters
// remove invalid characters
input = input.replace(BACON_CLEARER_MAP[translation], "");
// normalize to unique alphabet
if (BACON_NORMALIZE_MAP[translation] !== undefined) {
input = input.replace(/./g, function (c) {
return BACON_NORMALIZE_MAP[translation][c];
});
} else if (translation === BACON_TRANSLATION_CASE) {
const codeA = "A".charCodeAt(0);
const codeZ = "Z".charCodeAt(0);
input = input.replace(/./g, function (c) {
const code = c.charCodeAt(0);
if (code >= codeA && code <= codeZ) {
return "1";
} else {
return "0";
}
});
} else if (translation === BACON_TRANSLATION_AMNZ) {
const words = input.split(" ");
const letters = words.map(function (e) {
const code = e[0].toUpperCase().charCodeAt(0);
return code >= "N".charCodeAt(0) ? "1" : "0";
});
input = letters.join("");
}
if (invert) {
input = input.replace(/./g, function (c) {
return {
"0": "1",
"1": "0"
}[c];
});
}
// group into 5
const inputArray = input.match(/(.{5})/g) || [];
let output = "";
for (let index = 0; index < inputArray.length; index++) {
const code = inputArray[index];
const number = parseInt(code, 2);
output += number < alphabet.length ? alphabet[number] : "?";
}
return output;
}
}
export default BaconCipherDecode;