mirror of
https://github.com/gchq/CyberChef.git
synced 2025-04-22 07:46:16 -04:00
Merged master into feature-unicode-strings
This commit is contained in:
commit
fff188eb30
20 changed files with 336 additions and 147 deletions
|
@ -1,4 +1,5 @@
|
|||
import Utils from "../Utils.js";
|
||||
import BigNumber from "bignumber.js";
|
||||
|
||||
|
||||
/**
|
||||
|
@ -24,11 +25,11 @@ const Arithmetic = {
|
|||
*
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {number}
|
||||
* @returns {BigNumber}
|
||||
*/
|
||||
runSum: function(input, args) {
|
||||
const val = Arithmetic._sum(Arithmetic._createNumArray(input, args[0]));
|
||||
return typeof(val) === "number" ? val : NaN;
|
||||
return val instanceof BigNumber ? val : new BigNumber(NaN);
|
||||
},
|
||||
|
||||
|
||||
|
@ -37,11 +38,11 @@ const Arithmetic = {
|
|||
*
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {number}
|
||||
* @returns {BigNumber}
|
||||
*/
|
||||
runSub: function(input, args) {
|
||||
let val = Arithmetic._sub(Arithmetic._createNumArray(input, args[0]));
|
||||
return typeof(val) === "number" ? val : NaN;
|
||||
return val instanceof BigNumber ? val : new BigNumber(NaN);
|
||||
},
|
||||
|
||||
|
||||
|
@ -50,11 +51,11 @@ const Arithmetic = {
|
|||
*
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {number}
|
||||
* @returns {BigNumber}
|
||||
*/
|
||||
runMulti: function(input, args) {
|
||||
let val = Arithmetic._multi(Arithmetic._createNumArray(input, args[0]));
|
||||
return typeof(val) === "number" ? val : NaN;
|
||||
return val instanceof BigNumber ? val : new BigNumber(NaN);
|
||||
},
|
||||
|
||||
|
||||
|
@ -63,11 +64,11 @@ const Arithmetic = {
|
|||
*
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {number}
|
||||
* @returns {BigNumber}
|
||||
*/
|
||||
runDiv: function(input, args) {
|
||||
let val = Arithmetic._div(Arithmetic._createNumArray(input, args[0]));
|
||||
return typeof(val) === "number" ? val : NaN;
|
||||
return val instanceof BigNumber ? val : new BigNumber(NaN);
|
||||
},
|
||||
|
||||
|
||||
|
@ -76,11 +77,11 @@ const Arithmetic = {
|
|||
*
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {number}
|
||||
* @returns {BigNumber}
|
||||
*/
|
||||
runMean: function(input, args) {
|
||||
let val = Arithmetic._mean(Arithmetic._createNumArray(input, args[0]));
|
||||
return typeof(val) === "number" ? val : NaN;
|
||||
return val instanceof BigNumber ? val : new BigNumber(NaN);
|
||||
},
|
||||
|
||||
|
||||
|
@ -89,11 +90,11 @@ const Arithmetic = {
|
|||
*
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {number}
|
||||
* @returns {BigNumber}
|
||||
*/
|
||||
runMedian: function(input, args) {
|
||||
let val = Arithmetic._median(Arithmetic._createNumArray(input, args[0]));
|
||||
return typeof(val) === "number" ? val : NaN;
|
||||
return val instanceof BigNumber ? val : new BigNumber(NaN);
|
||||
},
|
||||
|
||||
|
||||
|
@ -102,11 +103,11 @@ const Arithmetic = {
|
|||
*
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {number}
|
||||
* @returns {BigNumber}
|
||||
*/
|
||||
runStdDev: function(input, args) {
|
||||
let val = Arithmetic._stdDev(Arithmetic._createNumArray(input, args[0]));
|
||||
return typeof(val) === "number" ? val : NaN;
|
||||
return val instanceof BigNumber ? val : new BigNumber(NaN);
|
||||
},
|
||||
|
||||
|
||||
|
@ -116,7 +117,7 @@ const Arithmetic = {
|
|||
* @private
|
||||
* @param {string[]} input
|
||||
* @param {string} delim
|
||||
* @returns {number[]}
|
||||
* @returns {BigNumber[]}
|
||||
*/
|
||||
_createNumArray: function(input, delim) {
|
||||
delim = Utils.charRep[delim || "Space"];
|
||||
|
@ -125,13 +126,13 @@ const Arithmetic = {
|
|||
num;
|
||||
|
||||
for (let i = 0; i < splitNumbers.length; i++) {
|
||||
if (splitNumbers[i].indexOf(".") >= 0) {
|
||||
num = parseFloat(splitNumbers[i].trim());
|
||||
} else {
|
||||
num = parseInt(splitNumbers[i].trim(), 0);
|
||||
}
|
||||
if (!isNaN(num)) {
|
||||
numbers.push(num);
|
||||
try {
|
||||
num = BigNumber(splitNumbers[i].trim());
|
||||
if (!num.isNaN()) {
|
||||
numbers.push(num);
|
||||
}
|
||||
} catch (err) {
|
||||
// This line is not a valid number
|
||||
}
|
||||
}
|
||||
return numbers;
|
||||
|
@ -142,12 +143,12 @@ const Arithmetic = {
|
|||
* Adds an array of numbers and returns the value.
|
||||
*
|
||||
* @private
|
||||
* @param {number[]} data
|
||||
* @returns {number}
|
||||
* @param {BigNumber[]} data
|
||||
* @returns {BigNumber}
|
||||
*/
|
||||
_sum: function(data) {
|
||||
if (data.length > 0) {
|
||||
return data.reduce((acc, curr) => acc + curr);
|
||||
return data.reduce((acc, curr) => acc.plus(curr));
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -156,12 +157,12 @@ const Arithmetic = {
|
|||
* Subtracts an array of numbers and returns the value.
|
||||
*
|
||||
* @private
|
||||
* @param {number[]} data
|
||||
* @returns {number}
|
||||
* @param {BigNumber[]} data
|
||||
* @returns {BigNumber}
|
||||
*/
|
||||
_sub: function(data) {
|
||||
if (data.length > 0) {
|
||||
return data.reduce((acc, curr) => acc - curr);
|
||||
return data.reduce((acc, curr) => acc.minus(curr));
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -170,12 +171,12 @@ const Arithmetic = {
|
|||
* Multiplies an array of numbers and returns the value.
|
||||
*
|
||||
* @private
|
||||
* @param {number[]} data
|
||||
* @returns {number}
|
||||
* @param {BigNumber[]} data
|
||||
* @returns {BigNumber}
|
||||
*/
|
||||
_multi: function(data) {
|
||||
if (data.length > 0) {
|
||||
return data.reduce((acc, curr) => acc * curr);
|
||||
return data.reduce((acc, curr) => acc.times(curr));
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -184,12 +185,12 @@ const Arithmetic = {
|
|||
* Divides an array of numbers and returns the value.
|
||||
*
|
||||
* @private
|
||||
* @param {number[]} data
|
||||
* @returns {number}
|
||||
* @param {BigNumber[]} data
|
||||
* @returns {BigNumber}
|
||||
*/
|
||||
_div: function(data) {
|
||||
if (data.length > 0) {
|
||||
return data.reduce((acc, curr) => acc / curr);
|
||||
return data.reduce((acc, curr) => acc.div(curr));
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -198,12 +199,12 @@ const Arithmetic = {
|
|||
* Computes mean of a number array and returns the value.
|
||||
*
|
||||
* @private
|
||||
* @param {number[]} data
|
||||
* @returns {number}
|
||||
* @param {BigNumber[]} data
|
||||
* @returns {BigNumber}
|
||||
*/
|
||||
_mean: function(data) {
|
||||
if (data.length > 0) {
|
||||
return Arithmetic._sum(data) / data.length;
|
||||
return Arithmetic._sum(data).div(data.length);
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -212,14 +213,14 @@ const Arithmetic = {
|
|||
* Computes median of a number array and returns the value.
|
||||
*
|
||||
* @private
|
||||
* @param {number[]} data
|
||||
* @returns {number}
|
||||
* @param {BigNumber[]} data
|
||||
* @returns {BigNumber}
|
||||
*/
|
||||
_median: function (data) {
|
||||
if ((data.length % 2) === 0) {
|
||||
if ((data.length % 2) === 0 && data.length > 0) {
|
||||
let first, second;
|
||||
data.sort(function(a, b){
|
||||
return a - b;
|
||||
return a.minus(b);
|
||||
});
|
||||
first = data[Math.floor(data.length / 2)];
|
||||
second = data[Math.floor(data.length / 2) - 1];
|
||||
|
@ -234,17 +235,17 @@ const Arithmetic = {
|
|||
* Computes standard deviation of a number array and returns the value.
|
||||
*
|
||||
* @private
|
||||
* @param {number[]} data
|
||||
* @returns {number}
|
||||
* @param {BigNumber[]} data
|
||||
* @returns {BigNumber}
|
||||
*/
|
||||
_stdDev: function (data) {
|
||||
if (data.length > 0) {
|
||||
let avg = Arithmetic._mean(data);
|
||||
let devSum = 0;
|
||||
let devSum = new BigNumber(0);
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
devSum += (data[i] - avg) ** 2;
|
||||
devSum = devSum.plus(data[i].minus(avg).pow(2));
|
||||
}
|
||||
return Math.sqrt(devSum / data.length);
|
||||
return devSum.div(data.length).sqrt();
|
||||
}
|
||||
},
|
||||
};
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import Utils from "../Utils.js";
|
||||
import BigNumber from "bignumber.js";
|
||||
|
||||
|
||||
/**
|
||||
|
@ -61,14 +62,14 @@ const BCD = {
|
|||
/**
|
||||
* To BCD operation.
|
||||
*
|
||||
* @param {number} input
|
||||
* @param {BigNumber} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
runToBCD: function(input, args) {
|
||||
if (isNaN(input))
|
||||
if (input.isNaN())
|
||||
return "Invalid input";
|
||||
if (Math.floor(input) !== input)
|
||||
if (!input.floor().equals(input))
|
||||
return "Fractional values are not supported by BCD";
|
||||
|
||||
const encoding = BCD.ENCODING_LOOKUP[args[0]],
|
||||
|
@ -77,7 +78,7 @@ const BCD = {
|
|||
outputFormat = args[3];
|
||||
|
||||
// Split input number up into separate digits
|
||||
const digits = input.toString().split("");
|
||||
const digits = input.toFixed().split("");
|
||||
|
||||
if (digits[0] === "-" || digits[0] === "+") {
|
||||
digits.shift();
|
||||
|
@ -152,7 +153,7 @@ const BCD = {
|
|||
*
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {number}
|
||||
* @returns {BigNumber}
|
||||
*/
|
||||
runFromBCD: function(input, args) {
|
||||
const encoding = BCD.ENCODING_LOOKUP[args[0]],
|
||||
|
@ -206,7 +207,7 @@ const BCD = {
|
|||
output += val.toString();
|
||||
});
|
||||
|
||||
return parseInt(output, 10);
|
||||
return new BigNumber(output);
|
||||
},
|
||||
|
||||
};
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import BigNumber from "bignumber.js";
|
||||
|
||||
/**
|
||||
* Numerical base operations.
|
||||
*
|
||||
|
@ -18,7 +20,7 @@ const Base = {
|
|||
/**
|
||||
* To Base operation.
|
||||
*
|
||||
* @param {number} input
|
||||
* @param {BigNumber} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
|
@ -39,7 +41,7 @@ const Base = {
|
|||
*
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {number}
|
||||
* @returns {BigNumber}
|
||||
*/
|
||||
runFrom: function(input, args) {
|
||||
const radix = args[0] || Base.DEFAULT_RADIX;
|
||||
|
@ -48,14 +50,14 @@ const Base = {
|
|||
}
|
||||
|
||||
let number = input.replace(/\s/g, "").split("."),
|
||||
result = parseInt(number[0], radix) || 0;
|
||||
result = new BigNumber(number[0], radix) || 0;
|
||||
|
||||
if (number.length === 1) return result;
|
||||
|
||||
// Fractional part
|
||||
for (let i = 0; i < number[1].length; i++) {
|
||||
const digit = parseInt(number[1][i], radix);
|
||||
result += digit / Math.pow(radix, i+1);
|
||||
const digit = new BigNumber(number[1][i], radix);
|
||||
result += digit.div(Math.pow(radix, i+1));
|
||||
}
|
||||
|
||||
return result;
|
||||
|
|
|
@ -2,6 +2,7 @@ import Utils from "../Utils.js";
|
|||
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";
|
||||
import BigNumber from "bignumber.js";
|
||||
|
||||
|
||||
/**
|
||||
|
@ -520,7 +521,11 @@ DES uses a key length of 8 bytes (64 bits).`;
|
|||
* @default
|
||||
*/
|
||||
PRNG_BYTES: 32,
|
||||
PRNG_OUTPUT: ["Hex", "Number", "Byte array", "Raw"],
|
||||
/**
|
||||
* @constant
|
||||
* @default
|
||||
*/
|
||||
PRNG_OUTPUT: ["Hex", "Integer", "Byte array", "Raw"],
|
||||
|
||||
/**
|
||||
* Pseudo-Random Number Generator operation.
|
||||
|
@ -542,17 +547,17 @@ DES uses a key length of 8 bytes (64 bits).`;
|
|||
bytes = forge.random.getBytesSync(numBytes);
|
||||
}
|
||||
|
||||
let value = 0,
|
||||
let value = new BigNumber(0),
|
||||
i;
|
||||
|
||||
switch (outputAs) {
|
||||
case "Hex":
|
||||
return forge.util.bytesToHex(bytes);
|
||||
case "Number":
|
||||
case "Integer":
|
||||
for (i = bytes.length - 1; i >= 0; i--) {
|
||||
value = (value * 256) + bytes.charCodeAt(i);
|
||||
value = value.mul(256).plus(bytes.charCodeAt(i));
|
||||
}
|
||||
return value.toString();
|
||||
return value.toFixed();
|
||||
case "Byte array":
|
||||
return JSON.stringify(Utils.strToCharcode(bytes));
|
||||
case "Raw":
|
||||
|
|
|
@ -60,17 +60,16 @@ const Convert = {
|
|||
/**
|
||||
* Convert distance operation.
|
||||
*
|
||||
* @param {number} input
|
||||
* @param {BigNumber} input
|
||||
* @param {Object[]} args
|
||||
* @returns {number}
|
||||
* @returns {BigNumber}
|
||||
*/
|
||||
runDistance: function (input, args) {
|
||||
let inputUnits = args[0],
|
||||
outputUnits = args[1];
|
||||
|
||||
input = input * Convert.DISTANCE_FACTOR[inputUnits];
|
||||
return input / Convert.DISTANCE_FACTOR[outputUnits];
|
||||
// TODO Remove rounding errors (e.g. 1.000000000001)
|
||||
input = input.mul(Convert.DISTANCE_FACTOR[inputUnits]);
|
||||
return input.div(Convert.DISTANCE_FACTOR[outputUnits]);
|
||||
},
|
||||
|
||||
|
||||
|
@ -141,16 +140,16 @@ const Convert = {
|
|||
/**
|
||||
* Convert data units operation.
|
||||
*
|
||||
* @param {number} input
|
||||
* @param {BigNumber} input
|
||||
* @param {Object[]} args
|
||||
* @returns {number}
|
||||
* @returns {BigNumber}
|
||||
*/
|
||||
runDataSize: function (input, args) {
|
||||
let inputUnits = args[0],
|
||||
outputUnits = args[1];
|
||||
|
||||
input = input * Convert.DATA_FACTOR[inputUnits];
|
||||
return input / Convert.DATA_FACTOR[outputUnits];
|
||||
input = input.mul(Convert.DATA_FACTOR[inputUnits]);
|
||||
return input.div(Convert.DATA_FACTOR[outputUnits]);
|
||||
},
|
||||
|
||||
|
||||
|
@ -221,16 +220,16 @@ const Convert = {
|
|||
/**
|
||||
* Convert area operation.
|
||||
*
|
||||
* @param {number} input
|
||||
* @param {BigNumber} input
|
||||
* @param {Object[]} args
|
||||
* @returns {number}
|
||||
* @returns {BigNumber}
|
||||
*/
|
||||
runArea: function (input, args) {
|
||||
let inputUnits = args[0],
|
||||
outputUnits = args[1];
|
||||
|
||||
input = input * Convert.AREA_FACTOR[inputUnits];
|
||||
return input / Convert.AREA_FACTOR[outputUnits];
|
||||
input = input.mul(Convert.AREA_FACTOR[inputUnits]);
|
||||
return input.div(Convert.AREA_FACTOR[outputUnits]);
|
||||
},
|
||||
|
||||
|
||||
|
@ -332,16 +331,16 @@ const Convert = {
|
|||
/**
|
||||
* Convert mass operation.
|
||||
*
|
||||
* @param {number} input
|
||||
* @param {BigNumber} input
|
||||
* @param {Object[]} args
|
||||
* @returns {number}
|
||||
* @returns {BigNumber}
|
||||
*/
|
||||
runMass: function (input, args) {
|
||||
let inputUnits = args[0],
|
||||
outputUnits = args[1];
|
||||
|
||||
input = input * Convert.MASS_FACTOR[inputUnits];
|
||||
return input / Convert.MASS_FACTOR[outputUnits];
|
||||
input = input.mul(Convert.MASS_FACTOR[inputUnits]);
|
||||
return input.div(Convert.MASS_FACTOR[outputUnits]);
|
||||
},
|
||||
|
||||
|
||||
|
@ -397,16 +396,16 @@ const Convert = {
|
|||
/**
|
||||
* Convert speed operation.
|
||||
*
|
||||
* @param {number} input
|
||||
* @param {BigNumber} input
|
||||
* @param {Object[]} args
|
||||
* @returns {number}
|
||||
* @returns {BigNumber}
|
||||
*/
|
||||
runSpeed: function (input, args) {
|
||||
let inputUnits = args[0],
|
||||
outputUnits = args[1];
|
||||
|
||||
input = input * Convert.SPEED_FACTOR[inputUnits];
|
||||
return input / Convert.SPEED_FACTOR[outputUnits];
|
||||
input = input.mul(Convert.SPEED_FACTOR[inputUnits]);
|
||||
return input.div(Convert.SPEED_FACTOR[outputUnits]);
|
||||
},
|
||||
|
||||
};
|
||||
|
|
|
@ -329,6 +329,75 @@ const StrUtils = {
|
|||
})
|
||||
.join(delimiter);
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* @constant
|
||||
* @default
|
||||
*/
|
||||
HAMMING_DELIM: "\\n\\n",
|
||||
/**
|
||||
* @constant
|
||||
* @default
|
||||
*/
|
||||
HAMMING_INPUT_TYPE: ["Raw string", "Hex"],
|
||||
/**
|
||||
* @constant
|
||||
* @default
|
||||
*/
|
||||
HAMMING_UNIT: ["Byte", "Bit"],
|
||||
|
||||
/**
|
||||
* Hamming Distance operation.
|
||||
*
|
||||
* @author GCHQ Contributor [2]
|
||||
*
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
runHamming: function(input, args) {
|
||||
const delim = args[0],
|
||||
byByte = args[1] === "Byte",
|
||||
inputType = args[2],
|
||||
samples = input.split(delim);
|
||||
|
||||
if (samples.length !== 2) {
|
||||
return "Error: You can only calculae the edit distance between 2 strings. Please ensure exactly two inputs are provided, separated by the specified delimiter.";
|
||||
}
|
||||
|
||||
if (samples[0].length !== samples[1].length) {
|
||||
return "Error: Both inputs must be of the same length.";
|
||||
}
|
||||
|
||||
if (inputType === "Hex") {
|
||||
samples[0] = Utils.fromHex(samples[0]);
|
||||
samples[1] = Utils.fromHex(samples[1]);
|
||||
} else {
|
||||
samples[0] = Utils.strToByteArray(samples[0]);
|
||||
samples[1] = Utils.strToByteArray(samples[1]);
|
||||
}
|
||||
|
||||
let dist = 0;
|
||||
|
||||
for (let i = 0; i < samples[0].length; i++) {
|
||||
const lhs = samples[0][i],
|
||||
rhs = samples[1][i];
|
||||
|
||||
if (byByte && lhs !== rhs) {
|
||||
dist++;
|
||||
} else if (!byByte) {
|
||||
let xord = lhs ^ rhs;
|
||||
|
||||
while (xord) {
|
||||
dist++;
|
||||
xord &= xord - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return dist.toString();
|
||||
},
|
||||
};
|
||||
|
||||
export default StrUtils;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue