mirror of
https://github.com/gchq/CyberChef
synced 2024-11-15 00:57:08 +00:00
ESM: Added remaining Base64 ops and created a Base64 library. Added the prefer-const eslint rule.
This commit is contained in:
parent
9b4fc3d3aa
commit
041cd9fb8e
30 changed files with 986 additions and 825 deletions
|
@ -1 +1,2 @@
|
|||
src/core/vendor/**
|
||||
src/core/vendor/**
|
||||
src/core/operations/legacy/**
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 8,
|
||||
"ecmaVersion": 9,
|
||||
"ecmaFeatures": {
|
||||
"impliedStrict": true
|
||||
},
|
||||
|
@ -84,7 +84,8 @@
|
|||
"no-whitespace-before-property": "error",
|
||||
"operator-linebreak": ["error", "after"],
|
||||
"space-in-parens": "error",
|
||||
"no-var": "error"
|
||||
"no-var": "error",
|
||||
"prefer-const": "error"
|
||||
},
|
||||
"globals": {
|
||||
"$": false,
|
||||
|
|
|
@ -117,7 +117,7 @@ module.exports = function (grunt) {
|
|||
* Generates an entry list for all the modules.
|
||||
*/
|
||||
function listEntryModules() {
|
||||
let entryModules = {};
|
||||
const entryModules = {};
|
||||
|
||||
glob.sync("./src/core/config/modules/*.mjs").forEach(file => {
|
||||
const basename = path.basename(file);
|
||||
|
|
|
@ -121,9 +121,9 @@ class Chef {
|
|||
silentBake(recipeConfig) {
|
||||
log.debug("Running silent bake");
|
||||
|
||||
let startTime = new Date().getTime(),
|
||||
recipe = new Recipe(recipeConfig),
|
||||
dish = new Dish("", Dish.STRING);
|
||||
const startTime = new Date().getTime(),
|
||||
recipe = new Recipe(recipeConfig),
|
||||
dish = new Dish("", Dish.STRING);
|
||||
|
||||
try {
|
||||
recipe.execute(dish);
|
||||
|
|
|
@ -132,7 +132,7 @@ function silentBake(data) {
|
|||
*/
|
||||
function loadRequiredModules(recipeConfig) {
|
||||
recipeConfig.forEach(op => {
|
||||
let module = self.OperationConfig[op.op].module;
|
||||
const module = self.OperationConfig[op.op].module;
|
||||
|
||||
if (!OpModules.hasOwnProperty(module)) {
|
||||
log.info("Loading module " + module);
|
||||
|
|
|
@ -23,7 +23,7 @@ const FlowControl = {
|
|||
* @returns {Object} The updated state of the recipe.
|
||||
*/
|
||||
runFork: async function(state) {
|
||||
let opList = state.opList,
|
||||
const opList = state.opList,
|
||||
inputType = opList[state.progress].inputType,
|
||||
outputType = opList[state.progress].outputType,
|
||||
input = state.dish.get(inputType),
|
||||
|
@ -31,8 +31,8 @@ const FlowControl = {
|
|||
splitDelim = ings[0],
|
||||
mergeDelim = ings[1],
|
||||
ignoreErrors = ings[2],
|
||||
subOpList = [],
|
||||
inputs = [],
|
||||
subOpList = [];
|
||||
let inputs = [],
|
||||
i;
|
||||
|
||||
if (input)
|
||||
|
@ -48,8 +48,8 @@ const FlowControl = {
|
|||
}
|
||||
}
|
||||
|
||||
let recipe = new Recipe(),
|
||||
output = "",
|
||||
const recipe = new Recipe();
|
||||
let output = "",
|
||||
progress = 0;
|
||||
|
||||
state.forkOffset += state.progress + 1;
|
||||
|
@ -223,7 +223,7 @@ const FlowControl = {
|
|||
}
|
||||
|
||||
if (regexStr !== "") {
|
||||
let strMatch = dish.get(Dish.STRING).search(regexStr) > -1;
|
||||
const strMatch = dish.get(Dish.STRING).search(regexStr) > -1;
|
||||
if (!invert && strMatch || invert && !strMatch) {
|
||||
state.progress = jmpIndex;
|
||||
state.numJumps++;
|
||||
|
@ -274,9 +274,9 @@ const FlowControl = {
|
|||
*/
|
||||
_getLabelIndex: function(name, state) {
|
||||
for (let o = 0; o < state.opList.length; o++) {
|
||||
let operation = state.opList[o];
|
||||
const operation = state.opList[o];
|
||||
if (operation.name === "Label"){
|
||||
let ings = operation.ingValues;
|
||||
const ings = operation.ingValues;
|
||||
if (name === ings[0]) {
|
||||
return o;
|
||||
}
|
||||
|
|
|
@ -226,7 +226,7 @@ class Recipe {
|
|||
const highlights = [];
|
||||
|
||||
for (let i = 0; i < this.opList.length; i++) {
|
||||
let op = this.opList[i];
|
||||
const op = this.opList[i];
|
||||
if (op.disabled) continue;
|
||||
|
||||
// If any breakpoints are set, do not attempt to highlight
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
import utf8 from "utf8";
|
||||
import moment from "moment-timezone";
|
||||
import {fromBase64} from "./lib/Base64";
|
||||
|
||||
|
||||
/**
|
||||
|
@ -270,7 +271,7 @@ class Utils {
|
|||
if (i < alphStr.length - 2 &&
|
||||
alphStr[i+1] === "-" &&
|
||||
alphStr[i] !== "\\") {
|
||||
let start = Utils.ord(alphStr[i]),
|
||||
const start = Utils.ord(alphStr[i]),
|
||||
end = Utils.ord(alphStr[i+2]);
|
||||
|
||||
for (let j = start; j <= end; j++) {
|
||||
|
@ -313,7 +314,7 @@ class Utils {
|
|||
case "hex":
|
||||
return Utils.fromHex(str);
|
||||
case "base64":
|
||||
return Utils.fromBase64(str, null, "byteArray");
|
||||
return fromBase64(str, null, "byteArray");
|
||||
case "utf8":
|
||||
return Utils.strToUtf8ByteArray(str);
|
||||
case "latin1":
|
||||
|
@ -346,7 +347,7 @@ class Utils {
|
|||
case "hex":
|
||||
return Utils.byteArrayToChars(Utils.fromHex(str));
|
||||
case "base64":
|
||||
return Utils.byteArrayToChars(Utils.fromBase64(str, null, "byteArray"));
|
||||
return Utils.byteArrayToChars(fromBase64(str, null, "byteArray"));
|
||||
case "utf8":
|
||||
return utf8.encode(str);
|
||||
case "latin1":
|
||||
|
@ -518,118 +519,6 @@ class Utils {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Base64's the input byte array using the given alphabet, returning a string.
|
||||
*
|
||||
* @param {byteArray|Uint8Array|string} data
|
||||
* @param {string} [alphabet="A-Za-z0-9+/="]
|
||||
* @returns {string}
|
||||
*
|
||||
* @example
|
||||
* // returns "SGVsbG8="
|
||||
* Utils.toBase64([72, 101, 108, 108, 111]);
|
||||
*
|
||||
* // returns "SGVsbG8="
|
||||
* Utils.toBase64("Hello");
|
||||
*/
|
||||
static toBase64(data, alphabet="A-Za-z0-9+/=") {
|
||||
if (!data) return "";
|
||||
if (typeof data == "string") {
|
||||
data = Utils.strToByteArray(data);
|
||||
}
|
||||
|
||||
alphabet = Utils.expandAlphRange(alphabet).join("");
|
||||
|
||||
let output = "",
|
||||
chr1, chr2, chr3,
|
||||
enc1, enc2, enc3, enc4,
|
||||
i = 0;
|
||||
|
||||
while (i < data.length) {
|
||||
chr1 = data[i++];
|
||||
chr2 = data[i++];
|
||||
chr3 = data[i++];
|
||||
|
||||
enc1 = chr1 >> 2;
|
||||
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
|
||||
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
|
||||
enc4 = chr3 & 63;
|
||||
|
||||
if (isNaN(chr2)) {
|
||||
enc3 = enc4 = 64;
|
||||
} else if (isNaN(chr3)) {
|
||||
enc4 = 64;
|
||||
}
|
||||
|
||||
output += alphabet.charAt(enc1) + alphabet.charAt(enc2) +
|
||||
alphabet.charAt(enc3) + alphabet.charAt(enc4);
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* UnBase64's the input string using the given alphabet, returning a byte array.
|
||||
*
|
||||
* @param {byteArray} data
|
||||
* @param {string} [alphabet="A-Za-z0-9+/="]
|
||||
* @param {string} [returnType="string"] - Either "string" or "byteArray"
|
||||
* @param {boolean} [removeNonAlphChars=true]
|
||||
* @returns {byteArray}
|
||||
*
|
||||
* @example
|
||||
* // returns "Hello"
|
||||
* Utils.fromBase64("SGVsbG8=");
|
||||
*
|
||||
* // returns [72, 101, 108, 108, 111]
|
||||
* Utils.fromBase64("SGVsbG8=", null, "byteArray");
|
||||
*/
|
||||
static fromBase64(data, alphabet="A-Za-z0-9+/=", returnType="string", removeNonAlphChars=true) {
|
||||
if (!data) {
|
||||
return returnType === "string" ? "" : [];
|
||||
}
|
||||
|
||||
alphabet = Utils.expandAlphRange(alphabet).join("");
|
||||
|
||||
let output = [],
|
||||
chr1, chr2, chr3,
|
||||
enc1, enc2, enc3, enc4,
|
||||
i = 0;
|
||||
|
||||
if (removeNonAlphChars) {
|
||||
const re = new RegExp("[^" + alphabet.replace(/[[\]\\\-^$]/g, "\\$&") + "]", "g");
|
||||
data = data.replace(re, "");
|
||||
}
|
||||
|
||||
while (i < data.length) {
|
||||
enc1 = alphabet.indexOf(data.charAt(i++));
|
||||
enc2 = alphabet.indexOf(data.charAt(i++) || "=");
|
||||
enc3 = alphabet.indexOf(data.charAt(i++) || "=");
|
||||
enc4 = alphabet.indexOf(data.charAt(i++) || "=");
|
||||
|
||||
enc2 = enc2 === -1 ? 64 : enc2;
|
||||
enc3 = enc3 === -1 ? 64 : enc3;
|
||||
enc4 = enc4 === -1 ? 64 : enc4;
|
||||
|
||||
chr1 = (enc1 << 2) | (enc2 >> 4);
|
||||
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
|
||||
chr3 = ((enc3 & 3) << 6) | enc4;
|
||||
|
||||
output.push(chr1);
|
||||
|
||||
if (enc3 !== 64) {
|
||||
output.push(chr2);
|
||||
}
|
||||
if (enc4 !== 64) {
|
||||
output.push(chr3);
|
||||
}
|
||||
}
|
||||
|
||||
return returnType === "string" ? Utils.byteArrayToUtf8(output) : output;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert a byte array into a hex string.
|
||||
*
|
||||
|
@ -734,8 +623,8 @@ class Utils {
|
|||
ignoreNext = false,
|
||||
inString = false,
|
||||
cell = "",
|
||||
line = [],
|
||||
lines = [];
|
||||
line = [];
|
||||
const lines = [];
|
||||
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
b = data[i];
|
||||
|
@ -952,10 +841,9 @@ class Utils {
|
|||
|
||||
// Parse bespoke recipe format
|
||||
recipe = recipe.replace(/\n/g, "");
|
||||
let m,
|
||||
recipeRegex = /([^(]+)\(((?:'[^'\\]*(?:\\.[^'\\]*)*'|[^)/'])*)(\/[^)]+)?\)/g,
|
||||
recipeConfig = [],
|
||||
args;
|
||||
let m, args;
|
||||
const recipeRegex = /([^(]+)\(((?:'[^'\\]*(?:\\.[^'\\]*)*'|[^)/'])*)(\/[^)]+)?\)/g,
|
||||
recipeConfig = [];
|
||||
|
||||
while ((m = recipeRegex.exec(recipe))) {
|
||||
// Translate strings in args back to double-quotes
|
||||
|
@ -966,7 +854,7 @@ class Utils {
|
|||
.replace(/\\'/g, "'"); // Unescape single quotes
|
||||
args = "[" + args + "]";
|
||||
|
||||
let op = {
|
||||
const op = {
|
||||
op: m[1].replace(/_/g, " "),
|
||||
args: JSON.parse(args)
|
||||
};
|
||||
|
@ -1252,7 +1140,7 @@ export default Utils;
|
|||
* ["One", "Two", "Three", "One"].unique();
|
||||
*/
|
||||
Array.prototype.unique = function() {
|
||||
let u = {}, a = [];
|
||||
const u = {}, a = [];
|
||||
for (let i = 0, l = this.length; i < l; i++) {
|
||||
if (u.hasOwnProperty(this[i])) {
|
||||
continue;
|
||||
|
|
|
@ -21,340 +21,340 @@ const Categories = [
|
|||
{
|
||||
name: "Favourites",
|
||||
ops: []
|
||||
}/*,
|
||||
},
|
||||
{
|
||||
name: "Data format",
|
||||
ops: [
|
||||
"To Hexdump",
|
||||
"From Hexdump",
|
||||
"To Hex",
|
||||
"From Hex",
|
||||
"To Charcode",
|
||||
"From Charcode",
|
||||
"To Decimal",
|
||||
"From Decimal",
|
||||
"To Binary",
|
||||
"From Binary",
|
||||
"To Octal",
|
||||
"From Octal",
|
||||
// "To Hexdump",
|
||||
// "From Hexdump",
|
||||
// "To Hex",
|
||||
// "From Hex",
|
||||
// "To Charcode",
|
||||
// "From Charcode",
|
||||
// "To Decimal",
|
||||
// "From Decimal",
|
||||
// "To Binary",
|
||||
// "From Binary",
|
||||
// "To Octal",
|
||||
// "From Octal",
|
||||
"To Base64",
|
||||
"From Base64",
|
||||
"Show Base64 offsets",
|
||||
"To Base32",
|
||||
"From Base32",
|
||||
"To Base58",
|
||||
"From Base58",
|
||||
"To Base",
|
||||
"From Base",
|
||||
"To BCD",
|
||||
"From BCD",
|
||||
"To HTML Entity",
|
||||
"From HTML Entity",
|
||||
"URL Encode",
|
||||
"URL Decode",
|
||||
"Escape Unicode Characters",
|
||||
"Unescape Unicode Characters",
|
||||
"To Quoted Printable",
|
||||
"From Quoted Printable",
|
||||
"To Punycode",
|
||||
"From Punycode",
|
||||
"To Hex Content",
|
||||
"From Hex Content",
|
||||
"PEM to Hex",
|
||||
"Hex to PEM",
|
||||
"Parse ASN.1 hex string",
|
||||
"Change IP format",
|
||||
"Encode text",
|
||||
"Decode text",
|
||||
"Swap endianness",
|
||||
// "To Base58",
|
||||
// "From Base58",
|
||||
// "To Base",
|
||||
// "From Base",
|
||||
// "To BCD",
|
||||
// "From BCD",
|
||||
// "To HTML Entity",
|
||||
// "From HTML Entity",
|
||||
// "URL Encode",
|
||||
// "URL Decode",
|
||||
// "Escape Unicode Characters",
|
||||
// "Unescape Unicode Characters",
|
||||
// "To Quoted Printable",
|
||||
// "From Quoted Printable",
|
||||
// "To Punycode",
|
||||
// "From Punycode",
|
||||
// "To Hex Content",
|
||||
// "From Hex Content",
|
||||
// "PEM to Hex",
|
||||
// "Hex to PEM",
|
||||
// "Parse ASN.1 hex string",
|
||||
// "Change IP format",
|
||||
// "Encode text",
|
||||
// "Decode text",
|
||||
// "Swap endianness",
|
||||
// ]
|
||||
// },
|
||||
// {
|
||||
// name: "Encryption / Encoding",
|
||||
// ops: [
|
||||
// "AES Encrypt",
|
||||
// "AES Decrypt",
|
||||
// "Blowfish Encrypt",
|
||||
// "Blowfish Decrypt",
|
||||
// "DES Encrypt",
|
||||
// "DES Decrypt",
|
||||
// "Triple DES Encrypt",
|
||||
// "Triple DES Decrypt",
|
||||
// "RC2 Encrypt",
|
||||
// "RC2 Decrypt",
|
||||
// "RC4",
|
||||
// "RC4 Drop",
|
||||
// "ROT13",
|
||||
// "ROT47",
|
||||
// "XOR",
|
||||
// "XOR Brute Force",
|
||||
// "Vigenère Encode",
|
||||
// "Vigenère Decode",
|
||||
// "To Morse Code",
|
||||
// "From Morse Code",
|
||||
// "Bifid Cipher Encode",
|
||||
// "Bifid Cipher Decode",
|
||||
// "Affine Cipher Encode",
|
||||
// "Affine Cipher Decode",
|
||||
// "Atbash Cipher",
|
||||
// "Substitute",
|
||||
// "Derive PBKDF2 key",
|
||||
// "Derive EVP key",
|
||||
// "Bcrypt",
|
||||
// "Scrypt",
|
||||
// "Pseudo-Random Number Generator",
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Encryption / Encoding",
|
||||
ops: [
|
||||
"AES Encrypt",
|
||||
"AES Decrypt",
|
||||
"Blowfish Encrypt",
|
||||
"Blowfish Decrypt",
|
||||
"DES Encrypt",
|
||||
"DES Decrypt",
|
||||
"Triple DES Encrypt",
|
||||
"Triple DES Decrypt",
|
||||
"RC2 Encrypt",
|
||||
"RC2 Decrypt",
|
||||
"RC4",
|
||||
"RC4 Drop",
|
||||
"ROT13",
|
||||
"ROT47",
|
||||
"XOR",
|
||||
"XOR Brute Force",
|
||||
"Vigenère Encode",
|
||||
"Vigenère Decode",
|
||||
"To Morse Code",
|
||||
"From Morse Code",
|
||||
"Bifid Cipher Encode",
|
||||
"Bifid Cipher Decode",
|
||||
"Affine Cipher Encode",
|
||||
"Affine Cipher Decode",
|
||||
"Atbash Cipher",
|
||||
"Substitute",
|
||||
"Derive PBKDF2 key",
|
||||
"Derive EVP key",
|
||||
"Bcrypt",
|
||||
"Scrypt",
|
||||
"Pseudo-Random Number Generator",
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Public Key",
|
||||
ops: [
|
||||
"Parse X.509 certificate",
|
||||
"Parse ASN.1 hex string",
|
||||
"PEM to Hex",
|
||||
"Hex to PEM",
|
||||
"Hex to Object Identifier",
|
||||
"Object Identifier to Hex",
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Arithmetic / Logic",
|
||||
ops: [
|
||||
"XOR",
|
||||
"XOR Brute Force",
|
||||
"OR",
|
||||
"NOT",
|
||||
"AND",
|
||||
"ADD",
|
||||
"SUB",
|
||||
"Sum",
|
||||
"Subtract",
|
||||
"Multiply",
|
||||
"Divide",
|
||||
"Mean",
|
||||
"Median",
|
||||
"Standard Deviation",
|
||||
"Bit shift left",
|
||||
"Bit shift right",
|
||||
"Rotate left",
|
||||
"Rotate right",
|
||||
"ROT13",
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Networking",
|
||||
ops: [
|
||||
"HTTP request",
|
||||
"Strip HTTP headers",
|
||||
"Parse User Agent",
|
||||
"Parse IP range",
|
||||
"Parse IPv6 address",
|
||||
"Parse IPv4 header",
|
||||
"Parse URI",
|
||||
"URL Encode",
|
||||
"URL Decode",
|
||||
"Format MAC addresses",
|
||||
"Change IP format",
|
||||
"Group IP addresses",
|
||||
"Encode NetBIOS Name",
|
||||
"Decode NetBIOS Name",
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Language",
|
||||
ops: [
|
||||
"Encode text",
|
||||
"Decode text",
|
||||
"Unescape Unicode Characters",
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Utils",
|
||||
ops: [
|
||||
"Diff",
|
||||
"Remove whitespace",
|
||||
"Remove null bytes",
|
||||
"To Upper case",
|
||||
"To Lower case",
|
||||
"Add line numbers",
|
||||
"Remove line numbers",
|
||||
"Reverse",
|
||||
"Sort",
|
||||
"Unique",
|
||||
"Split",
|
||||
"Filter",
|
||||
"Head",
|
||||
"Tail",
|
||||
"Count occurrences",
|
||||
"Expand alphabet range",
|
||||
"Drop bytes",
|
||||
"Take bytes",
|
||||
"Pad lines",
|
||||
"Find / Replace",
|
||||
"Regular expression",
|
||||
"Offset checker",
|
||||
"Hamming Distance",
|
||||
"Convert distance",
|
||||
"Convert area",
|
||||
"Convert mass",
|
||||
"Convert speed",
|
||||
"Convert data units",
|
||||
"Parse UNIX file permissions",
|
||||
"Swap endianness",
|
||||
"Parse colour code",
|
||||
"Escape string",
|
||||
"Unescape string",
|
||||
"Pseudo-Random Number Generator",
|
||||
"Sleep",
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Date / Time",
|
||||
ops: [
|
||||
"Parse DateTime",
|
||||
"Translate DateTime Format",
|
||||
"From UNIX Timestamp",
|
||||
"To UNIX Timestamp",
|
||||
"Windows Filetime to UNIX Timestamp",
|
||||
"UNIX Timestamp to Windows Filetime",
|
||||
"Extract dates",
|
||||
"Sleep",
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Extractors",
|
||||
ops: [
|
||||
"Strings",
|
||||
"Extract IP addresses",
|
||||
"Extract email addresses",
|
||||
"Extract MAC addresses",
|
||||
"Extract URLs",
|
||||
"Extract domains",
|
||||
"Extract file paths",
|
||||
"Extract dates",
|
||||
"Regular expression",
|
||||
"XPath expression",
|
||||
"JPath expression",
|
||||
"CSS selector",
|
||||
"Extract EXIF",
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Compression",
|
||||
ops: [
|
||||
"Raw Deflate",
|
||||
"Raw Inflate",
|
||||
"Zlib Deflate",
|
||||
"Zlib Inflate",
|
||||
"Gzip",
|
||||
"Gunzip",
|
||||
"Zip",
|
||||
"Unzip",
|
||||
"Bzip2 Decompress",
|
||||
"Tar",
|
||||
"Untar",
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Hashing",
|
||||
ops: [
|
||||
"Analyse hash",
|
||||
"Generate all hashes",
|
||||
"MD2",
|
||||
"MD4",
|
||||
"MD5",
|
||||
"MD6",
|
||||
"SHA0",
|
||||
"SHA1",
|
||||
"SHA2",
|
||||
"SHA3",
|
||||
"Keccak",
|
||||
"Shake",
|
||||
"RIPEMD",
|
||||
"HAS-160",
|
||||
"Whirlpool",
|
||||
"Snefru",
|
||||
"SSDEEP",
|
||||
"CTPH",
|
||||
"Compare SSDEEP hashes",
|
||||
"Compare CTPH hashes",
|
||||
"HMAC",
|
||||
"Bcrypt",
|
||||
"Bcrypt compare",
|
||||
"Bcrypt parse",
|
||||
"Scrypt",
|
||||
"Fletcher-8 Checksum",
|
||||
"Fletcher-16 Checksum",
|
||||
"Fletcher-32 Checksum",
|
||||
"Fletcher-64 Checksum",
|
||||
"Adler-32 Checksum",
|
||||
"CRC-16 Checksum",
|
||||
"CRC-32 Checksum",
|
||||
"TCP/IP Checksum",
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Code tidy",
|
||||
ops: [
|
||||
"Syntax highlighter",
|
||||
"Generic Code Beautify",
|
||||
"JavaScript Parser",
|
||||
"JavaScript Beautify",
|
||||
"JavaScript Minify",
|
||||
"JSON Beautify",
|
||||
"JSON Minify",
|
||||
"XML Beautify",
|
||||
"XML Minify",
|
||||
"SQL Beautify",
|
||||
"SQL Minify",
|
||||
"CSS Beautify",
|
||||
"CSS Minify",
|
||||
"XPath expression",
|
||||
"JPath expression",
|
||||
"CSS selector",
|
||||
"PHP Deserialize",
|
||||
"Microsoft Script Decoder",
|
||||
"Strip HTML tags",
|
||||
"Diff",
|
||||
"To Snake case",
|
||||
"To Camel case",
|
||||
"To Kebab case",
|
||||
"BSON serialise",
|
||||
"BSON deserialise",
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Other",
|
||||
ops: [
|
||||
"Entropy",
|
||||
"Frequency distribution",
|
||||
"Chi Square",
|
||||
"Detect File Type",
|
||||
"Scan for Embedded Files",
|
||||
"Disassemble x86",
|
||||
"Pseudo-Random Number Generator",
|
||||
"Generate UUID",
|
||||
"Generate TOTP",
|
||||
"Generate HOTP",
|
||||
"Render Image",
|
||||
"Remove EXIF",
|
||||
"Extract EXIF",
|
||||
"Numberwang",
|
||||
"XKCD Random Number",
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Flow control",
|
||||
ops: [
|
||||
"Fork",
|
||||
"Merge",
|
||||
"Register",
|
||||
"Label",
|
||||
"Jump",
|
||||
"Conditional Jump",
|
||||
"Return",
|
||||
"Comment"
|
||||
]
|
||||
},*/
|
||||
// {
|
||||
// name: "Public Key",
|
||||
// ops: [
|
||||
// "Parse X.509 certificate",
|
||||
// "Parse ASN.1 hex string",
|
||||
// "PEM to Hex",
|
||||
// "Hex to PEM",
|
||||
// "Hex to Object Identifier",
|
||||
// "Object Identifier to Hex",
|
||||
// ]
|
||||
// },
|
||||
// {
|
||||
// name: "Arithmetic / Logic",
|
||||
// ops: [
|
||||
// "XOR",
|
||||
// "XOR Brute Force",
|
||||
// "OR",
|
||||
// "NOT",
|
||||
// "AND",
|
||||
// "ADD",
|
||||
// "SUB",
|
||||
// "Sum",
|
||||
// "Subtract",
|
||||
// "Multiply",
|
||||
// "Divide",
|
||||
// "Mean",
|
||||
// "Median",
|
||||
// "Standard Deviation",
|
||||
// "Bit shift left",
|
||||
// "Bit shift right",
|
||||
// "Rotate left",
|
||||
// "Rotate right",
|
||||
// "ROT13",
|
||||
// ]
|
||||
// },
|
||||
// {
|
||||
// name: "Networking",
|
||||
// ops: [
|
||||
// "HTTP request",
|
||||
// "Strip HTTP headers",
|
||||
// "Parse User Agent",
|
||||
// "Parse IP range",
|
||||
// "Parse IPv6 address",
|
||||
// "Parse IPv4 header",
|
||||
// "Parse URI",
|
||||
// "URL Encode",
|
||||
// "URL Decode",
|
||||
// "Format MAC addresses",
|
||||
// "Change IP format",
|
||||
// "Group IP addresses",
|
||||
// "Encode NetBIOS Name",
|
||||
// "Decode NetBIOS Name",
|
||||
// ]
|
||||
// },
|
||||
// {
|
||||
// name: "Language",
|
||||
// ops: [
|
||||
// "Encode text",
|
||||
// "Decode text",
|
||||
// "Unescape Unicode Characters",
|
||||
// ]
|
||||
// },
|
||||
// {
|
||||
// name: "Utils",
|
||||
// ops: [
|
||||
// "Diff",
|
||||
// "Remove whitespace",
|
||||
// "Remove null bytes",
|
||||
// "To Upper case",
|
||||
// "To Lower case",
|
||||
// "Add line numbers",
|
||||
// "Remove line numbers",
|
||||
// "Reverse",
|
||||
// "Sort",
|
||||
// "Unique",
|
||||
// "Split",
|
||||
// "Filter",
|
||||
// "Head",
|
||||
// "Tail",
|
||||
// "Count occurrences",
|
||||
// "Expand alphabet range",
|
||||
// "Drop bytes",
|
||||
// "Take bytes",
|
||||
// "Pad lines",
|
||||
// "Find / Replace",
|
||||
// "Regular expression",
|
||||
// "Offset checker",
|
||||
// "Hamming Distance",
|
||||
// "Convert distance",
|
||||
// "Convert area",
|
||||
// "Convert mass",
|
||||
// "Convert speed",
|
||||
// "Convert data units",
|
||||
// "Parse UNIX file permissions",
|
||||
// "Swap endianness",
|
||||
// "Parse colour code",
|
||||
// "Escape string",
|
||||
// "Unescape string",
|
||||
// "Pseudo-Random Number Generator",
|
||||
// "Sleep",
|
||||
// ]
|
||||
// },
|
||||
// {
|
||||
// name: "Date / Time",
|
||||
// ops: [
|
||||
// "Parse DateTime",
|
||||
// "Translate DateTime Format",
|
||||
// "From UNIX Timestamp",
|
||||
// "To UNIX Timestamp",
|
||||
// "Windows Filetime to UNIX Timestamp",
|
||||
// "UNIX Timestamp to Windows Filetime",
|
||||
// "Extract dates",
|
||||
// "Sleep",
|
||||
// ]
|
||||
// },
|
||||
// {
|
||||
// name: "Extractors",
|
||||
// ops: [
|
||||
// "Strings",
|
||||
// "Extract IP addresses",
|
||||
// "Extract email addresses",
|
||||
// "Extract MAC addresses",
|
||||
// "Extract URLs",
|
||||
// "Extract domains",
|
||||
// "Extract file paths",
|
||||
// "Extract dates",
|
||||
// "Regular expression",
|
||||
// "XPath expression",
|
||||
// "JPath expression",
|
||||
// "CSS selector",
|
||||
// "Extract EXIF",
|
||||
// ]
|
||||
// },
|
||||
// {
|
||||
// name: "Compression",
|
||||
// ops: [
|
||||
// "Raw Deflate",
|
||||
// "Raw Inflate",
|
||||
// "Zlib Deflate",
|
||||
// "Zlib Inflate",
|
||||
// "Gzip",
|
||||
// "Gunzip",
|
||||
// "Zip",
|
||||
// "Unzip",
|
||||
// "Bzip2 Decompress",
|
||||
// "Tar",
|
||||
// "Untar",
|
||||
// ]
|
||||
// },
|
||||
// {
|
||||
// name: "Hashing",
|
||||
// ops: [
|
||||
// "Analyse hash",
|
||||
// "Generate all hashes",
|
||||
// "MD2",
|
||||
// "MD4",
|
||||
// "MD5",
|
||||
// "MD6",
|
||||
// "SHA0",
|
||||
// "SHA1",
|
||||
// "SHA2",
|
||||
// "SHA3",
|
||||
// "Keccak",
|
||||
// "Shake",
|
||||
// "RIPEMD",
|
||||
// "HAS-160",
|
||||
// "Whirlpool",
|
||||
// "Snefru",
|
||||
// "SSDEEP",
|
||||
// "CTPH",
|
||||
// "Compare SSDEEP hashes",
|
||||
// "Compare CTPH hashes",
|
||||
// "HMAC",
|
||||
// "Bcrypt",
|
||||
// "Bcrypt compare",
|
||||
// "Bcrypt parse",
|
||||
// "Scrypt",
|
||||
// "Fletcher-8 Checksum",
|
||||
// "Fletcher-16 Checksum",
|
||||
// "Fletcher-32 Checksum",
|
||||
// "Fletcher-64 Checksum",
|
||||
// "Adler-32 Checksum",
|
||||
// "CRC-16 Checksum",
|
||||
// "CRC-32 Checksum",
|
||||
// "TCP/IP Checksum",
|
||||
// ]
|
||||
// },
|
||||
// {
|
||||
// name: "Code tidy",
|
||||
// ops: [
|
||||
// "Syntax highlighter",
|
||||
// "Generic Code Beautify",
|
||||
// "JavaScript Parser",
|
||||
// "JavaScript Beautify",
|
||||
// "JavaScript Minify",
|
||||
// "JSON Beautify",
|
||||
// "JSON Minify",
|
||||
// "XML Beautify",
|
||||
// "XML Minify",
|
||||
// "SQL Beautify",
|
||||
// "SQL Minify",
|
||||
// "CSS Beautify",
|
||||
// "CSS Minify",
|
||||
// "XPath expression",
|
||||
// "JPath expression",
|
||||
// "CSS selector",
|
||||
// "PHP Deserialize",
|
||||
// "Microsoft Script Decoder",
|
||||
// "Strip HTML tags",
|
||||
// "Diff",
|
||||
// "To Snake case",
|
||||
// "To Camel case",
|
||||
// "To Kebab case",
|
||||
// "BSON serialise",
|
||||
// "BSON deserialise",
|
||||
// ]
|
||||
// },
|
||||
// {
|
||||
// name: "Other",
|
||||
// ops: [
|
||||
// "Entropy",
|
||||
// "Frequency distribution",
|
||||
// "Chi Square",
|
||||
// "Detect File Type",
|
||||
// "Scan for Embedded Files",
|
||||
// "Disassemble x86",
|
||||
// "Pseudo-Random Number Generator",
|
||||
// "Generate UUID",
|
||||
// "Generate TOTP",
|
||||
// "Generate HOTP",
|
||||
// "Render Image",
|
||||
// "Remove EXIF",
|
||||
// "Extract EXIF",
|
||||
// "Numberwang",
|
||||
// "XKCD Random Number",
|
||||
// ]
|
||||
// },
|
||||
// {
|
||||
// name: "Flow control",
|
||||
// ops: [
|
||||
// "Fork",
|
||||
// "Merge",
|
||||
// "Register",
|
||||
// "Label",
|
||||
// "Jump",
|
||||
// "Conditional Jump",
|
||||
// "Return",
|
||||
// "Comment"
|
||||
// ]
|
||||
// },
|
||||
];
|
||||
|
||||
export default Categories;
|
||||
|
|
|
@ -1,68 +1,20 @@
|
|||
{
|
||||
"To Base64": {
|
||||
"From Base32": {
|
||||
"module": "Default",
|
||||
"description": "Base64 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.<br><br>This operation decodes data from an ASCII Base64 string back into its raw format.<br><br>e.g. <code>aGVsbG8=</code> becomes <code>hello</code>",
|
||||
"inputType": "ArrayBuffer",
|
||||
"outputType": "string",
|
||||
"description": "Base32 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. It uses a smaller set of characters than Base64, usually the uppercase alphabet and the numbers 2 to 7.",
|
||||
"inputType": "string",
|
||||
"outputType": "byteArray",
|
||||
"flowControl": false,
|
||||
"args": [
|
||||
{
|
||||
"name": "Alphabet",
|
||||
"type": "editableOption",
|
||||
"value": [
|
||||
{
|
||||
"name": "Standard: A-Za-z0-9+/=",
|
||||
"value": "A-Za-z0-9+/="
|
||||
},
|
||||
{
|
||||
"name": "URL safe: A-Za-z0-9-_",
|
||||
"value": "A-Za-z0-9-_"
|
||||
},
|
||||
{
|
||||
"name": "Filename safe: A-Za-z0-9+-=",
|
||||
"value": "A-Za-z0-9+\\-="
|
||||
},
|
||||
{
|
||||
"name": "itoa64: ./0-9A-Za-z=",
|
||||
"value": "./0-9A-Za-z="
|
||||
},
|
||||
{
|
||||
"name": "XML: A-Za-z0-9_.",
|
||||
"value": "A-Za-z0-9_."
|
||||
},
|
||||
{
|
||||
"name": "y64: A-Za-z0-9._-",
|
||||
"value": "A-Za-z0-9._-"
|
||||
},
|
||||
{
|
||||
"name": "z64: 0-9a-zA-Z+/=",
|
||||
"value": "0-9a-zA-Z+/="
|
||||
},
|
||||
{
|
||||
"name": "Radix-64: 0-9A-Za-z+/=",
|
||||
"value": "0-9A-Za-z+/="
|
||||
},
|
||||
{
|
||||
"name": "Uuencoding: [space]-_",
|
||||
"value": " -_"
|
||||
},
|
||||
{
|
||||
"name": "Xxencoding: +-0-9A-Za-z",
|
||||
"value": "+\\-0-9A-Za-z"
|
||||
},
|
||||
{
|
||||
"name": "BinHex: !-,-0-689@A-NP-VX-Z[`a-fh-mp-r",
|
||||
"value": "!-,-0-689@A-NP-VX-Z[`a-fh-mp-r"
|
||||
},
|
||||
{
|
||||
"name": "ROT13: N-ZA-Mn-za-m0-9+/=",
|
||||
"value": "N-ZA-Mn-za-m0-9+/="
|
||||
},
|
||||
{
|
||||
"name": "UNIX crypt: ./0-9A-Za-z",
|
||||
"value": "./0-9A-Za-z"
|
||||
}
|
||||
]
|
||||
"type": "binaryString",
|
||||
"value": "A-Z2-7="
|
||||
},
|
||||
{
|
||||
"name": "Remove non-alphabet chars",
|
||||
"type": "boolean",
|
||||
"value": true
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -137,5 +89,105 @@
|
|||
"value": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"Show Base64 offsets": {
|
||||
"module": "Default",
|
||||
"description": "When a string is within a block of data and the whole block is Base64'd, the string itself could be represented in Base64 in three distinct ways depending on its offset within the block.<br><br>This operation shows all possible offsets for a given string so that each possible encoding can be considered.",
|
||||
"inputType": "byteArray",
|
||||
"outputType": "html",
|
||||
"flowControl": false,
|
||||
"args": [
|
||||
{
|
||||
"name": "Alphabet",
|
||||
"type": "binaryString",
|
||||
"value": "A-Za-z0-9+/="
|
||||
},
|
||||
{
|
||||
"name": "Show variable chars and padding",
|
||||
"type": "boolean",
|
||||
"value": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"To Base32": {
|
||||
"module": "Default",
|
||||
"description": "Base32 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. It uses a smaller set of characters than Base64, usually the uppercase alphabet and the numbers 2 to 7.",
|
||||
"inputType": "byteArray",
|
||||
"outputType": "string",
|
||||
"flowControl": false,
|
||||
"args": [
|
||||
{
|
||||
"name": "Alphabet",
|
||||
"type": "binaryString",
|
||||
"value": "A-Z2-7="
|
||||
}
|
||||
]
|
||||
},
|
||||
"To Base64": {
|
||||
"module": "Default",
|
||||
"description": "Base64 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.<br><br>This operation decodes data from an ASCII Base64 string back into its raw format.<br><br>e.g. <code>aGVsbG8=</code> becomes <code>hello</code>",
|
||||
"inputType": "ArrayBuffer",
|
||||
"outputType": "string",
|
||||
"flowControl": false,
|
||||
"args": [
|
||||
{
|
||||
"name": "Alphabet",
|
||||
"type": "editableOption",
|
||||
"value": [
|
||||
{
|
||||
"name": "Standard: A-Za-z0-9+/=",
|
||||
"value": "A-Za-z0-9+/="
|
||||
},
|
||||
{
|
||||
"name": "URL safe: A-Za-z0-9-_",
|
||||
"value": "A-Za-z0-9-_"
|
||||
},
|
||||
{
|
||||
"name": "Filename safe: A-Za-z0-9+-=",
|
||||
"value": "A-Za-z0-9+\\-="
|
||||
},
|
||||
{
|
||||
"name": "itoa64: ./0-9A-Za-z=",
|
||||
"value": "./0-9A-Za-z="
|
||||
},
|
||||
{
|
||||
"name": "XML: A-Za-z0-9_.",
|
||||
"value": "A-Za-z0-9_."
|
||||
},
|
||||
{
|
||||
"name": "y64: A-Za-z0-9._-",
|
||||
"value": "A-Za-z0-9._-"
|
||||
},
|
||||
{
|
||||
"name": "z64: 0-9a-zA-Z+/=",
|
||||
"value": "0-9a-zA-Z+/="
|
||||
},
|
||||
{
|
||||
"name": "Radix-64: 0-9A-Za-z+/=",
|
||||
"value": "0-9A-Za-z+/="
|
||||
},
|
||||
{
|
||||
"name": "Uuencoding: [space]-_",
|
||||
"value": " -_"
|
||||
},
|
||||
{
|
||||
"name": "Xxencoding: +-0-9A-Za-z",
|
||||
"value": "+\\-0-9A-Za-z"
|
||||
},
|
||||
{
|
||||
"name": "BinHex: !-,-0-689@A-NP-VX-Z[`a-fh-mp-r",
|
||||
"value": "!-,-0-689@A-NP-VX-Z[`a-fh-mp-r"
|
||||
},
|
||||
{
|
||||
"name": "ROT13: N-ZA-Mn-za-m0-9+/=",
|
||||
"value": "N-ZA-Mn-za-m0-9+/="
|
||||
},
|
||||
{
|
||||
"name": "UNIX crypt: ./0-9A-Za-z",
|
||||
"value": "./0-9A-Za-z"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
|
@ -14,7 +14,7 @@
|
|||
import path from "path";
|
||||
import fs from "fs";
|
||||
import process from "process";
|
||||
import OpIndex from "../operations/index";
|
||||
import * as Ops from "../operations/index";
|
||||
|
||||
const dir = path.join(process.cwd() + "/src/core/config/");
|
||||
if (!fs.existsSync(dir)) {
|
||||
|
@ -25,14 +25,14 @@ if (!fs.existsSync(dir)) {
|
|||
}
|
||||
|
||||
|
||||
let operationConfig = {},
|
||||
const operationConfig = {},
|
||||
modules = {};
|
||||
|
||||
/**
|
||||
* Generate operation config and module lists.
|
||||
*/
|
||||
OpIndex.forEach(opObj => {
|
||||
const op = new opObj();
|
||||
for (const opObj in Ops) {
|
||||
const op = new Ops[opObj]();
|
||||
|
||||
operationConfig[op.name] = {
|
||||
module: op.module,
|
||||
|
@ -45,8 +45,8 @@ OpIndex.forEach(opObj => {
|
|||
|
||||
if (!modules.hasOwnProperty(op.module))
|
||||
modules[op.module] = {};
|
||||
modules[op.module][op.name] = op.name.replace(/\s/g, "");
|
||||
});
|
||||
modules[op.module][op.name] = opObj;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
@ -67,7 +67,7 @@ fs.writeFile(
|
|||
/**
|
||||
* Write modules.
|
||||
*/
|
||||
for (let module in modules) {
|
||||
for (const module in modules) {
|
||||
let code = `/**
|
||||
* THIS FILE IS AUTOMATICALLY GENERATED BY src/core/config/generateConfig.mjs
|
||||
*
|
||||
|
@ -77,17 +77,17 @@ for (let module in modules) {
|
|||
*/
|
||||
`;
|
||||
|
||||
for (let opName in modules[module]) {
|
||||
for (const opName in modules[module]) {
|
||||
const objName = modules[module][opName];
|
||||
code += `import ${objName} from "../../operations/${objName}";\n`;
|
||||
}
|
||||
|
||||
code += `
|
||||
let OpModules = typeof self === "undefined" ? {} : self.OpModules || {};
|
||||
const OpModules = typeof self === "undefined" ? {} : self.OpModules || {};
|
||||
|
||||
OpModules.${module} = {
|
||||
`;
|
||||
for (let opName in modules[module]) {
|
||||
for (const opName in modules[module]) {
|
||||
const objName = modules[module][opName];
|
||||
code += ` "${opName}": ${objName},\n`;
|
||||
}
|
||||
|
@ -123,18 +123,18 @@ let opModulesCode = `/**
|
|||
*/
|
||||
`;
|
||||
|
||||
for (let module in modules) {
|
||||
for (const module in modules) {
|
||||
opModulesCode += `import ${module}Module from "./${module}";\n`;
|
||||
}
|
||||
|
||||
opModulesCode += `
|
||||
let OpModules = {};
|
||||
const OpModules = {};
|
||||
|
||||
Object.assign(
|
||||
OpModules,
|
||||
`;
|
||||
|
||||
for (let module in modules) {
|
||||
for (const module in modules) {
|
||||
opModulesCode += ` ${module}Module,\n`;
|
||||
}
|
||||
|
||||
|
|
|
@ -5,14 +5,20 @@
|
|||
* @copyright Crown Copyright 2018
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
import ToBase64 from "../../operations/ToBase64";
|
||||
import FromBase32 from "../../operations/FromBase32";
|
||||
import FromBase64 from "../../operations/FromBase64";
|
||||
import ShowBase64Offsets from "../../operations/ShowBase64Offsets";
|
||||
import ToBase32 from "../../operations/ToBase32";
|
||||
import ToBase64 from "../../operations/ToBase64";
|
||||
|
||||
let OpModules = typeof self === "undefined" ? {} : self.OpModules || {};
|
||||
const OpModules = typeof self === "undefined" ? {} : self.OpModules || {};
|
||||
|
||||
OpModules.Default = {
|
||||
"To Base64": ToBase64,
|
||||
"From Base32": FromBase32,
|
||||
"From Base64": FromBase64,
|
||||
"Show Base64 offsets": ShowBase64Offsets,
|
||||
"To Base32": ToBase32,
|
||||
"To Base64": ToBase64,
|
||||
};
|
||||
|
||||
export default OpModules;
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
*/
|
||||
import DefaultModule from "./Default";
|
||||
|
||||
let OpModules = {};
|
||||
const OpModules = {};
|
||||
|
||||
Object.assign(
|
||||
OpModules,
|
||||
|
|
|
@ -1,263 +1,129 @@
|
|||
import Utils from "../Utils";
|
||||
|
||||
|
||||
/**
|
||||
* Base64 operations.
|
||||
* Base64 functions.
|
||||
*
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
* @copyright Crown Copyright 2016
|
||||
* @license Apache-2.0
|
||||
*
|
||||
* @namespace
|
||||
*/
|
||||
const Base64 = {
|
||||
|
||||
/**
|
||||
* @constant
|
||||
* @default
|
||||
*/
|
||||
BASE32_ALPHABET: "A-Z2-7=",
|
||||
import Utils from "../Utils";
|
||||
|
||||
/**
|
||||
* To Base32 operation.
|
||||
*
|
||||
* @param {byteArray} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
runTo32: function(input, args) {
|
||||
if (!input) return "";
|
||||
|
||||
let alphabet = args[0] ?
|
||||
Utils.expandAlphRange(args[0]).join("") : "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567=",
|
||||
output = "",
|
||||
chr1, chr2, chr3, chr4, chr5,
|
||||
enc1, enc2, enc3, enc4, enc5, enc6, enc7, enc8,
|
||||
i = 0;
|
||||
/**
|
||||
* Base64's the input byte array using the given alphabet, returning a string.
|
||||
*
|
||||
* @param {byteArray|Uint8Array|string} data
|
||||
* @param {string} [alphabet="A-Za-z0-9+/="]
|
||||
* @returns {string}
|
||||
*
|
||||
* @example
|
||||
* // returns "SGVsbG8="
|
||||
* toBase64([72, 101, 108, 108, 111]);
|
||||
*
|
||||
* // returns "SGVsbG8="
|
||||
* toBase64("Hello");
|
||||
*/
|
||||
export function toBase64(data, alphabet="A-Za-z0-9+/=") {
|
||||
if (!data) return "";
|
||||
if (typeof data == "string") {
|
||||
data = Utils.strToByteArray(data);
|
||||
}
|
||||
|
||||
while (i < input.length) {
|
||||
chr1 = input[i++];
|
||||
chr2 = input[i++];
|
||||
chr3 = input[i++];
|
||||
chr4 = input[i++];
|
||||
chr5 = input[i++];
|
||||
alphabet = Utils.expandAlphRange(alphabet).join("");
|
||||
|
||||
enc1 = chr1 >> 3;
|
||||
enc2 = ((chr1 & 7) << 2) | (chr2 >> 6);
|
||||
enc3 = (chr2 >> 1) & 31;
|
||||
enc4 = ((chr2 & 1) << 4) | (chr3 >> 4);
|
||||
enc5 = ((chr3 & 15) << 1) | (chr4 >> 7);
|
||||
enc6 = (chr4 >> 2) & 31;
|
||||
enc7 = ((chr4 & 3) << 3) | (chr5 >> 5);
|
||||
enc8 = chr5 & 31;
|
||||
let output = "",
|
||||
chr1, chr2, chr3,
|
||||
enc1, enc2, enc3, enc4,
|
||||
i = 0;
|
||||
|
||||
if (isNaN(chr2)) {
|
||||
enc3 = enc4 = enc5 = enc6 = enc7 = enc8 = 32;
|
||||
} else if (isNaN(chr3)) {
|
||||
enc5 = enc6 = enc7 = enc8 = 32;
|
||||
} else if (isNaN(chr4)) {
|
||||
enc6 = enc7 = enc8 = 32;
|
||||
} else if (isNaN(chr5)) {
|
||||
enc8 = 32;
|
||||
}
|
||||
while (i < data.length) {
|
||||
chr1 = data[i++];
|
||||
chr2 = data[i++];
|
||||
chr3 = data[i++];
|
||||
|
||||
output += alphabet.charAt(enc1) + alphabet.charAt(enc2) + alphabet.charAt(enc3) +
|
||||
alphabet.charAt(enc4) + alphabet.charAt(enc5) + alphabet.charAt(enc6) +
|
||||
alphabet.charAt(enc7) + alphabet.charAt(enc8);
|
||||
enc1 = chr1 >> 2;
|
||||
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
|
||||
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
|
||||
enc4 = chr3 & 63;
|
||||
|
||||
if (isNaN(chr2)) {
|
||||
enc3 = enc4 = 64;
|
||||
} else if (isNaN(chr3)) {
|
||||
enc4 = 64;
|
||||
}
|
||||
|
||||
return output;
|
||||
},
|
||||
output += alphabet.charAt(enc1) + alphabet.charAt(enc2) +
|
||||
alphabet.charAt(enc3) + alphabet.charAt(enc4);
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* From Base32 operation.
|
||||
*
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {byteArray}
|
||||
*/
|
||||
runFrom32: function(input, args) {
|
||||
if (!input) return [];
|
||||
/**
|
||||
* UnBase64's the input string using the given alphabet, returning a byte array.
|
||||
*
|
||||
* @param {byteArray} data
|
||||
* @param {string} [alphabet="A-Za-z0-9+/="]
|
||||
* @param {string} [returnType="string"] - Either "string" or "byteArray"
|
||||
* @param {boolean} [removeNonAlphChars=true]
|
||||
* @returns {byteArray}
|
||||
*
|
||||
* @example
|
||||
* // returns "Hello"
|
||||
* fromBase64("SGVsbG8=");
|
||||
*
|
||||
* // returns [72, 101, 108, 108, 111]
|
||||
* fromBase64("SGVsbG8=", null, "byteArray");
|
||||
*/
|
||||
export function fromBase64(data, alphabet="A-Za-z0-9+/=", returnType="string", removeNonAlphChars=true) {
|
||||
if (!data) {
|
||||
return returnType === "string" ? "" : [];
|
||||
}
|
||||
|
||||
let alphabet = args[0] ?
|
||||
Utils.expandAlphRange(args[0]).join("") : "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567=",
|
||||
removeNonAlphChars = args[0];
|
||||
alphabet = Utils.expandAlphRange(alphabet).join("");
|
||||
|
||||
let output = [],
|
||||
chr1, chr2, chr3, chr4, chr5,
|
||||
enc1, enc2, enc3, enc4, enc5, enc6, enc7, enc8,
|
||||
i = 0;
|
||||
const output = [];
|
||||
let chr1, chr2, chr3,
|
||||
enc1, enc2, enc3, enc4,
|
||||
i = 0;
|
||||
|
||||
if (removeNonAlphChars) {
|
||||
const re = new RegExp("[^" + alphabet.replace(/[\]\\\-^]/g, "\\$&") + "]", "g");
|
||||
input = input.replace(re, "");
|
||||
if (removeNonAlphChars) {
|
||||
const re = new RegExp("[^" + alphabet.replace(/[[\]\\\-^$]/g, "\\$&") + "]", "g");
|
||||
data = data.replace(re, "");
|
||||
}
|
||||
|
||||
while (i < data.length) {
|
||||
enc1 = alphabet.indexOf(data.charAt(i++));
|
||||
enc2 = alphabet.indexOf(data.charAt(i++) || "=");
|
||||
enc3 = alphabet.indexOf(data.charAt(i++) || "=");
|
||||
enc4 = alphabet.indexOf(data.charAt(i++) || "=");
|
||||
|
||||
enc2 = enc2 === -1 ? 64 : enc2;
|
||||
enc3 = enc3 === -1 ? 64 : enc3;
|
||||
enc4 = enc4 === -1 ? 64 : enc4;
|
||||
|
||||
chr1 = (enc1 << 2) | (enc2 >> 4);
|
||||
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
|
||||
chr3 = ((enc3 & 3) << 6) | enc4;
|
||||
|
||||
output.push(chr1);
|
||||
|
||||
if (enc3 !== 64) {
|
||||
output.push(chr2);
|
||||
}
|
||||
|
||||
while (i < input.length) {
|
||||
enc1 = alphabet.indexOf(input.charAt(i++));
|
||||
enc2 = alphabet.indexOf(input.charAt(i++) || "=");
|
||||
enc3 = alphabet.indexOf(input.charAt(i++) || "=");
|
||||
enc4 = alphabet.indexOf(input.charAt(i++) || "=");
|
||||
enc5 = alphabet.indexOf(input.charAt(i++) || "=");
|
||||
enc6 = alphabet.indexOf(input.charAt(i++) || "=");
|
||||
enc7 = alphabet.indexOf(input.charAt(i++) || "=");
|
||||
enc8 = alphabet.indexOf(input.charAt(i++) || "=");
|
||||
|
||||
chr1 = (enc1 << 3) | (enc2 >> 2);
|
||||
chr2 = ((enc2 & 3) << 6) | (enc3 << 1) | (enc4 >> 4);
|
||||
chr3 = ((enc4 & 15) << 4) | (enc5 >> 1);
|
||||
chr4 = ((enc5 & 1) << 7) | (enc6 << 2) | (enc7 >> 3);
|
||||
chr5 = ((enc7 & 7) << 5) | enc8;
|
||||
|
||||
output.push(chr1);
|
||||
if (enc2 & 3 !== 0 || enc3 !== 32) output.push(chr2);
|
||||
if (enc4 & 15 !== 0 || enc5 !== 32) output.push(chr3);
|
||||
if (enc5 & 1 !== 0 || enc6 !== 32) output.push(chr4);
|
||||
if (enc7 & 7 !== 0 || enc8 !== 32) output.push(chr5);
|
||||
if (enc4 !== 64) {
|
||||
output.push(chr3);
|
||||
}
|
||||
}
|
||||
|
||||
return output;
|
||||
},
|
||||
return returnType === "string" ? Utils.byteArrayToUtf8(output) : output;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @constant
|
||||
* @default
|
||||
*/
|
||||
SHOW_IN_BINARY: false,
|
||||
/**
|
||||
* @constant
|
||||
* @default
|
||||
*/
|
||||
OFFSETS_SHOW_VARIABLE: true,
|
||||
|
||||
/**
|
||||
* Show Base64 offsets operation.
|
||||
*
|
||||
* @param {byteArray} input
|
||||
* @param {Object[]} args
|
||||
* @returns {html}
|
||||
*/
|
||||
runOffsets: function(input, args) {
|
||||
let alphabet = args[0] || Base64.ALPHABET,
|
||||
showVariable = args[1],
|
||||
offset0 = Utils.toBase64(input, alphabet),
|
||||
offset1 = Utils.toBase64([0].concat(input), alphabet),
|
||||
offset2 = Utils.toBase64([0, 0].concat(input), alphabet),
|
||||
len0 = offset0.indexOf("="),
|
||||
len1 = offset1.indexOf("="),
|
||||
len2 = offset2.indexOf("="),
|
||||
script = "<script type='application/javascript'>$('[data-toggle=\"tooltip\"]').tooltip()</script>",
|
||||
staticSection = "",
|
||||
padding = "";
|
||||
|
||||
if (input.length < 1) {
|
||||
return "Please enter a string.";
|
||||
}
|
||||
|
||||
// Highlight offset 0
|
||||
if (len0 % 4 === 2) {
|
||||
staticSection = offset0.slice(0, -3);
|
||||
offset0 = "<span data-toggle='tooltip' data-placement='top' title='" +
|
||||
Utils.escapeHtml(Utils.fromBase64(staticSection, alphabet).slice(0, -2)) + "'>" +
|
||||
staticSection + "</span>" +
|
||||
"<span class='hl5'>" + offset0.substr(offset0.length - 3, 1) + "</span>" +
|
||||
"<span class='hl3'>" + offset0.substr(offset0.length - 2) + "</span>";
|
||||
} else if (len0 % 4 === 3) {
|
||||
staticSection = offset0.slice(0, -2);
|
||||
offset0 = "<span data-toggle='tooltip' data-placement='top' title='" +
|
||||
Utils.escapeHtml(Utils.fromBase64(staticSection, alphabet).slice(0, -1)) + "'>" +
|
||||
staticSection + "</span>" +
|
||||
"<span class='hl5'>" + offset0.substr(offset0.length - 2, 1) + "</span>" +
|
||||
"<span class='hl3'>" + offset0.substr(offset0.length - 1) + "</span>";
|
||||
} else {
|
||||
staticSection = offset0;
|
||||
offset0 = "<span data-toggle='tooltip' data-placement='top' title='" +
|
||||
Utils.escapeHtml(Utils.fromBase64(staticSection, alphabet)) + "'>" +
|
||||
staticSection + "</span>";
|
||||
}
|
||||
|
||||
if (!showVariable) {
|
||||
offset0 = staticSection;
|
||||
}
|
||||
|
||||
|
||||
// Highlight offset 1
|
||||
padding = "<span class='hl3'>" + offset1.substr(0, 1) + "</span>" +
|
||||
"<span class='hl5'>" + offset1.substr(1, 1) + "</span>";
|
||||
offset1 = offset1.substr(2);
|
||||
if (len1 % 4 === 2) {
|
||||
staticSection = offset1.slice(0, -3);
|
||||
offset1 = padding + "<span data-toggle='tooltip' data-placement='top' title='" +
|
||||
Utils.escapeHtml(Utils.fromBase64("AA" + staticSection, alphabet).slice(1, -2)) + "'>" +
|
||||
staticSection + "</span>" +
|
||||
"<span class='hl5'>" + offset1.substr(offset1.length - 3, 1) + "</span>" +
|
||||
"<span class='hl3'>" + offset1.substr(offset1.length - 2) + "</span>";
|
||||
} else if (len1 % 4 === 3) {
|
||||
staticSection = offset1.slice(0, -2);
|
||||
offset1 = padding + "<span data-toggle='tooltip' data-placement='top' title='" +
|
||||
Utils.escapeHtml(Utils.fromBase64("AA" + staticSection, alphabet).slice(1, -1)) + "'>" +
|
||||
staticSection + "</span>" +
|
||||
"<span class='hl5'>" + offset1.substr(offset1.length - 2, 1) + "</span>" +
|
||||
"<span class='hl3'>" + offset1.substr(offset1.length - 1) + "</span>";
|
||||
} else {
|
||||
staticSection = offset1;
|
||||
offset1 = padding + "<span data-toggle='tooltip' data-placement='top' title='" +
|
||||
Utils.escapeHtml(Utils.fromBase64("AA" + staticSection, alphabet).slice(1)) + "'>" +
|
||||
staticSection + "</span>";
|
||||
}
|
||||
|
||||
if (!showVariable) {
|
||||
offset1 = staticSection;
|
||||
}
|
||||
|
||||
// Highlight offset 2
|
||||
padding = "<span class='hl3'>" + offset2.substr(0, 2) + "</span>" +
|
||||
"<span class='hl5'>" + offset2.substr(2, 1) + "</span>";
|
||||
offset2 = offset2.substr(3);
|
||||
if (len2 % 4 === 2) {
|
||||
staticSection = offset2.slice(0, -3);
|
||||
offset2 = padding + "<span data-toggle='tooltip' data-placement='top' title='" +
|
||||
Utils.escapeHtml(Utils.fromBase64("AAA" + staticSection, alphabet).slice(2, -2)) + "'>" +
|
||||
staticSection + "</span>" +
|
||||
"<span class='hl5'>" + offset2.substr(offset2.length - 3, 1) + "</span>" +
|
||||
"<span class='hl3'>" + offset2.substr(offset2.length - 2) + "</span>";
|
||||
} else if (len2 % 4 === 3) {
|
||||
staticSection = offset2.slice(0, -2);
|
||||
offset2 = padding + "<span data-toggle='tooltip' data-placement='top' title='" +
|
||||
Utils.escapeHtml(Utils.fromBase64("AAA" + staticSection, alphabet).slice(2, -2)) + "'>" +
|
||||
staticSection + "</span>" +
|
||||
"<span class='hl5'>" + offset2.substr(offset2.length - 2, 1) + "</span>" +
|
||||
"<span class='hl3'>" + offset2.substr(offset2.length - 1) + "</span>";
|
||||
} else {
|
||||
staticSection = offset2;
|
||||
offset2 = padding + "<span data-toggle='tooltip' data-placement='top' title='" +
|
||||
Utils.escapeHtml(Utils.fromBase64("AAA" + staticSection, alphabet).slice(2)) + "'>" +
|
||||
staticSection + "</span>";
|
||||
}
|
||||
|
||||
if (!showVariable) {
|
||||
offset2 = staticSection;
|
||||
}
|
||||
|
||||
return (showVariable ? "Characters highlighted in <span class='hl5'>green</span> could change if the input is surrounded by more data." +
|
||||
"\nCharacters highlighted in <span class='hl3'>red</span> are for padding purposes only." +
|
||||
"\nUnhighlighted characters are <span data-toggle='tooltip' data-placement='top' title='Tooltip on left'>static</span>." +
|
||||
"\nHover over the static sections to see what they decode to on their own.\n" +
|
||||
"\nOffset 0: " + offset0 +
|
||||
"\nOffset 1: " + offset1 +
|
||||
"\nOffset 2: " + offset2 +
|
||||
script :
|
||||
offset0 + "\n" + offset1 + "\n" + offset2);
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
export default Base64;
|
||||
|
||||
export const ALPHABET = "A-Za-z0-9+/=";
|
||||
|
||||
/**
|
||||
* Base64 alphabets.
|
||||
*/
|
||||
export const ALPHABET_OPTIONS = [
|
||||
{name: "Standard: A-Za-z0-9+/=", value: "A-Za-z0-9+/="},
|
||||
{name: "URL safe: A-Za-z0-9-_", value: "A-Za-z0-9-_"},
|
||||
|
|
90
src/core/operations/FromBase32.mjs
Normal file
90
src/core/operations/FromBase32.mjs
Normal file
|
@ -0,0 +1,90 @@
|
|||
/**
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
* @copyright Crown Copyright 2016
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation";
|
||||
import Utils from "../Utils";
|
||||
|
||||
/**
|
||||
* From Base32 operation
|
||||
*/
|
||||
class FromBase32 extends Operation {
|
||||
|
||||
/**
|
||||
* FromBase32 constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "From Base32";
|
||||
this.module = "Default";
|
||||
this.description = "Base32 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. It uses a smaller set of characters than Base64, usually the uppercase alphabet and the numbers 2 to 7.";
|
||||
this.inputType = "string";
|
||||
this.outputType = "byteArray";
|
||||
this.args = [
|
||||
{
|
||||
name: "Alphabet",
|
||||
type: "binaryString",
|
||||
value: "A-Z2-7="
|
||||
},
|
||||
{
|
||||
name: "Remove non-alphabet chars",
|
||||
type: "boolean",
|
||||
value: true
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {byteArray}
|
||||
*/
|
||||
run(input, args) {
|
||||
if (!input) return [];
|
||||
|
||||
const alphabet = args[0] ?
|
||||
Utils.expandAlphRange(args[0]).join("") : "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567=",
|
||||
removeNonAlphChars = args[1],
|
||||
output = [];
|
||||
|
||||
let chr1, chr2, chr3, chr4, chr5,
|
||||
enc1, enc2, enc3, enc4, enc5, enc6, enc7, enc8,
|
||||
i = 0;
|
||||
|
||||
if (removeNonAlphChars) {
|
||||
const re = new RegExp("[^" + alphabet.replace(/[\]\\\-^]/g, "\\$&") + "]", "g");
|
||||
input = input.replace(re, "");
|
||||
}
|
||||
|
||||
while (i < input.length) {
|
||||
enc1 = alphabet.indexOf(input.charAt(i++));
|
||||
enc2 = alphabet.indexOf(input.charAt(i++) || "=");
|
||||
enc3 = alphabet.indexOf(input.charAt(i++) || "=");
|
||||
enc4 = alphabet.indexOf(input.charAt(i++) || "=");
|
||||
enc5 = alphabet.indexOf(input.charAt(i++) || "=");
|
||||
enc6 = alphabet.indexOf(input.charAt(i++) || "=");
|
||||
enc7 = alphabet.indexOf(input.charAt(i++) || "=");
|
||||
enc8 = alphabet.indexOf(input.charAt(i++) || "=");
|
||||
|
||||
chr1 = (enc1 << 3) | (enc2 >> 2);
|
||||
chr2 = ((enc2 & 3) << 6) | (enc3 << 1) | (enc4 >> 4);
|
||||
chr3 = ((enc4 & 15) << 4) | (enc5 >> 1);
|
||||
chr4 = ((enc5 & 1) << 7) | (enc6 << 2) | (enc7 >> 3);
|
||||
chr5 = ((enc7 & 7) << 5) | enc8;
|
||||
|
||||
output.push(chr1);
|
||||
if (enc2 & 3 !== 0 || enc3 !== 32) output.push(chr2);
|
||||
if (enc4 & 15 !== 0 || enc5 !== 32) output.push(chr3);
|
||||
if (enc5 & 1 !== 0 || enc6 !== 32) output.push(chr4);
|
||||
if (enc7 & 7 !== 0 || enc8 !== 32) output.push(chr5);
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default FromBase32;
|
|
@ -5,8 +5,7 @@
|
|||
*/
|
||||
|
||||
import Operation from "../Operation";
|
||||
import Utils from "../Utils";
|
||||
import {ALPHABET, ALPHABET_OPTIONS} from "../lib/Base64";
|
||||
import {fromBase64, ALPHABET_OPTIONS} from "../lib/Base64";
|
||||
|
||||
/**
|
||||
* From Base64 operation
|
||||
|
@ -14,17 +13,17 @@ import {ALPHABET, ALPHABET_OPTIONS} from "../lib/Base64";
|
|||
class FromBase64 extends Operation {
|
||||
|
||||
/**
|
||||
* ToBase64 constructor
|
||||
* FromBase64 constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "From Base64";
|
||||
this.module = "Default";
|
||||
this.name = "From Base64";
|
||||
this.module = "Default";
|
||||
this.description = "Base64 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.<br><br>This operation decodes data from an ASCII Base64 string back into its raw format.<br><br>e.g. <code>aGVsbG8=</code> becomes <code>hello</code>";
|
||||
this.inputType = "string";
|
||||
this.outputType = "byteArray";
|
||||
this.args = [
|
||||
this.inputType = "string";
|
||||
this.outputType = "byteArray";
|
||||
this.args = [
|
||||
{
|
||||
name: "Alphabet",
|
||||
type: "editableOption",
|
||||
|
@ -44,10 +43,9 @@ class FromBase64 extends Operation {
|
|||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
let alphabet = args[0] || ALPHABET,
|
||||
removeNonAlphChars = args[1];
|
||||
const [alphabet, removeNonAlphChars] = args;
|
||||
|
||||
return Utils.fromBase64(input, alphabet, "byteArray", removeNonAlphChars);
|
||||
return fromBase64(input, alphabet, "byteArray", removeNonAlphChars);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
162
src/core/operations/ShowBase64Offsets.mjs
Normal file
162
src/core/operations/ShowBase64Offsets.mjs
Normal file
|
@ -0,0 +1,162 @@
|
|||
/**
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
* @copyright Crown Copyright 2016
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation";
|
||||
import Utils from "../Utils";
|
||||
import {fromBase64, toBase64} from "../lib/Base64";
|
||||
|
||||
/**
|
||||
* Show Base64 offsets operation
|
||||
*/
|
||||
class ShowBase64Offsets extends Operation {
|
||||
|
||||
/**
|
||||
* ShowBase64Offsets constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "Show Base64 offsets";
|
||||
this.module = "Default";
|
||||
this.description = "When a string is within a block of data and the whole block is Base64'd, the string itself could be represented in Base64 in three distinct ways depending on its offset within the block.<br><br>This operation shows all possible offsets for a given string so that each possible encoding can be considered.";
|
||||
this.inputType = "byteArray";
|
||||
this.outputType = "html";
|
||||
this.args = [
|
||||
{
|
||||
name: "Alphabet",
|
||||
type: "binaryString",
|
||||
value: "A-Za-z0-9+/="
|
||||
},
|
||||
{
|
||||
name: "Show variable chars and padding",
|
||||
type: "boolean",
|
||||
value: true
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {byteArray} input
|
||||
* @param {Object[]} args
|
||||
* @returns {html}
|
||||
*/
|
||||
run(input, args) {
|
||||
const [alphabet, showVariable] = args;
|
||||
|
||||
let offset0 = toBase64(input, alphabet),
|
||||
offset1 = toBase64([0].concat(input), alphabet),
|
||||
offset2 = toBase64([0, 0].concat(input), alphabet),
|
||||
staticSection = "",
|
||||
padding = "";
|
||||
|
||||
const len0 = offset0.indexOf("="),
|
||||
len1 = offset1.indexOf("="),
|
||||
len2 = offset2.indexOf("="),
|
||||
script = "<script type='application/javascript'>$('[data-toggle=\"tooltip\"]').tooltip()</script>";
|
||||
|
||||
if (input.length < 1) {
|
||||
return "Please enter a string.";
|
||||
}
|
||||
|
||||
// Highlight offset 0
|
||||
if (len0 % 4 === 2) {
|
||||
staticSection = offset0.slice(0, -3);
|
||||
offset0 = "<span data-toggle='tooltip' data-placement='top' title='" +
|
||||
Utils.escapeHtml(fromBase64(staticSection, alphabet).slice(0, -2)) + "'>" +
|
||||
staticSection + "</span>" +
|
||||
"<span class='hl5'>" + offset0.substr(offset0.length - 3, 1) + "</span>" +
|
||||
"<span class='hl3'>" + offset0.substr(offset0.length - 2) + "</span>";
|
||||
} else if (len0 % 4 === 3) {
|
||||
staticSection = offset0.slice(0, -2);
|
||||
offset0 = "<span data-toggle='tooltip' data-placement='top' title='" +
|
||||
Utils.escapeHtml(fromBase64(staticSection, alphabet).slice(0, -1)) + "'>" +
|
||||
staticSection + "</span>" +
|
||||
"<span class='hl5'>" + offset0.substr(offset0.length - 2, 1) + "</span>" +
|
||||
"<span class='hl3'>" + offset0.substr(offset0.length - 1) + "</span>";
|
||||
} else {
|
||||
staticSection = offset0;
|
||||
offset0 = "<span data-toggle='tooltip' data-placement='top' title='" +
|
||||
Utils.escapeHtml(fromBase64(staticSection, alphabet)) + "'>" +
|
||||
staticSection + "</span>";
|
||||
}
|
||||
|
||||
if (!showVariable) {
|
||||
offset0 = staticSection;
|
||||
}
|
||||
|
||||
|
||||
// Highlight offset 1
|
||||
padding = "<span class='hl3'>" + offset1.substr(0, 1) + "</span>" +
|
||||
"<span class='hl5'>" + offset1.substr(1, 1) + "</span>";
|
||||
offset1 = offset1.substr(2);
|
||||
if (len1 % 4 === 2) {
|
||||
staticSection = offset1.slice(0, -3);
|
||||
offset1 = padding + "<span data-toggle='tooltip' data-placement='top' title='" +
|
||||
Utils.escapeHtml(fromBase64("AA" + staticSection, alphabet).slice(1, -2)) + "'>" +
|
||||
staticSection + "</span>" +
|
||||
"<span class='hl5'>" + offset1.substr(offset1.length - 3, 1) + "</span>" +
|
||||
"<span class='hl3'>" + offset1.substr(offset1.length - 2) + "</span>";
|
||||
} else if (len1 % 4 === 3) {
|
||||
staticSection = offset1.slice(0, -2);
|
||||
offset1 = padding + "<span data-toggle='tooltip' data-placement='top' title='" +
|
||||
Utils.escapeHtml(fromBase64("AA" + staticSection, alphabet).slice(1, -1)) + "'>" +
|
||||
staticSection + "</span>" +
|
||||
"<span class='hl5'>" + offset1.substr(offset1.length - 2, 1) + "</span>" +
|
||||
"<span class='hl3'>" + offset1.substr(offset1.length - 1) + "</span>";
|
||||
} else {
|
||||
staticSection = offset1;
|
||||
offset1 = padding + "<span data-toggle='tooltip' data-placement='top' title='" +
|
||||
Utils.escapeHtml(fromBase64("AA" + staticSection, alphabet).slice(1)) + "'>" +
|
||||
staticSection + "</span>";
|
||||
}
|
||||
|
||||
if (!showVariable) {
|
||||
offset1 = staticSection;
|
||||
}
|
||||
|
||||
// Highlight offset 2
|
||||
padding = "<span class='hl3'>" + offset2.substr(0, 2) + "</span>" +
|
||||
"<span class='hl5'>" + offset2.substr(2, 1) + "</span>";
|
||||
offset2 = offset2.substr(3);
|
||||
if (len2 % 4 === 2) {
|
||||
staticSection = offset2.slice(0, -3);
|
||||
offset2 = padding + "<span data-toggle='tooltip' data-placement='top' title='" +
|
||||
Utils.escapeHtml(fromBase64("AAA" + staticSection, alphabet).slice(2, -2)) + "'>" +
|
||||
staticSection + "</span>" +
|
||||
"<span class='hl5'>" + offset2.substr(offset2.length - 3, 1) + "</span>" +
|
||||
"<span class='hl3'>" + offset2.substr(offset2.length - 2) + "</span>";
|
||||
} else if (len2 % 4 === 3) {
|
||||
staticSection = offset2.slice(0, -2);
|
||||
offset2 = padding + "<span data-toggle='tooltip' data-placement='top' title='" +
|
||||
Utils.escapeHtml(fromBase64("AAA" + staticSection, alphabet).slice(2, -2)) + "'>" +
|
||||
staticSection + "</span>" +
|
||||
"<span class='hl5'>" + offset2.substr(offset2.length - 2, 1) + "</span>" +
|
||||
"<span class='hl3'>" + offset2.substr(offset2.length - 1) + "</span>";
|
||||
} else {
|
||||
staticSection = offset2;
|
||||
offset2 = padding + "<span data-toggle='tooltip' data-placement='top' title='" +
|
||||
Utils.escapeHtml(fromBase64("AAA" + staticSection, alphabet).slice(2)) + "'>" +
|
||||
staticSection + "</span>";
|
||||
}
|
||||
|
||||
if (!showVariable) {
|
||||
offset2 = staticSection;
|
||||
}
|
||||
|
||||
return (showVariable ? "Characters highlighted in <span class='hl5'>green</span> could change if the input is surrounded by more data." +
|
||||
"\nCharacters highlighted in <span class='hl3'>red</span> are for padding purposes only." +
|
||||
"\nUnhighlighted characters are <span data-toggle='tooltip' data-placement='top' title='Tooltip on left'>static</span>." +
|
||||
"\nHover over the static sections to see what they decode to on their own.\n" +
|
||||
"\nOffset 0: " + offset0 +
|
||||
"\nOffset 1: " + offset1 +
|
||||
"\nOffset 2: " + offset2 +
|
||||
script :
|
||||
offset0 + "\n" + offset1 + "\n" + offset2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default ShowBase64Offsets;
|
85
src/core/operations/ToBase32.mjs
Normal file
85
src/core/operations/ToBase32.mjs
Normal file
|
@ -0,0 +1,85 @@
|
|||
/**
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
* @copyright Crown Copyright 2016
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation";
|
||||
import Utils from "../Utils";
|
||||
|
||||
/**
|
||||
* To Base32 operation
|
||||
*/
|
||||
class ToBase32 extends Operation {
|
||||
|
||||
/**
|
||||
* ToBase32 constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "To Base32";
|
||||
this.module = "Default";
|
||||
this.description = "Base32 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. It uses a smaller set of characters than Base64, usually the uppercase alphabet and the numbers 2 to 7.";
|
||||
this.inputType = "byteArray";
|
||||
this.outputType = "string";
|
||||
this.args = [
|
||||
{
|
||||
name: "Alphabet",
|
||||
type: "binaryString",
|
||||
value: "A-Z2-7="
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {byteArray} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
if (!input) return "";
|
||||
|
||||
const alphabet = args[0] ? Utils.expandAlphRange(args[0]).join("") : "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567=";
|
||||
let output = "",
|
||||
chr1, chr2, chr3, chr4, chr5,
|
||||
enc1, enc2, enc3, enc4, enc5, enc6, enc7, enc8,
|
||||
i = 0;
|
||||
|
||||
while (i < input.length) {
|
||||
chr1 = input[i++];
|
||||
chr2 = input[i++];
|
||||
chr3 = input[i++];
|
||||
chr4 = input[i++];
|
||||
chr5 = input[i++];
|
||||
|
||||
enc1 = chr1 >> 3;
|
||||
enc2 = ((chr1 & 7) << 2) | (chr2 >> 6);
|
||||
enc3 = (chr2 >> 1) & 31;
|
||||
enc4 = ((chr2 & 1) << 4) | (chr3 >> 4);
|
||||
enc5 = ((chr3 & 15) << 1) | (chr4 >> 7);
|
||||
enc6 = (chr4 >> 2) & 31;
|
||||
enc7 = ((chr4 & 3) << 3) | (chr5 >> 5);
|
||||
enc8 = chr5 & 31;
|
||||
|
||||
if (isNaN(chr2)) {
|
||||
enc3 = enc4 = enc5 = enc6 = enc7 = enc8 = 32;
|
||||
} else if (isNaN(chr3)) {
|
||||
enc5 = enc6 = enc7 = enc8 = 32;
|
||||
} else if (isNaN(chr4)) {
|
||||
enc6 = enc7 = enc8 = 32;
|
||||
} else if (isNaN(chr5)) {
|
||||
enc8 = 32;
|
||||
}
|
||||
|
||||
output += alphabet.charAt(enc1) + alphabet.charAt(enc2) + alphabet.charAt(enc3) +
|
||||
alphabet.charAt(enc4) + alphabet.charAt(enc5) + alphabet.charAt(enc6) +
|
||||
alphabet.charAt(enc7) + alphabet.charAt(enc8);
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default ToBase32;
|
|
@ -5,8 +5,7 @@
|
|||
*/
|
||||
|
||||
import Operation from "../Operation";
|
||||
import Utils from "../Utils";
|
||||
import {ALPHABET, ALPHABET_OPTIONS} from "../lib/Base64";
|
||||
import {toBase64, ALPHABET_OPTIONS} from "../lib/Base64";
|
||||
|
||||
/**
|
||||
* To Base64 operation
|
||||
|
@ -19,12 +18,12 @@ class ToBase64 extends Operation {
|
|||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "To Base64";
|
||||
this.module = "Default";
|
||||
this.name = "To Base64";
|
||||
this.module = "Default";
|
||||
this.description = "Base64 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.<br><br>This operation decodes data from an ASCII Base64 string back into its raw format.<br><br>e.g. <code>aGVsbG8=</code> becomes <code>hello</code>";
|
||||
this.inputType = "ArrayBuffer";
|
||||
this.outputType = "string";
|
||||
this.args = [
|
||||
this.inputType = "ArrayBuffer";
|
||||
this.outputType = "string";
|
||||
this.args = [
|
||||
{
|
||||
name: "Alphabet",
|
||||
type: "editableOption",
|
||||
|
@ -39,8 +38,8 @@ class ToBase64 extends Operation {
|
|||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
const alphabet = args[0] || ALPHABET;
|
||||
return Utils.toBase64(new Uint8Array(input), alphabet);
|
||||
const alphabet = args[0];
|
||||
return toBase64(new Uint8Array(input), alphabet);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,7 +1,13 @@
|
|||
import ToBase64 from "./ToBase64";
|
||||
import FromBase64 from "./FromBase64";
|
||||
import ToBase32 from "./ToBase32";
|
||||
import FromBase32 from "./FromBase32";
|
||||
import ShowBase64Offsets from "./ShowBase64Offsets";
|
||||
|
||||
export default [
|
||||
export {
|
||||
ToBase64,
|
||||
FromBase64
|
||||
];
|
||||
FromBase64,
|
||||
ToBase32,
|
||||
FromBase32,
|
||||
ShowBase64Offsets
|
||||
};
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import Utils from "../Utils.js";
|
||||
import {toBase64} from "../lib/Base64";
|
||||
import CryptoJS from "crypto-js";
|
||||
import forge from "imports-loader?jQuery=>null!node-forge/dist/forge.min.js";
|
||||
import {blowfish as Blowfish} from "sladex-blowfish";
|
||||
|
@ -366,7 +367,7 @@ DES uses a key length of 8 bytes (64 bits).`;
|
|||
|
||||
input = Utils.convertToByteString(input, inputType);
|
||||
|
||||
Blowfish.setIV(Utils.toBase64(iv), 0);
|
||||
Blowfish.setIV(toBase64(iv), 0);
|
||||
|
||||
const enc = Blowfish.encrypt(input, key, {
|
||||
outputType: Cipher._BLOWFISH_OUTPUT_TYPE_LOOKUP[outputType],
|
||||
|
@ -395,7 +396,7 @@ DES uses a key length of 8 bytes (64 bits).`;
|
|||
|
||||
input = inputType === "Raw" ? Utils.strToByteArray(input) : input;
|
||||
|
||||
Blowfish.setIV(Utils.toBase64(iv), 0);
|
||||
Blowfish.setIV(toBase64(iv), 0);
|
||||
|
||||
const result = Blowfish.decrypt(input, key, {
|
||||
outputType: Cipher._BLOWFISH_OUTPUT_TYPE_LOOKUP[inputType], // This actually means inputType. The library is weird.
|
||||
|
|
|
@ -2,6 +2,7 @@ import * as ExifParser from "exif-parser";
|
|||
import removeEXIF from "../vendor/remove-exif.js";
|
||||
import Utils from "../Utils.js";
|
||||
import FileType from "./FileType.js";
|
||||
import {fromBase64, toBase64} from "../lib/Base64";
|
||||
|
||||
|
||||
/**
|
||||
|
@ -96,7 +97,7 @@ const Image = {
|
|||
case "Base64":
|
||||
// Don't trust the Base64 entered by the user.
|
||||
// Unwrap it first, then re-encode later.
|
||||
input = Utils.fromBase64(input, null, "byteArray");
|
||||
input = fromBase64(input, null, "byteArray");
|
||||
break;
|
||||
case "Raw":
|
||||
default:
|
||||
|
@ -113,7 +114,7 @@ const Image = {
|
|||
}
|
||||
|
||||
// Add image data to URI
|
||||
dataURI += "base64," + Utils.toBase64(input);
|
||||
dataURI += "base64," + toBase64(input);
|
||||
|
||||
return "<img src='" + dataURI + "'>";
|
||||
},
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import Utils from "../Utils.js";
|
||||
import {fromBase64} from "../lib/Base64";
|
||||
import * as r from "jsrsasign";
|
||||
|
||||
|
||||
|
@ -43,7 +44,7 @@ const PublicKey = {
|
|||
cert.readCertPEM(input);
|
||||
break;
|
||||
case "Base64":
|
||||
cert.readCertHex(Utils.toHex(Utils.fromBase64(input, null, "byteArray"), ""));
|
||||
cert.readCertHex(Utils.toHex(fromBase64(input, null, "byteArray"), ""));
|
||||
break;
|
||||
case "Raw":
|
||||
cert.readCertHex(Utils.toHex(Utils.strToByteArray(input), ""));
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import Utils from "../core/Utils";
|
||||
import {fromBase64} from "../core/lib/Base64";
|
||||
import Manager from "./Manager.js";
|
||||
import HTMLCategory from "./HTMLCategory.js";
|
||||
import HTMLOperation from "./HTMLOperation.js";
|
||||
|
@ -193,12 +194,12 @@ App.prototype.populateOperationsList = function() {
|
|||
let i;
|
||||
|
||||
for (i = 0; i < this.categories.length; i++) {
|
||||
let catConf = this.categories[i],
|
||||
const catConf = this.categories[i],
|
||||
selected = i === 0,
|
||||
cat = new HTMLCategory(catConf.name, selected);
|
||||
|
||||
for (let j = 0; j < catConf.ops.length; j++) {
|
||||
let opName = catConf.ops[j],
|
||||
const opName = catConf.ops[j],
|
||||
op = new HTMLOperation(opName, this.operations[opName], this, this.manager);
|
||||
cat.addOperation(op);
|
||||
}
|
||||
|
@ -405,7 +406,7 @@ App.prototype.loadURIParams = function() {
|
|||
// Read in input data from URI params
|
||||
if (this.uriParams.input) {
|
||||
try {
|
||||
const inputData = Utils.fromBase64(this.uriParams.input);
|
||||
const inputData = fromBase64(this.uriParams.input);
|
||||
this.setInput(inputData);
|
||||
} catch (err) {}
|
||||
}
|
||||
|
@ -503,11 +504,11 @@ App.prototype.resetLayout = function() {
|
|||
*/
|
||||
App.prototype.setCompileMessage = function() {
|
||||
// Display time since last build and compile message
|
||||
let now = new Date(),
|
||||
const now = new Date(),
|
||||
timeSinceCompile = Utils.fuzzyTime(now.getTime() - window.compileTime);
|
||||
|
||||
// Calculate previous version to compare to
|
||||
let prev = PKG_VERSION.split(".").map(n => {
|
||||
const prev = PKG_VERSION.split(".").map(n => {
|
||||
return parseInt(n, 10);
|
||||
});
|
||||
if (prev[2] > 0) prev[2]--;
|
||||
|
@ -574,7 +575,7 @@ App.prototype.alert = function(str, style, timeout, silent) {
|
|||
style = style || "danger";
|
||||
timeout = timeout || 0;
|
||||
|
||||
let alertEl = document.getElementById("alert"),
|
||||
const alertEl = document.getElementById("alert"),
|
||||
alertContent = document.getElementById("alert-content");
|
||||
|
||||
alertEl.classList.remove("alert-danger");
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import Utils from "../core/Utils";
|
||||
import {toBase64} from "../core/lib/Base64";
|
||||
|
||||
|
||||
/**
|
||||
|
@ -169,7 +170,7 @@ ControlsWaiter.prototype.generateStateUrl = function(includeRecipe, includeInput
|
|||
window.location.host +
|
||||
window.location.pathname;
|
||||
const recipeStr = Utils.generatePrettyRecipe(recipeConfig);
|
||||
const inputStr = Utils.toBase64(this.app.getInput(), "A-Za-z0-9+/"); // B64 alphabet with no padding
|
||||
const inputStr = toBase64(this.app.getInput(), "A-Za-z0-9+/"); // B64 alphabet with no padding
|
||||
|
||||
includeRecipe = includeRecipe && (recipeConfig.length > 0);
|
||||
// Only inlcude input if it is less than 50KB (51200 * 4/3 as it is Base64 encoded)
|
||||
|
@ -271,9 +272,9 @@ ControlsWaiter.prototype.saveButtonClick = function() {
|
|||
return;
|
||||
}
|
||||
|
||||
let savedRecipes = localStorage.savedRecipes ?
|
||||
JSON.parse(localStorage.savedRecipes) : [],
|
||||
recipeId = localStorage.recipeId || 0;
|
||||
const savedRecipes = localStorage.savedRecipes ?
|
||||
JSON.parse(localStorage.savedRecipes) : [];
|
||||
let recipeId = localStorage.recipeId || 0;
|
||||
|
||||
savedRecipes.push({
|
||||
id: ++recipeId,
|
||||
|
|
|
@ -32,12 +32,14 @@ const HTMLIngredient = function(config, app, manager) {
|
|||
* @returns {string}
|
||||
*/
|
||||
HTMLIngredient.prototype.toHtml = function() {
|
||||
let inline = (this.type === "boolean" ||
|
||||
this.type === "number" ||
|
||||
this.type === "option" ||
|
||||
this.type === "shortString" ||
|
||||
this.type === "binaryShortString"),
|
||||
html = inline ? "" : "<div class='clearfix'> </div>",
|
||||
const inline = (
|
||||
this.type === "boolean" ||
|
||||
this.type === "number" ||
|
||||
this.type === "option" ||
|
||||
this.type === "shortString" ||
|
||||
this.type === "binaryShortString"
|
||||
);
|
||||
let html = inline ? "" : "<div class='clearfix'> </div>",
|
||||
i, m;
|
||||
|
||||
html += "<div class='arg-group" + (inline ? " inline-args" : "") +
|
||||
|
@ -202,7 +204,7 @@ HTMLIngredient.prototype.populateOptionChange = function(e) {
|
|||
* @param {event} e
|
||||
*/
|
||||
HTMLIngredient.prototype.editableOptionChange = function(e) {
|
||||
let select = e.target,
|
||||
const select = e.target,
|
||||
input = select.nextSibling;
|
||||
|
||||
input.value = select.childNodes[select.selectedIndex].value;
|
||||
|
|
|
@ -40,8 +40,8 @@ HighlighterWaiter.OUTPUT = 1;
|
|||
* @returns {boolean}
|
||||
*/
|
||||
HighlighterWaiter.prototype._isSelectionBackwards = function() {
|
||||
let backwards = false,
|
||||
sel = window.getSelection();
|
||||
let backwards = false;
|
||||
const sel = window.getSelection();
|
||||
|
||||
if (!sel.isCollapsed) {
|
||||
const range = document.createRange();
|
||||
|
|
|
@ -25,7 +25,7 @@ self.addEventListener("message", function(e) {
|
|||
*/
|
||||
self.loadFile = function(file) {
|
||||
const reader = new FileReader();
|
||||
let data = new Uint8Array(file.size);
|
||||
const data = new Uint8Array(file.size);
|
||||
let offset = 0;
|
||||
const CHUNK_SIZE = 10485760; // 10MiB
|
||||
|
||||
|
|
|
@ -453,7 +453,7 @@ RecipeWaiter.prototype.setRegisters = function(opIndex, numPrevRegisters, regist
|
|||
// Remove previous div
|
||||
if (prevRegList) prevRegList.remove();
|
||||
|
||||
let registerList = [];
|
||||
const registerList = [];
|
||||
for (let i = 0; i < registers.length; i++) {
|
||||
registerList.push(`$R${numPrevRegisters + i} = ${Utils.escapeHtml(Utils.truncate(Utils.printable(registers[i]), 100))}`);
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ sitemap.add({
|
|||
priority: 1.0
|
||||
});
|
||||
|
||||
for (let op in OperationConfig) {
|
||||
for (const op in OperationConfig) {
|
||||
sitemap.add({
|
||||
url: `/?op=${encodeURIComponent(op)}`,
|
||||
changeFreq: "yearly",
|
||||
|
|
Loading…
Reference in a new issue