ESM: Added remaining Base64 ops and created a Base64 library. Added the prefer-const eslint rule.

This commit is contained in:
n1474335 2018-04-02 17:10:51 +01:00
parent 9b4fc3d3aa
commit 041cd9fb8e
30 changed files with 986 additions and 825 deletions

View File

@ -1 +1,2 @@
src/core/vendor/**
src/core/vendor/**
src/core/operations/legacy/**

View File

@ -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,

View File

@ -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);

View 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);

View File

@ -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);

View File

@ -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;
}

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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"
}
]
}
]
}
}

View File

@ -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`;
}

View File

@ -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;

View File

@ -9,7 +9,7 @@
*/
import DefaultModule from "./Default";
let OpModules = {};
const OpModules = {};
Object.assign(
OpModules,

View File

@ -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-_"},

View 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;

View File

@ -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);
}
/**

View 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;

View 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;

View File

@ -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);
}
/**

View File

@ -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
};

View File

@ -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.

View File

@ -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 + "'>";
},

View File

@ -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), ""));

View File

@ -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");

View File

@ -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,

View File

@ -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'>&nbsp;</div>",
const inline = (
this.type === "boolean" ||
this.type === "number" ||
this.type === "option" ||
this.type === "shortString" ||
this.type === "binaryShortString"
);
let html = inline ? "" : "<div class='clearfix'>&nbsp;</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;

View File

@ -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();

View File

@ -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

View File

@ -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))}`);
}

View File

@ -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",