mirror of
https://github.com/gchq/CyberChef.git
synced 2025-04-21 07:16:17 -04:00
106 lines
3.5 KiB
JavaScript
106 lines
3.5 KiB
JavaScript
![]() |
/**
|
||
|
* @author Daniel Temkin [http://danieltemkin.com]
|
||
|
* @author Thomas Leplus [https://www.leplus.org]
|
||
|
* @copyright Crown Copyright 2021
|
||
|
* @license Apache-2.0
|
||
|
*/
|
||
|
|
||
|
import Operation from "../Operation.mjs";
|
||
|
|
||
|
/**
|
||
|
* ROT8000 operation.
|
||
|
*/
|
||
|
class ROT8000 extends Operation {
|
||
|
|
||
|
/**
|
||
|
* ROT8000 constructor
|
||
|
*/
|
||
|
constructor() {
|
||
|
super();
|
||
|
this.name = "ROT8000";
|
||
|
this.module = "Default";
|
||
|
this.description = "The simple Caesar-cypher encryption that replaces each Unicode character with the one 0x8000 places forward or back along the alphabet.";
|
||
|
this.infoURL = "https://github.com/rottytooth/rot8000";
|
||
|
this.inputType = "string";
|
||
|
this.outputType = "string";
|
||
|
this.args = [];
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param {byteArray} input
|
||
|
* @param {Object[]} args
|
||
|
* @returns {byteArray}
|
||
|
*/
|
||
|
run(input, args) {
|
||
|
// Inspired from https://github.com/rottytooth/rot8000/blob/main/rot8000.js
|
||
|
// these come from the valid-code-point-transitions.json file generated from the c# proj
|
||
|
// this is done bc: 1) don't trust JS's understanging of surrogate pairs and 2) consistency with original rot8000
|
||
|
const validCodePoints = JSON.parse('{"33":true,"127":false,"161":true,"5760":false,"5761":true,"8192":false,"8203":true,"8232":false,"8234":true,"8239":false,"8240":true,"8287":false,"8288":true,"12288":false,"12289":true,"55296":false,"57344":true}');
|
||
|
const bmpSize = 0x10000;
|
||
|
const rotList = {}; // the mapping of char to rotated char
|
||
|
const hiddenBlocks = [];
|
||
|
let startBlock = 0;
|
||
|
for (const key in validCodePoints) {
|
||
|
if (Object.prototype.hasOwnProperty.call(validCodePoints, key)) {
|
||
|
if (validCodePoints[key] === true)
|
||
|
hiddenBlocks.push({ start: startBlock, end: parseInt(key, 10) - 1 });
|
||
|
else
|
||
|
startBlock = parseInt(key, 10);
|
||
|
}
|
||
|
}
|
||
|
const validIntList = []; // list of all valid chars
|
||
|
let currValid = false;
|
||
|
for (let i = 0; i < bmpSize; i++) {
|
||
|
if (validCodePoints[i] !== undefined) {
|
||
|
currValid = validCodePoints[i];
|
||
|
}
|
||
|
if (currValid) validIntList.push(i);
|
||
|
}
|
||
|
const rotateNum = Object.keys(validIntList).length / 2;
|
||
|
// go through every valid char and find its match
|
||
|
for (let i = 0; i < validIntList.length; i++) {
|
||
|
rotList[String.fromCharCode(validIntList[i])] =
|
||
|
String.fromCharCode(validIntList[(i + rotateNum) % (rotateNum * 2)]);
|
||
|
}
|
||
|
let output = "";
|
||
|
for (let count = 0; count < input.length; count++) {
|
||
|
// if it is not in the mappings list, just add it directly (no rotation)
|
||
|
if (rotList[input[count]] === undefined) {
|
||
|
output += input[count];
|
||
|
continue;
|
||
|
}
|
||
|
// otherwise, rotate it and add it to the string
|
||
|
output += rotList[input[count]];
|
||
|
}
|
||
|
return output;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Highlight ROT8000
|
||
|
*
|
||
|
* @param {Object[]} pos
|
||
|
* @param {number} pos[].start
|
||
|
* @param {number} pos[].end
|
||
|
* @param {Object[]} args
|
||
|
* @returns {Object[]} pos
|
||
|
*/
|
||
|
highlight(pos, args) {
|
||
|
return pos;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Highlight ROT8000 in reverse
|
||
|
*
|
||
|
* @param {Object[]} pos
|
||
|
* @param {number} pos[].start
|
||
|
* @param {number} pos[].end
|
||
|
* @param {Object[]} args
|
||
|
* @returns {Object[]} pos
|
||
|
*/
|
||
|
highlightReverse(pos, args) {
|
||
|
return pos;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
export default ROT8000;
|