mirror of
https://github.com/gchq/CyberChef.git
synced 2025-05-14 10:06:58 -04:00
Merge branch 'master' into feat/1216-1531-upgrade-uuid
This commit is contained in:
commit
7ed7fca3ad
41 changed files with 3011 additions and 107 deletions
|
@ -112,7 +112,7 @@ class AESDecrypt extends Operation {
|
|||
run(input, args) {
|
||||
const key = Utils.convertToByteString(args[0].string, args[0].option),
|
||||
iv = Utils.convertToByteString(args[1].string, args[1].option),
|
||||
mode = args[2].substring(0, 3),
|
||||
mode = args[2].split("/")[0],
|
||||
noPadding = args[2].endsWith("NoPadding"),
|
||||
inputType = args[3],
|
||||
outputType = args[4],
|
||||
|
|
|
@ -66,6 +66,14 @@ class AESEncrypt extends Operation {
|
|||
{
|
||||
name: "ECB",
|
||||
off: [5]
|
||||
},
|
||||
{
|
||||
name: "CBC/NoPadding",
|
||||
off: [5]
|
||||
},
|
||||
{
|
||||
name: "ECB/NoPadding",
|
||||
off: [5]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -98,7 +106,8 @@ class AESEncrypt extends Operation {
|
|||
run(input, args) {
|
||||
const key = Utils.convertToByteString(args[0].string, args[0].option),
|
||||
iv = Utils.convertToByteString(args[1].string, args[1].option),
|
||||
mode = args[2],
|
||||
mode = args[2].split("/")[0],
|
||||
noPadding = args[2].endsWith("NoPadding"),
|
||||
inputType = args[3],
|
||||
outputType = args[4],
|
||||
aad = Utils.convertToByteString(args[5].string, args[5].option);
|
||||
|
@ -114,11 +123,20 @@ The following algorithms will be used based on the size of the key:
|
|||
|
||||
input = Utils.convertToByteString(input, inputType);
|
||||
|
||||
// Handle NoPadding modes
|
||||
if (noPadding && input.length % 16 !== 0) {
|
||||
throw new OperationError("Input length must be a multiple of 16 bytes for NoPadding modes.");
|
||||
}
|
||||
const cipher = forge.cipher.createCipher("AES-" + mode, key);
|
||||
cipher.start({
|
||||
iv: iv,
|
||||
additionalData: mode === "GCM" ? aad : undefined
|
||||
});
|
||||
if (noPadding) {
|
||||
cipher.mode.pad = function(output, options) {
|
||||
return true;
|
||||
};
|
||||
}
|
||||
cipher.update(forge.util.createBuffer(input));
|
||||
cipher.finish();
|
||||
|
||||
|
|
53
src/core/operations/AlternatingCaps.mjs
Normal file
53
src/core/operations/AlternatingCaps.mjs
Normal file
|
@ -0,0 +1,53 @@
|
|||
/**
|
||||
* @author sw5678
|
||||
* @copyright Crown Copyright 2023
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation.mjs";
|
||||
|
||||
/**
|
||||
* Alternating caps operation
|
||||
*/
|
||||
class AlternatingCaps extends Operation {
|
||||
|
||||
/**
|
||||
* AlternatingCaps constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "Alternating Caps";
|
||||
this.module = "Default";
|
||||
this.description = "Alternating caps, also known as studly caps, sticky caps, or spongecase is a form of text notation in which the capitalization of letters varies by some pattern, or arbitrarily. An example of this would be spelling 'alternative caps' as 'aLtErNaTiNg CaPs'.";
|
||||
this.infoURL = "https://en.wikipedia.org/wiki/Alternating_caps";
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
this.args= [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
let output = "";
|
||||
let previousCaps = true;
|
||||
for (let i = 0; i < input.length; i++) {
|
||||
// Check if the element is a letter
|
||||
if (!RegExp(/^\p{L}/, "u").test(input[i])) {
|
||||
output += input[i];
|
||||
} else if (previousCaps) {
|
||||
output += input[i].toLowerCase();
|
||||
previousCaps = false;
|
||||
} else {
|
||||
output += input[i].toUpperCase();
|
||||
previousCaps = true;
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
}
|
||||
|
||||
export default AlternatingCaps;
|
58
src/core/operations/BLAKE3.mjs
Normal file
58
src/core/operations/BLAKE3.mjs
Normal file
|
@ -0,0 +1,58 @@
|
|||
/**
|
||||
* @author xumptex [xumptex@outlook.fr]
|
||||
* @copyright Crown Copyright 2025
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation.mjs";
|
||||
import OperationError from "../errors/OperationError.mjs";
|
||||
import { blake3 } from "hash-wasm";
|
||||
/**
|
||||
* BLAKE3 operation
|
||||
*/
|
||||
class BLAKE3 extends Operation {
|
||||
|
||||
/**
|
||||
* BLAKE3 constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "BLAKE3";
|
||||
this.module = "Hashing";
|
||||
this.description = "Hashes the input using BLAKE3 (UTF-8 encoded), with an optional key (also UTF-8), and outputs the result in hexadecimal format.";
|
||||
this.infoURL = "https://en.wikipedia.org/wiki/BLAKE_(hash_function)#BLAKE3";
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
this.args = [
|
||||
{
|
||||
"name": "Size (bytes)",
|
||||
"type": "number"
|
||||
}, {
|
||||
"name": "Key",
|
||||
"type": "string",
|
||||
"value": ""
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
const key = args[1];
|
||||
const size = args[0];
|
||||
// Check if the user want a key hash or not
|
||||
if (key === "") {
|
||||
return blake3(input, size*8);
|
||||
} if (key.length !== 32) {
|
||||
throw new OperationError("The key must be exactly 32 bytes long");
|
||||
}
|
||||
return blake3(input, size*8, key);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default BLAKE3;
|
|
@ -9,6 +9,7 @@ import OperationError from "../errors/OperationError.mjs";
|
|||
import { fromBase64 } from "../lib/Base64.mjs";
|
||||
import { toHexFast } from "../lib/Hex.mjs";
|
||||
import r from "jsrsasign";
|
||||
import Utils from "../Utils.mjs";
|
||||
|
||||
/**
|
||||
* ECDSA Verify operation
|
||||
|
@ -59,6 +60,11 @@ class ECDSAVerify extends Operation {
|
|||
name: "Message",
|
||||
type: "text",
|
||||
value: ""
|
||||
},
|
||||
{
|
||||
name: "Message format",
|
||||
type: "option",
|
||||
value: ["Raw", "Hex", "Base64"]
|
||||
}
|
||||
];
|
||||
}
|
||||
|
@ -70,7 +76,7 @@ class ECDSAVerify extends Operation {
|
|||
*/
|
||||
run(input, args) {
|
||||
let inputFormat = args[0];
|
||||
const [, mdAlgo, keyPem, msg] = args;
|
||||
const [, mdAlgo, keyPem, msg, msgFormat] = args;
|
||||
|
||||
if (keyPem.replace("-----BEGIN PUBLIC KEY-----", "").length === 0) {
|
||||
throw new OperationError("Please enter a public key.");
|
||||
|
@ -145,7 +151,8 @@ class ECDSAVerify extends Operation {
|
|||
throw new OperationError("Provided key is not a public key.");
|
||||
}
|
||||
sig.init(key);
|
||||
sig.updateString(msg);
|
||||
const messageStr = Utils.convertToByteString(msg, msgFormat);
|
||||
sig.updateString(messageStr);
|
||||
const result = sig.verify(signatureASN1Hex);
|
||||
return result ? "Verified OK" : "Verification Failure";
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ class ExtractEmailAddresses extends Operation {
|
|||
run(input, args) {
|
||||
const [displayTotal, sort, unique] = args,
|
||||
// email regex from: https://www.regextester.com/98066
|
||||
regex = /(?:[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9](?:[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9-]*[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9])?\.)+[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9](?:[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9-]*[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}\])/ig;
|
||||
regex = /(?:[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9](?:[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9-]*[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9])?\.)+[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9](?:[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9-]*[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\])/ig;
|
||||
|
||||
const results = search(
|
||||
input,
|
||||
|
|
|
@ -21,7 +21,7 @@ class ExtractIPAddresses extends Operation {
|
|||
|
||||
this.name = "Extract IP addresses";
|
||||
this.module = "Regex";
|
||||
this.description = "Extracts all IPv4 and IPv6 addresses.<br><br>Warning: Given a string <code>710.65.0.456</code>, this will match <code>10.65.0.45</code> so always check the original input!";
|
||||
this.description = "Extracts all IPv4 and IPv6 addresses.<br><br>Warning: Given a string <code>1.2.3.4.5.6.7.8</code>, this will match <code>1.2.3.4 and 5.6.7.8</code> so always check the original input!";
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
this.args = [
|
||||
|
@ -65,7 +65,21 @@ class ExtractIPAddresses extends Operation {
|
|||
*/
|
||||
run(input, args) {
|
||||
const [includeIpv4, includeIpv6, removeLocal, displayTotal, sort, unique] = args,
|
||||
ipv4 = "(?:(?:\\d|[01]?\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d\\d|\\d)(?:\\/\\d{1,2})?",
|
||||
|
||||
// IPv4 decimal groups can have values 0 to 255. To construct a regex the following sub-regex is reused:
|
||||
ipv4DecimalByte = "(?:25[0-5]|2[0-4]\\d|1?[0-9]\\d|\\d)",
|
||||
ipv4OctalByte = "(?:0[1-3]?[0-7]{1,2})",
|
||||
|
||||
// Look behind and ahead will be used to exclude matches with additional decimal digits left and right of IP address
|
||||
lookBehind = "(?<!\\d)",
|
||||
lookAhead = "(?!\\d)",
|
||||
|
||||
// Each variant requires exactly 4 groups with literal . between.
|
||||
ipv4Decimal = "(?:" + lookBehind + ipv4DecimalByte + "\\.){3}" + "(?:" + ipv4DecimalByte + lookAhead + ")",
|
||||
ipv4Octal = "(?:" + lookBehind + ipv4OctalByte + "\\.){3}" + "(?:" + ipv4OctalByte + lookAhead + ")",
|
||||
|
||||
// Then we allow IPv4 addresses to be expressed either entirely in decimal or entirely in Octal
|
||||
ipv4 = "(?:" + ipv4Decimal + "|" + ipv4Octal + ")",
|
||||
ipv6 = "((?=.*::)(?!.*::.+::)(::)?([\\dA-F]{1,4}:(:|\\b)|){5}|([\\dA-F]{1,4}:){6})(([\\dA-F]{1,4}((?!\\3)::|:\\b|(?![\\dA-F])))|(?!\\2\\3)){2}";
|
||||
let ips = "";
|
||||
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
import Operation from "../Operation.mjs";
|
||||
import Utils from "../Utils.mjs";
|
||||
import {ALPHABET_OPTIONS} from "../lib/Base32.mjs";
|
||||
|
||||
|
||||
/**
|
||||
* From Base32 operation
|
||||
|
@ -27,8 +29,8 @@ class FromBase32 extends Operation {
|
|||
this.args = [
|
||||
{
|
||||
name: "Alphabet",
|
||||
type: "binaryString",
|
||||
value: "A-Z2-7="
|
||||
type: "editableOption",
|
||||
value: ALPHABET_OPTIONS
|
||||
},
|
||||
{
|
||||
name: "Remove non-alphabet chars",
|
||||
|
@ -41,6 +43,11 @@ class FromBase32 extends Operation {
|
|||
pattern: "^(?:[A-Z2-7]{8})+(?:[A-Z2-7]{2}={6}|[A-Z2-7]{4}={4}|[A-Z2-7]{5}={3}|[A-Z2-7]{7}={1})?$",
|
||||
flags: "",
|
||||
args: ["A-Z2-7=", false]
|
||||
},
|
||||
{
|
||||
pattern: "^(?:[0-9A-V]{8})+(?:[0-9A-V]{2}={6}|[0-9A-V]{4}={4}|[0-9A-V]{5}={3}|[0-9A-V]{7}={1})?$",
|
||||
flags: "",
|
||||
args: ["0-9A-V=", false]
|
||||
}
|
||||
];
|
||||
}
|
||||
|
@ -96,3 +103,4 @@ class FromBase32 extends Operation {
|
|||
}
|
||||
|
||||
export default FromBase32;
|
||||
|
||||
|
|
254
src/core/operations/GenerateAllChecksums.mjs
Normal file
254
src/core/operations/GenerateAllChecksums.mjs
Normal file
|
@ -0,0 +1,254 @@
|
|||
/**
|
||||
* @author r4mos [2k95ljkhg@mozmail.com]
|
||||
* @copyright Crown Copyright 2025
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation.mjs";
|
||||
import Adler32Checksum from "./Adler32Checksum.mjs";
|
||||
import CRCChecksum from "./CRCChecksum.mjs";
|
||||
import Fletcher8Checksum from "./Fletcher8Checksum.mjs";
|
||||
import Fletcher16Checksum from "./Fletcher16Checksum.mjs";
|
||||
import Fletcher32Checksum from "./Fletcher32Checksum.mjs";
|
||||
import Fletcher64Checksum from "./Fletcher64Checksum.mjs";
|
||||
|
||||
/**
|
||||
* Generate all checksums operation
|
||||
*/
|
||||
class GenerateAllChecksums extends Operation {
|
||||
|
||||
/**
|
||||
* GenerateAllChecksums constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "Generate all checksums";
|
||||
this.module = "Crypto";
|
||||
this.description = "Generates all available checksums for the input.";
|
||||
this.infoURL = "https://wikipedia.org/wiki/Checksum";
|
||||
this.inputType = "ArrayBuffer";
|
||||
this.outputType = "string";
|
||||
this.args = [
|
||||
{
|
||||
name: "Length (bits)",
|
||||
type: "option",
|
||||
value: [
|
||||
"All", "3", "4", "5", "6", "7", "8", "10", "11", "12", "13", "14", "15", "16", "17", "21", "24", "30", "31", "32", "40", "64", "82"
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Include names",
|
||||
type: "boolean",
|
||||
value: true
|
||||
},
|
||||
];
|
||||
|
||||
const adler32 = new Adler32Checksum;
|
||||
const crc = new CRCChecksum;
|
||||
const fletcher8 = new Fletcher8Checksum;
|
||||
const fletcher16 = new Fletcher16Checksum;
|
||||
const fletcher32 = new Fletcher32Checksum;
|
||||
const fletcher64 = new Fletcher64Checksum;
|
||||
this.checksums = [
|
||||
{name: "CRC-3/GSM", algo: crc, params: ["CRC-3/GSM"]},
|
||||
{name: "CRC-3/ROHC", algo: crc, params: ["CRC-3/ROHC"]},
|
||||
{name: "CRC-4/G-704", algo: crc, params: ["CRC-4/G-704"]},
|
||||
{name: "CRC-4/INTERLAKEN", algo: crc, params: ["CRC-4/INTERLAKEN"]},
|
||||
{name: "CRC-4/ITU", algo: crc, params: ["CRC-4/ITU"]},
|
||||
{name: "CRC-5/EPC", algo: crc, params: ["CRC-5/EPC"]},
|
||||
{name: "CRC-5/EPC-C1G2", algo: crc, params: ["CRC-5/EPC-C1G2"]},
|
||||
{name: "CRC-5/G-704", algo: crc, params: ["CRC-5/G-704"]},
|
||||
{name: "CRC-5/ITU", algo: crc, params: ["CRC-5/ITU"]},
|
||||
{name: "CRC-5/USB", algo: crc, params: ["CRC-5/USB"]},
|
||||
{name: "CRC-6/CDMA2000-A", algo: crc, params: ["CRC-6/CDMA2000-A"]},
|
||||
{name: "CRC-6/CDMA2000-B", algo: crc, params: ["CRC-6/CDMA2000-B"]},
|
||||
{name: "CRC-6/DARC", algo: crc, params: ["CRC-6/DARC"]},
|
||||
{name: "CRC-6/G-704", algo: crc, params: ["CRC-6/G-704"]},
|
||||
{name: "CRC-6/GSM", algo: crc, params: ["CRC-6/GSM"]},
|
||||
{name: "CRC-6/ITU", algo: crc, params: ["CRC-6/ITU"]},
|
||||
{name: "CRC-7/MMC", algo: crc, params: ["CRC-7/MMC"]},
|
||||
{name: "CRC-7/ROHC", algo: crc, params: ["CRC-7/ROHC"]},
|
||||
{name: "CRC-7/UMTS", algo: crc, params: ["CRC-7/UMTS"]},
|
||||
{name: "CRC-8", algo: crc, params: ["CRC-8"]},
|
||||
{name: "CRC-8/8H2F", algo: crc, params: ["CRC-8/8H2F"]},
|
||||
{name: "CRC-8/AES", algo: crc, params: ["CRC-8/AES"]},
|
||||
{name: "CRC-8/AUTOSAR", algo: crc, params: ["CRC-8/AUTOSAR"]},
|
||||
{name: "CRC-8/BLUETOOTH", algo: crc, params: ["CRC-8/BLUETOOTH"]},
|
||||
{name: "CRC-8/CDMA2000", algo: crc, params: ["CRC-8/CDMA2000"]},
|
||||
{name: "CRC-8/DARC", algo: crc, params: ["CRC-8/DARC"]},
|
||||
{name: "CRC-8/DVB-S2", algo: crc, params: ["CRC-8/DVB-S2"]},
|
||||
{name: "CRC-8/EBU", algo: crc, params: ["CRC-8/EBU"]},
|
||||
{name: "CRC-8/GSM-A", algo: crc, params: ["CRC-8/GSM-A"]},
|
||||
{name: "CRC-8/GSM-B", algo: crc, params: ["CRC-8/GSM-B"]},
|
||||
{name: "CRC-8/HITAG", algo: crc, params: ["CRC-8/HITAG"]},
|
||||
{name: "CRC-8/I-432-1", algo: crc, params: ["CRC-8/I-432-1"]},
|
||||
{name: "CRC-8/I-CODE", algo: crc, params: ["CRC-8/I-CODE"]},
|
||||
{name: "CRC-8/ITU", algo: crc, params: ["CRC-8/ITU"]},
|
||||
{name: "CRC-8/LTE", algo: crc, params: ["CRC-8/LTE"]},
|
||||
{name: "CRC-8/MAXIM", algo: crc, params: ["CRC-8/MAXIM"]},
|
||||
{name: "CRC-8/MAXIM-DOW", algo: crc, params: ["CRC-8/MAXIM-DOW"]},
|
||||
{name: "CRC-8/MIFARE-MAD", algo: crc, params: ["CRC-8/MIFARE-MAD"]},
|
||||
{name: "CRC-8/NRSC-5", algo: crc, params: ["CRC-8/NRSC-5"]},
|
||||
{name: "CRC-8/OPENSAFETY", algo: crc, params: ["CRC-8/OPENSAFETY"]},
|
||||
{name: "CRC-8/ROHC", algo: crc, params: ["CRC-8/ROHC"]},
|
||||
{name: "CRC-8/SAE-J1850", algo: crc, params: ["CRC-8/SAE-J1850"]},
|
||||
{name: "CRC-8/SAE-J1850-ZERO", algo: crc, params: ["CRC-8/SAE-J1850-ZERO"]},
|
||||
{name: "CRC-8/SMBUS", algo: crc, params: ["CRC-8/SMBUS"]},
|
||||
{name: "CRC-8/TECH-3250", algo: crc, params: ["CRC-8/TECH-3250"]},
|
||||
{name: "CRC-8/WCDMA", algo: crc, params: ["CRC-8/WCDMA"]},
|
||||
{name: "Fletcher-8", algo: fletcher8, params: []},
|
||||
{name: "CRC-10/ATM", algo: crc, params: ["CRC-10/ATM"]},
|
||||
{name: "CRC-10/CDMA2000", algo: crc, params: ["CRC-10/CDMA2000"]},
|
||||
{name: "CRC-10/GSM", algo: crc, params: ["CRC-10/GSM"]},
|
||||
{name: "CRC-10/I-610", algo: crc, params: ["CRC-10/I-610"]},
|
||||
{name: "CRC-11/FLEXRAY", algo: crc, params: ["CRC-11/FLEXRAY"]},
|
||||
{name: "CRC-11/UMTS", algo: crc, params: ["CRC-11/UMTS"]},
|
||||
{name: "CRC-12/3GPP", algo: crc, params: ["CRC-12/3GPP"]},
|
||||
{name: "CRC-12/CDMA2000", algo: crc, params: ["CRC-12/CDMA2000"]},
|
||||
{name: "CRC-12/DECT", algo: crc, params: ["CRC-12/DECT"]},
|
||||
{name: "CRC-12/GSM", algo: crc, params: ["CRC-12/GSM"]},
|
||||
{name: "CRC-12/UMTS", algo: crc, params: ["CRC-12/UMTS"]},
|
||||
{name: "CRC-13/BBC", algo: crc, params: ["CRC-13/BBC"]},
|
||||
{name: "CRC-14/DARC", algo: crc, params: ["CRC-14/DARC"]},
|
||||
{name: "CRC-14/GSM", algo: crc, params: ["CRC-14/GSM"]},
|
||||
{name: "CRC-15/CAN", algo: crc, params: ["CRC-15/CAN"]},
|
||||
{name: "CRC-15/MPT1327", algo: crc, params: ["CRC-15/MPT1327"]},
|
||||
{name: "CRC-16", algo: crc, params: ["CRC-16"]},
|
||||
{name: "CRC-16/A", algo: crc, params: ["CRC-16/A"]},
|
||||
{name: "CRC-16/ACORN", algo: crc, params: ["CRC-16/ACORN"]},
|
||||
{name: "CRC-16/ARC", algo: crc, params: ["CRC-16/ARC"]},
|
||||
{name: "CRC-16/AUG-CCITT", algo: crc, params: ["CRC-16/AUG-CCITT"]},
|
||||
{name: "CRC-16/AUTOSAR", algo: crc, params: ["CRC-16/AUTOSAR"]},
|
||||
{name: "CRC-16/B", algo: crc, params: ["CRC-16/B"]},
|
||||
{name: "CRC-16/BLUETOOTH", algo: crc, params: ["CRC-16/BLUETOOTH"]},
|
||||
{name: "CRC-16/BUYPASS", algo: crc, params: ["CRC-16/BUYPASS"]},
|
||||
{name: "CRC-16/CCITT", algo: crc, params: ["CRC-16/CCITT"]},
|
||||
{name: "CRC-16/CCITT-FALSE", algo: crc, params: ["CRC-16/CCITT-FALSE"]},
|
||||
{name: "CRC-16/CCITT-TRUE", algo: crc, params: ["CRC-16/CCITT-TRUE"]},
|
||||
{name: "CRC-16/CCITT-ZERO", algo: crc, params: ["CRC-16/CCITT-ZERO"]},
|
||||
{name: "CRC-16/CDMA2000", algo: crc, params: ["CRC-16/CDMA2000"]},
|
||||
{name: "CRC-16/CMS", algo: crc, params: ["CRC-16/CMS"]},
|
||||
{name: "CRC-16/DARC", algo: crc, params: ["CRC-16/DARC"]},
|
||||
{name: "CRC-16/DDS-110", algo: crc, params: ["CRC-16/DDS-110"]},
|
||||
{name: "CRC-16/DECT-R", algo: crc, params: ["CRC-16/DECT-R"]},
|
||||
{name: "CRC-16/DECT-X", algo: crc, params: ["CRC-16/DECT-X"]},
|
||||
{name: "CRC-16/DNP", algo: crc, params: ["CRC-16/DNP"]},
|
||||
{name: "CRC-16/EN-13757", algo: crc, params: ["CRC-16/EN-13757"]},
|
||||
{name: "CRC-16/EPC", algo: crc, params: ["CRC-16/EPC"]},
|
||||
{name: "CRC-16/EPC-C1G2", algo: crc, params: ["CRC-16/EPC-C1G2"]},
|
||||
{name: "CRC-16/GENIBUS", algo: crc, params: ["CRC-16/GENIBUS"]},
|
||||
{name: "CRC-16/GSM", algo: crc, params: ["CRC-16/GSM"]},
|
||||
{name: "CRC-16/I-CODE", algo: crc, params: ["CRC-16/I-CODE"]},
|
||||
{name: "CRC-16/IBM", algo: crc, params: ["CRC-16/IBM"]},
|
||||
{name: "CRC-16/IBM-3740", algo: crc, params: ["CRC-16/IBM-3740"]},
|
||||
{name: "CRC-16/IBM-SDLC", algo: crc, params: ["CRC-16/IBM-SDLC"]},
|
||||
{name: "CRC-16/IEC-61158-2", algo: crc, params: ["CRC-16/IEC-61158-2"]},
|
||||
{name: "CRC-16/ISO-HDLC", algo: crc, params: ["CRC-16/ISO-HDLC"]},
|
||||
{name: "CRC-16/ISO-IEC-14443-3-A", algo: crc, params: ["CRC-16/ISO-IEC-14443-3-A"]},
|
||||
{name: "CRC-16/ISO-IEC-14443-3-B", algo: crc, params: ["CRC-16/ISO-IEC-14443-3-B"]},
|
||||
{name: "CRC-16/KERMIT", algo: crc, params: ["CRC-16/KERMIT"]},
|
||||
{name: "CRC-16/LHA", algo: crc, params: ["CRC-16/LHA"]},
|
||||
{name: "CRC-16/LJ1200", algo: crc, params: ["CRC-16/LJ1200"]},
|
||||
{name: "CRC-16/LTE", algo: crc, params: ["CRC-16/LTE"]},
|
||||
{name: "CRC-16/M17", algo: crc, params: ["CRC-16/M17"]},
|
||||
{name: "CRC-16/MAXIM", algo: crc, params: ["CRC-16/MAXIM"]},
|
||||
{name: "CRC-16/MAXIM-DOW", algo: crc, params: ["CRC-16/MAXIM-DOW"]},
|
||||
{name: "CRC-16/MCRF4XX", algo: crc, params: ["CRC-16/MCRF4XX"]},
|
||||
{name: "CRC-16/MODBUS", algo: crc, params: ["CRC-16/MODBUS"]},
|
||||
{name: "CRC-16/NRSC-5", algo: crc, params: ["CRC-16/NRSC-5"]},
|
||||
{name: "CRC-16/OPENSAFETY-A", algo: crc, params: ["CRC-16/OPENSAFETY-A"]},
|
||||
{name: "CRC-16/OPENSAFETY-B", algo: crc, params: ["CRC-16/OPENSAFETY-B"]},
|
||||
{name: "CRC-16/PROFIBUS", algo: crc, params: ["CRC-16/PROFIBUS"]},
|
||||
{name: "CRC-16/RIELLO", algo: crc, params: ["CRC-16/RIELLO"]},
|
||||
{name: "CRC-16/SPI-FUJITSU", algo: crc, params: ["CRC-16/SPI-FUJITSU"]},
|
||||
{name: "CRC-16/T10-DIF", algo: crc, params: ["CRC-16/T10-DIF"]},
|
||||
{name: "CRC-16/TELEDISK", algo: crc, params: ["CRC-16/TELEDISK"]},
|
||||
{name: "CRC-16/TMS37157", algo: crc, params: ["CRC-16/TMS37157"]},
|
||||
{name: "CRC-16/UMTS", algo: crc, params: ["CRC-16/UMTS"]},
|
||||
{name: "CRC-16/USB", algo: crc, params: ["CRC-16/USB"]},
|
||||
{name: "CRC-16/V-41-LSB", algo: crc, params: ["CRC-16/V-41-LSB"]},
|
||||
{name: "CRC-16/V-41-MSB", algo: crc, params: ["CRC-16/V-41-MSB"]},
|
||||
{name: "CRC-16/VERIFONE", algo: crc, params: ["CRC-16/VERIFONE"]},
|
||||
{name: "CRC-16/X-25", algo: crc, params: ["CRC-16/X-25"]},
|
||||
{name: "CRC-16/XMODEM", algo: crc, params: ["CRC-16/XMODEM"]},
|
||||
{name: "CRC-16/ZMODEM", algo: crc, params: ["CRC-16/ZMODEM"]},
|
||||
{name: "Fletcher-16", algo: fletcher16, params: []},
|
||||
{name: "CRC-17/CAN-FD", algo: crc, params: ["CRC-17/CAN-FD"]},
|
||||
{name: "CRC-21/CAN-FD", algo: crc, params: ["CRC-21/CAN-FD"]},
|
||||
{name: "CRC-24/BLE", algo: crc, params: ["CRC-24/BLE"]},
|
||||
{name: "CRC-24/FLEXRAY-A", algo: crc, params: ["CRC-24/FLEXRAY-A"]},
|
||||
{name: "CRC-24/FLEXRAY-B", algo: crc, params: ["CRC-24/FLEXRAY-B"]},
|
||||
{name: "CRC-24/INTERLAKEN", algo: crc, params: ["CRC-24/INTERLAKEN"]},
|
||||
{name: "CRC-24/LTE-A", algo: crc, params: ["CRC-24/LTE-A"]},
|
||||
{name: "CRC-24/LTE-B", algo: crc, params: ["CRC-24/LTE-B"]},
|
||||
{name: "CRC-24/OPENPGP", algo: crc, params: ["CRC-24/OPENPGP"]},
|
||||
{name: "CRC-24/OS-9", algo: crc, params: ["CRC-24/OS-9"]},
|
||||
{name: "CRC-30/CDMA", algo: crc, params: ["CRC-30/CDMA"]},
|
||||
{name: "CRC-31/PHILIPS", algo: crc, params: ["CRC-31/PHILIPS"]},
|
||||
{name: "Adler-32", algo: adler32, params: []},
|
||||
{name: "CRC-32", algo: crc, params: ["CRC-32"]},
|
||||
{name: "CRC-32/AAL5", algo: crc, params: ["CRC-32/AAL5"]},
|
||||
{name: "CRC-32/ADCCP", algo: crc, params: ["CRC-32/ADCCP"]},
|
||||
{name: "CRC-32/AIXM", algo: crc, params: ["CRC-32/AIXM"]},
|
||||
{name: "CRC-32/AUTOSAR", algo: crc, params: ["CRC-32/AUTOSAR"]},
|
||||
{name: "CRC-32/BASE91-C", algo: crc, params: ["CRC-32/BASE91-C"]},
|
||||
{name: "CRC-32/BASE91-D", algo: crc, params: ["CRC-32/BASE91-D"]},
|
||||
{name: "CRC-32/BZIP2", algo: crc, params: ["CRC-32/BZIP2"]},
|
||||
{name: "CRC-32/C", algo: crc, params: ["CRC-32/C"]},
|
||||
{name: "CRC-32/CASTAGNOLI", algo: crc, params: ["CRC-32/CASTAGNOLI"]},
|
||||
{name: "CRC-32/CD-ROM-EDC", algo: crc, params: ["CRC-32/CD-ROM-EDC"]},
|
||||
{name: "CRC-32/CKSUM", algo: crc, params: ["CRC-32/CKSUM"]},
|
||||
{name: "CRC-32/D", algo: crc, params: ["CRC-32/D"]},
|
||||
{name: "CRC-32/DECT-B", algo: crc, params: ["CRC-32/DECT-B"]},
|
||||
{name: "CRC-32/INTERLAKEN", algo: crc, params: ["CRC-32/INTERLAKEN"]},
|
||||
{name: "CRC-32/ISCSI", algo: crc, params: ["CRC-32/ISCSI"]},
|
||||
{name: "CRC-32/ISO-HDLC", algo: crc, params: ["CRC-32/ISO-HDLC"]},
|
||||
{name: "CRC-32/JAMCRC", algo: crc, params: ["CRC-32/JAMCRC"]},
|
||||
{name: "CRC-32/MEF", algo: crc, params: ["CRC-32/MEF"]},
|
||||
{name: "CRC-32/MPEG-2", algo: crc, params: ["CRC-32/MPEG-2"]},
|
||||
{name: "CRC-32/NVME", algo: crc, params: ["CRC-32/NVME"]},
|
||||
{name: "CRC-32/PKZIP", algo: crc, params: ["CRC-32/PKZIP"]},
|
||||
{name: "CRC-32/POSIX", algo: crc, params: ["CRC-32/POSIX"]},
|
||||
{name: "CRC-32/Q", algo: crc, params: ["CRC-32/Q"]},
|
||||
{name: "CRC-32/SATA", algo: crc, params: ["CRC-32/SATA"]},
|
||||
{name: "CRC-32/V-42", algo: crc, params: ["CRC-32/V-42"]},
|
||||
{name: "CRC-32/XFER", algo: crc, params: ["CRC-32/XFER"]},
|
||||
{name: "CRC-32/XZ", algo: crc, params: ["CRC-32/XZ"]},
|
||||
{name: "Fletcher-32", algo: fletcher32, params: []},
|
||||
{name: "CRC-40/GSM", algo: crc, params: ["CRC-40/GSM"]},
|
||||
{name: "CRC-64/ECMA-182", algo: crc, params: ["CRC-64/ECMA-182"]},
|
||||
{name: "CRC-64/GO-ECMA", algo: crc, params: ["CRC-64/GO-ECMA"]},
|
||||
{name: "CRC-64/GO-ISO", algo: crc, params: ["CRC-64/GO-ISO"]},
|
||||
{name: "CRC-64/MS", algo: crc, params: ["CRC-64/MS"]},
|
||||
{name: "CRC-64/NVME", algo: crc, params: ["CRC-64/NVME"]},
|
||||
{name: "CRC-64/REDIS", algo: crc, params: ["CRC-64/REDIS"]},
|
||||
{name: "CRC-64/WE", algo: crc, params: ["CRC-64/WE"]},
|
||||
{name: "CRC-64/XZ", algo: crc, params: ["CRC-64/XZ"]},
|
||||
{name: "Fletcher-64", algo: fletcher64, params: []},
|
||||
{name: "CRC-82/DARC", algo: crc, params: ["CRC-82/DARC"]}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {ArrayBuffer} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
const [length, includeNames] = args;
|
||||
let output = "";
|
||||
this.checksums.forEach(checksum => {
|
||||
const checksumLength = checksum.name.match(new RegExp("-(\\d{1,2})(\\/|$)"))[1];
|
||||
if (length === "All" || length === checksumLength) {
|
||||
const value = checksum.algo.run(new Uint8Array(input), checksum.params || []);
|
||||
output += includeNames ?
|
||||
`${checksum.name}:${" ".repeat(25-checksum.name.length)}${value}\n`:
|
||||
`${value}\n`;
|
||||
}
|
||||
});
|
||||
return output;
|
||||
}
|
||||
}
|
||||
|
||||
export default GenerateAllChecksums;
|
|
@ -22,12 +22,6 @@ import HAS160 from "./HAS160.mjs";
|
|||
import Whirlpool from "./Whirlpool.mjs";
|
||||
import SSDEEP from "./SSDEEP.mjs";
|
||||
import CTPH from "./CTPH.mjs";
|
||||
import Fletcher8Checksum from "./Fletcher8Checksum.mjs";
|
||||
import Fletcher16Checksum from "./Fletcher16Checksum.mjs";
|
||||
import Fletcher32Checksum from "./Fletcher32Checksum.mjs";
|
||||
import Fletcher64Checksum from "./Fletcher64Checksum.mjs";
|
||||
import Adler32Checksum from "./Adler32Checksum.mjs";
|
||||
import CRCChecksum from "./CRCChecksum.mjs";
|
||||
import BLAKE2b from "./BLAKE2b.mjs";
|
||||
import BLAKE2s from "./BLAKE2s.mjs";
|
||||
import Streebog from "./Streebog.mjs";
|
||||
|
@ -112,16 +106,6 @@ class GenerateAllHashes extends Operation {
|
|||
{name: "SSDEEP", algo: (new SSDEEP()), inputType: "str"},
|
||||
{name: "CTPH", algo: (new CTPH()), inputType: "str"}
|
||||
];
|
||||
this.checksums = [
|
||||
{name: "Fletcher-8", algo: (new Fletcher8Checksum), inputType: "byteArray", params: []},
|
||||
{name: "Fletcher-16", algo: (new Fletcher16Checksum), inputType: "byteArray", params: []},
|
||||
{name: "Fletcher-32", algo: (new Fletcher32Checksum), inputType: "byteArray", params: []},
|
||||
{name: "Fletcher-64", algo: (new Fletcher64Checksum), inputType: "byteArray", params: []},
|
||||
{name: "Adler-32", algo: (new Adler32Checksum), inputType: "byteArray", params: []},
|
||||
{name: "CRC-8", algo: (new CRCChecksum), inputType: "arrayBuffer", params: ["CRC-8"]},
|
||||
{name: "CRC-16", algo: (new CRCChecksum), inputType: "arrayBuffer", params: ["CRC-16"]},
|
||||
{name: "CRC-32", algo: (new CRCChecksum), inputType: "arrayBuffer", params: ["CRC-32"]}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -142,14 +126,6 @@ class GenerateAllHashes extends Operation {
|
|||
output += this.formatDigest(digest, length, includeNames, hash.name);
|
||||
});
|
||||
|
||||
if (length === "All") {
|
||||
output += "\nChecksums:\n";
|
||||
this.checksums.forEach(checksum => {
|
||||
digest = this.executeAlgo(checksum.algo, checksum.inputType, checksum.params || []);
|
||||
output += this.formatDigest(digest, length, includeNames, checksum.name);
|
||||
});
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
|
|
65
src/core/operations/Jsonata.mjs
Normal file
65
src/core/operations/Jsonata.mjs
Normal file
|
@ -0,0 +1,65 @@
|
|||
/**
|
||||
* @author Jon K (jon@ajarsoftware.com)
|
||||
* @copyright Crown Copyright 2016
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import jsonata from "jsonata";
|
||||
import Operation from "../Operation.mjs";
|
||||
import OperationError from "../errors/OperationError.mjs";
|
||||
|
||||
/**
|
||||
* Jsonata Query operation
|
||||
*/
|
||||
class JsonataQuery extends Operation {
|
||||
/**
|
||||
* JsonataQuery constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "Jsonata Query";
|
||||
this.module = "Code";
|
||||
this.description =
|
||||
"Query and transform JSON data with a jsonata query.";
|
||||
this.infoURL = "https://docs.jsonata.org/overview.html";
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
this.args = [
|
||||
{
|
||||
name: "Query",
|
||||
type: "text",
|
||||
value: "string",
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
async run(input, args) {
|
||||
const [query] = args;
|
||||
let result, jsonObj;
|
||||
|
||||
try {
|
||||
jsonObj = JSON.parse(input);
|
||||
} catch (err) {
|
||||
throw new OperationError(`Invalid input JSON: ${err.message}`);
|
||||
}
|
||||
|
||||
try {
|
||||
const expression = jsonata(query);
|
||||
result = await expression.evaluate(jsonObj);
|
||||
} catch (err) {
|
||||
throw new OperationError(
|
||||
`Invalid Jsonata Expression: ${err.message}`
|
||||
);
|
||||
}
|
||||
|
||||
return JSON.stringify(result === undefined ? "" : result);
|
||||
}
|
||||
}
|
||||
|
||||
export default JsonataQuery;
|
126
src/core/operations/PHPSerialize.mjs
Normal file
126
src/core/operations/PHPSerialize.mjs
Normal file
|
@ -0,0 +1,126 @@
|
|||
/**
|
||||
* @author brun0ne [brunonblok@gmail.com]
|
||||
* @copyright Crown Copyright 2023
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation.mjs";
|
||||
import OperationError from "../errors/OperationError.mjs";
|
||||
|
||||
/**
|
||||
* PHP Serialize operation
|
||||
*/
|
||||
class PHPSerialize extends Operation {
|
||||
|
||||
/**
|
||||
* PHPSerialize constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "PHP Serialize";
|
||||
this.module = "Default";
|
||||
this.description = "Performs PHP serialization on JSON data.<br><br>This function does not support <code>object</code> tags.<br><br>Since PHP doesn't distinguish dicts and arrays, this operation is not always symmetric to <code>PHP Deserialize</code>.<br><br>Example:<br><code>[5,"abc",true]</code><br>becomes<br><code>a:3:{i:0;i:5;i:1;s:3:"abc";i:2;b:1;}<code>";
|
||||
this.infoURL = "https://www.phpinternalsbook.com/php5/classes_objects/serialization.html";
|
||||
this.inputType = "JSON";
|
||||
this.outputType = "string";
|
||||
this.args = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {JSON} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
/**
|
||||
* Determines if a number is an integer
|
||||
* @param {number} value
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isInteger(value) {
|
||||
return typeof value === "number" && parseInt(value.toString(), 10) === value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize basic types
|
||||
* @param {string | number | boolean} content
|
||||
* @returns {string}
|
||||
*/
|
||||
function serializeBasicTypes(content) {
|
||||
const basicTypes = {
|
||||
"string": "s",
|
||||
"integer": "i",
|
||||
"float": "d",
|
||||
"boolean": "b"
|
||||
};
|
||||
/**
|
||||
* Booleans
|
||||
* cast to 0 or 1
|
||||
*/
|
||||
if (typeof content === "boolean") {
|
||||
return `${basicTypes.boolean}:${content ? 1 : 0}`;
|
||||
}
|
||||
/* Numbers */
|
||||
if (typeof content === "number") {
|
||||
if (isInteger(content)) {
|
||||
return `${basicTypes.integer}:${content.toString()}`;
|
||||
} else {
|
||||
return `${basicTypes.float}:${content.toString()}`;
|
||||
}
|
||||
}
|
||||
/* Strings */
|
||||
if (typeof content === "string")
|
||||
return `${basicTypes.string}:${content.length}:"${content}"`;
|
||||
|
||||
/** This should be unreachable */
|
||||
throw new OperationError(`Encountered a non-implemented type: ${typeof content}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively serialize
|
||||
* @param {*} object
|
||||
* @returns {string}
|
||||
*/
|
||||
function serialize(object) {
|
||||
/* Null */
|
||||
if (object == null) {
|
||||
return `N;`;
|
||||
}
|
||||
|
||||
if (typeof object !== "object") {
|
||||
/* Basic types */
|
||||
return `${serializeBasicTypes(object)};`;
|
||||
} else if (object instanceof Array) {
|
||||
/* Arrays */
|
||||
const serializedElements = [];
|
||||
|
||||
for (let i = 0; i < object.length; i++) {
|
||||
serializedElements.push(`${serialize(i)}${serialize(object[i])}`);
|
||||
}
|
||||
|
||||
return `a:${object.length}:{${serializedElements.join("")}}`;
|
||||
} else if (object instanceof Object) {
|
||||
/**
|
||||
* Objects
|
||||
* Note: the output cannot be guaranteed to be in the same order as the input
|
||||
*/
|
||||
const serializedElements = [];
|
||||
const keys = Object.keys(object);
|
||||
|
||||
for (const key of keys) {
|
||||
serializedElements.push(`${serialize(key)}${serialize(object[key])}`);
|
||||
}
|
||||
|
||||
return `a:${keys.length}:{${serializedElements.join("")}}`;
|
||||
}
|
||||
|
||||
/** This should be unreachable */
|
||||
throw new OperationError(`Encountered a non-implemented type: ${typeof object}`);
|
||||
}
|
||||
|
||||
return serialize(input);
|
||||
}
|
||||
}
|
||||
|
||||
export default PHPSerialize;
|
|
@ -72,7 +72,7 @@ class RailFenceCipherDecode extends Operation {
|
|||
}
|
||||
}
|
||||
|
||||
return plaintext.join("").trim();
|
||||
return plaintext.join("");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@ class RailFenceCipherEncode extends Operation {
|
|||
rows[rowIdx] += plaintext[pos];
|
||||
}
|
||||
|
||||
return rows.join("").trim();
|
||||
return rows.join("");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
import Operation from "../Operation.mjs";
|
||||
import Utils from "../Utils.mjs";
|
||||
import {ALPHABET_OPTIONS} from "../lib/Base32.mjs";
|
||||
|
||||
/**
|
||||
* To Base32 operation
|
||||
|
@ -27,8 +28,8 @@ class ToBase32 extends Operation {
|
|||
this.args = [
|
||||
{
|
||||
name: "Alphabet",
|
||||
type: "binaryString",
|
||||
value: "A-Z2-7="
|
||||
type: "editableOption",
|
||||
value: ALPHABET_OPTIONS
|
||||
}
|
||||
];
|
||||
}
|
||||
|
@ -83,3 +84,4 @@ class ToBase32 extends Operation {
|
|||
}
|
||||
|
||||
export default ToBase32;
|
||||
|
||||
|
|
|
@ -23,7 +23,13 @@ class URLDecode extends Operation {
|
|||
this.infoURL = "https://wikipedia.org/wiki/Percent-encoding";
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
this.args = [];
|
||||
this.args = [
|
||||
{
|
||||
"name": "Treat \"+\" as space",
|
||||
"type": "boolean",
|
||||
"value": true
|
||||
},
|
||||
];
|
||||
this.checks = [
|
||||
{
|
||||
pattern: ".*(?:%[\\da-f]{2}.*){4}",
|
||||
|
@ -39,7 +45,8 @@ class URLDecode extends Operation {
|
|||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
const data = input.replace(/\+/g, "%20");
|
||||
const plusIsSpace = args[0];
|
||||
const data = plusIsSpace ? input.replace(/\+/g, "%20") : input;
|
||||
try {
|
||||
return decodeURIComponent(data);
|
||||
} catch (err) {
|
||||
|
|
59
src/core/operations/XORChecksum.mjs
Normal file
59
src/core/operations/XORChecksum.mjs
Normal file
|
@ -0,0 +1,59 @@
|
|||
/**
|
||||
* @author Thomas Weißschuh [thomas@t-8ch.de]
|
||||
* @copyright Crown Copyright 2023
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation.mjs";
|
||||
import Utils from "../Utils.mjs";
|
||||
import { toHex } from "../lib/Hex.mjs";
|
||||
|
||||
/**
|
||||
* XOR Checksum operation
|
||||
*/
|
||||
class XORChecksum extends Operation {
|
||||
|
||||
/**
|
||||
* XORChecksum constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "XOR Checksum";
|
||||
this.module = "Crypto";
|
||||
this.description = "XOR Checksum splits the input into blocks of a configurable size and performs the XOR operation on these blocks.";
|
||||
this.infoURL = "https://wikipedia.org/wiki/XOR";
|
||||
this.inputType = "ArrayBuffer";
|
||||
this.outputType = "string";
|
||||
this.args = [
|
||||
{
|
||||
name: "Blocksize",
|
||||
type: "number",
|
||||
value: 4
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {ArrayBuffer} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
const blocksize = args[0];
|
||||
input = new Uint8Array(input);
|
||||
|
||||
const res = Array(blocksize);
|
||||
res.fill(0);
|
||||
|
||||
for (const chunk of Utils.chunked(input, blocksize)) {
|
||||
for (let i = 0; i < blocksize; i++) {
|
||||
res[i] ^= chunk[i];
|
||||
}
|
||||
}
|
||||
|
||||
return toHex(res, "");
|
||||
}
|
||||
}
|
||||
|
||||
export default XORChecksum;
|
Loading…
Add table
Add a link
Reference in a new issue