mirror of
https://github.com/gchq/CyberChef.git
synced 2025-04-20 14:56:19 -04:00
Merge pull request #1553 from sg5506844/base92
Feature: Add Base92 operations
This commit is contained in:
commit
c13997bdb1
6 changed files with 258 additions and 0 deletions
|
@ -29,6 +29,8 @@
|
||||||
"To Base64",
|
"To Base64",
|
||||||
"From Base64",
|
"From Base64",
|
||||||
"Show Base64 offsets",
|
"Show Base64 offsets",
|
||||||
|
"To Base92",
|
||||||
|
"From Base92",
|
||||||
"To Base85",
|
"To Base85",
|
||||||
"From Base85",
|
"From Base85",
|
||||||
"To Base",
|
"To Base",
|
||||||
|
|
44
src/core/lib/Base92.mjs
Normal file
44
src/core/lib/Base92.mjs
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
/**
|
||||||
|
* Base92 resources.
|
||||||
|
*
|
||||||
|
* @author sg5506844 [sg5506844@gmail.com]
|
||||||
|
* @copyright Crown Copyright 2021
|
||||||
|
* @license Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import OperationError from "../errors/OperationError.mjs";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base92 alphabet char
|
||||||
|
*
|
||||||
|
* @param {number} val
|
||||||
|
* @returns {number}
|
||||||
|
*/
|
||||||
|
export function base92Chr(val) {
|
||||||
|
if (val < 0 || val >= 91) {
|
||||||
|
throw new OperationError("Invalid value");
|
||||||
|
}
|
||||||
|
if (val === 0)
|
||||||
|
return "!".charCodeAt(0);
|
||||||
|
else if (val <= 61)
|
||||||
|
return "#".charCodeAt(0) + val - 1;
|
||||||
|
else
|
||||||
|
return "a".charCodeAt(0) + val - 62;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base92 alphabet ord
|
||||||
|
*
|
||||||
|
* @param {string} val
|
||||||
|
* @returns {number}
|
||||||
|
*/
|
||||||
|
export function base92Ord(val) {
|
||||||
|
if (val === "!")
|
||||||
|
return 0;
|
||||||
|
else if ("#" <= val && val <= "_")
|
||||||
|
return val.charCodeAt(0) - "#".charCodeAt(0) + 1;
|
||||||
|
else if ("a" <= val && val <= "}")
|
||||||
|
return val.charCodeAt(0) - "a".charCodeAt(0) + 62;
|
||||||
|
throw new OperationError(`${val} is not a base92 character`);
|
||||||
|
}
|
||||||
|
|
55
src/core/operations/FromBase92.mjs
Normal file
55
src/core/operations/FromBase92.mjs
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
/**
|
||||||
|
* @author sg5506844 [sg5506844@gmail.com]
|
||||||
|
* @copyright Crown Copyright 2021
|
||||||
|
* @license Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { base92Ord } from "../lib/Base92.mjs";
|
||||||
|
import Operation from "../Operation.mjs";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* From Base92 operation
|
||||||
|
*/
|
||||||
|
class FromBase92 extends Operation {
|
||||||
|
/**
|
||||||
|
* FromBase92 constructor
|
||||||
|
*/
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.name = "From Base92";
|
||||||
|
this.module = "Default";
|
||||||
|
this.description = "Base92 is a notation for encoding arbitrary byte data using a restricted set of symbols that can be conveniently used by humans and processed by computers.";
|
||||||
|
this.infoURL = "https://wikipedia.org/wiki/List_of_numeral_systems";
|
||||||
|
this.inputType = "string";
|
||||||
|
this.outputType = "byteArray";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} input
|
||||||
|
* @param {Object[]} args
|
||||||
|
* @returns {byteArray}
|
||||||
|
*/
|
||||||
|
run(input, args) {
|
||||||
|
const res = [];
|
||||||
|
let bitString = "";
|
||||||
|
|
||||||
|
for (let i = 0; i < input.length; i += 2) {
|
||||||
|
if (i + 1 !== input.length) {
|
||||||
|
const x = base92Ord(input[i]) * 91 + base92Ord(input[i + 1]);
|
||||||
|
bitString += x.toString(2).padStart(13, "0");
|
||||||
|
} else {
|
||||||
|
const x = base92Ord(input[i]);
|
||||||
|
bitString += x.toString(2).padStart(6, "0");
|
||||||
|
}
|
||||||
|
while (bitString.length >= 8) {
|
||||||
|
res.push(parseInt(bitString.slice(0, 8), 2));
|
||||||
|
bitString = bitString.slice(8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default FromBase92;
|
67
src/core/operations/ToBase92.mjs
Normal file
67
src/core/operations/ToBase92.mjs
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
/**
|
||||||
|
* @author sg5506844 [sg5506844@gmail.com]
|
||||||
|
* @copyright Crown Copyright 2021
|
||||||
|
* @license Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { base92Chr } from "../lib/Base92.mjs";
|
||||||
|
import Operation from "../Operation.mjs";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To Base92 operation
|
||||||
|
*/
|
||||||
|
class ToBase92 extends Operation {
|
||||||
|
/**
|
||||||
|
* ToBase92 constructor
|
||||||
|
*/
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.name = "To Base92";
|
||||||
|
this.module = "Default";
|
||||||
|
this.description = "Base92 is a notation for encoding arbitrary byte data using a restricted set of symbols that can be conveniently used by humans and processed by computers.";
|
||||||
|
this.infoURL = "https://wikipedia.org/wiki/List_of_numeral_systems";
|
||||||
|
this.inputType = "string";
|
||||||
|
this.outputType = "byteArray";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} input
|
||||||
|
* @param {Object[]} args
|
||||||
|
* @returns {byteArray}
|
||||||
|
*/
|
||||||
|
run(input, args) {
|
||||||
|
const res = [];
|
||||||
|
let bitString = "";
|
||||||
|
|
||||||
|
while (input.length > 0) {
|
||||||
|
while (bitString.length < 13 && input.length > 0) {
|
||||||
|
bitString += input[0].charCodeAt(0).toString(2).padStart(8, "0");
|
||||||
|
input = input.slice(1);
|
||||||
|
}
|
||||||
|
if (bitString.length < 13)
|
||||||
|
break;
|
||||||
|
const i = parseInt(bitString.slice(0, 13), 2);
|
||||||
|
res.push(base92Chr(Math.floor(i / 91)));
|
||||||
|
res.push(base92Chr(i % 91));
|
||||||
|
bitString = bitString.slice(13);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bitString.length > 0) {
|
||||||
|
if (bitString.length < 7) {
|
||||||
|
bitString = bitString.padEnd(6, "0");
|
||||||
|
res.push(base92Chr(parseInt(bitString, 2)));
|
||||||
|
} else {
|
||||||
|
bitString = bitString.padEnd(13, "0");
|
||||||
|
const i = parseInt(bitString.slice(0, 13), 2);
|
||||||
|
res.push(base92Chr(Math.floor(i / 91)));
|
||||||
|
res.push(base92Chr(i % 91));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ToBase92;
|
|
@ -25,6 +25,7 @@ import "./tests/Base58.mjs";
|
||||||
import "./tests/Base64.mjs";
|
import "./tests/Base64.mjs";
|
||||||
import "./tests/Base62.mjs";
|
import "./tests/Base62.mjs";
|
||||||
import "./tests/Base85.mjs";
|
import "./tests/Base85.mjs";
|
||||||
|
import "./tests/Base92.mjs";
|
||||||
import "./tests/BitwiseOp.mjs";
|
import "./tests/BitwiseOp.mjs";
|
||||||
import "./tests/ByteRepr.mjs";
|
import "./tests/ByteRepr.mjs";
|
||||||
import "./tests/CartesianProduct.mjs";
|
import "./tests/CartesianProduct.mjs";
|
||||||
|
|
89
tests/operations/tests/Base92.mjs
Normal file
89
tests/operations/tests/Base92.mjs
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
/**
|
||||||
|
* Base92 tests.
|
||||||
|
*
|
||||||
|
* @author sg5506844 [sg5506844@gmail.com]
|
||||||
|
* @copyright Crown Copyright 2021
|
||||||
|
* @license Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import TestRegister from "../../lib/TestRegister.mjs";
|
||||||
|
|
||||||
|
TestRegister.addTests([
|
||||||
|
{
|
||||||
|
name: "To Base92: nothing",
|
||||||
|
input: "",
|
||||||
|
expectedOutput: "",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
op: "To Base92",
|
||||||
|
args: [],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "To Base92: Spec encoding example 1",
|
||||||
|
input: "AB",
|
||||||
|
expectedOutput: "8y2",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
op: "To Base92",
|
||||||
|
args: [],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "To Base92: Spec encoding example 2",
|
||||||
|
input: "Hello!!",
|
||||||
|
expectedOutput: ";K_$aOTo&",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
op: "To Base92",
|
||||||
|
args: [],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "To Base92: Spec encoding example 3",
|
||||||
|
input: "base-92",
|
||||||
|
expectedOutput: "DX2?V<Y(*",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
op: "To Base92",
|
||||||
|
args: [],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "From Base92: nothing",
|
||||||
|
input: "",
|
||||||
|
expectedOutput: "",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
op: "From Base92",
|
||||||
|
args: [],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "From Base92: Spec decoding example 1",
|
||||||
|
input: "G'_DW[B",
|
||||||
|
expectedOutput: "ietf!",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
op: "From Base92",
|
||||||
|
args: [],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "From Base92: Invalid character",
|
||||||
|
input: "~",
|
||||||
|
expectedOutput: "~ is not a base92 character",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
op: "From Base92",
|
||||||
|
args: [],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]);
|
Loading…
Add table
Add a link
Reference in a new issue