Compare commits

..

19 Commits

Author SHA1 Message Date
n1474335
4acf7b4e4f 8.10.2 2018-11-09 15:25:22 +00:00
n1474335
42e881326f Added 'Binary' key option to all bitwise operations. Closes #398 2018-11-09 15:25:16 +00:00
n1474335
3c4893d7c7 8.10.1 2018-11-07 15:20:51 +00:00
n1474335
027aca4ab2 Merge branch 'qistoph-NumSortHex' 2018-11-07 15:20:43 +00:00
n1474335
2d471f551f Lint 2018-11-07 15:20:09 +00:00
n1474335
5c598b69b0 Merge branch 'NumSortHex' of https://github.com/qistoph/CyberChef into qistoph-NumSortHex 2018-11-07 15:15:39 +00:00
n1474335
037300de79 8.10.0 2018-11-07 15:10:57 +00:00
n1474335
6990dcae89 Updated changelog 2018-11-07 15:10:25 +00:00
n1474335
6e81d6dfcd Merge branch 'klaxon1-feature/remove-letter-accents' 2018-11-07 15:08:09 +00:00
n1474335
cea30465d8 Changed 'Remove Letter Accents' to 'Remove Diacritics' 2018-11-07 15:07:54 +00:00
n1474335
b301d16cb2 Merge branch 'feature/remove-letter-accents' of https://github.com/klaxon1/CyberChef into klaxon1-feature/remove-letter-accents 2018-11-07 14:57:05 +00:00
Chris van Marle
ba24e12454 Update hexadecimal sort after review
- Use Array.map instead of for-loop
- Add test case
2018-10-12 15:39:06 +02:00
Chris van Marle
3b3c27072f Fix lint errors 2018-10-11 15:50:58 +02:00
Klaxon
3089c39369 add test 2018-10-11 22:26:44 +10:00
Chris van Marle
0cbb17f7ce Support hexadecimal and other bases in numeric sorting 2018-10-11 14:23:05 +02:00
Klaxon
54793f2b78 update operation 2018-10-11 21:52:49 +10:00
Klaxon
f1ffe19ec8 Merge branch 'master' into feature/remove-letter-accents 2018-10-11 21:28:04 +10:00
Klaxon
04ee2fb3e4 add function to replace accent chars with latin chars 2018-10-03 13:26:01 +10:00
Klaxon
ac2466a304 create operation from npm run newop 2018-10-03 13:11:22 +10:00
19 changed files with 221 additions and 37 deletions

View File

@@ -1,6 +1,9 @@
# Changelog
All notable changes to CyberChef will be documented in this file.
### [8.10.0] - 2018-11-07
- 'Remove Diacritics' operation added [@klaxon1] | [#387]
### [8.9.0] - 2018-11-07
- 'Defang URL' operation added [@arnydo] | [#394]
@@ -80,6 +83,7 @@ All notable changes to CyberChef will be documented in this file.
[@sevzero]: https://github.com/sevzero
[@PenguinGeorge]: https://github.com/PenguinGeorge
[@arnydo]: https://github.com/arnydo
[@klaxon1]: https://github.com/klaxon1
[#95]: https://github.com/gchq/CyberChef/pull/299
[#173]: https://github.com/gchq/CyberChef/pull/173
@@ -99,4 +103,5 @@ All notable changes to CyberChef will be documented in this file.
[#344]: https://github.com/gchq/CyberChef/pull/344
[#348]: https://github.com/gchq/CyberChef/pull/348
[#351]: https://github.com/gchq/CyberChef/pull/351
[#387]: https://github.com/gchq/CyberChef/pull/387
[#394]: https://github.com/gchq/CyberChef/pull/394

2
package-lock.json generated
View File

@@ -1,6 +1,6 @@
{
"name": "cyberchef",
"version": "8.9.2",
"version": "8.10.2",
"lockfileVersion": 1,
"requires": true,
"dependencies": {

View File

@@ -1,6 +1,6 @@
{
"name": "cyberchef",
"version": "8.9.2",
"version": "8.10.2",
"description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.",
"author": "n1474335 <n1474335@gmail.com>",
"homepage": "https://gchq.github.io/CyberChef",

View File

@@ -9,6 +9,7 @@ import moment from "moment-timezone";
import {fromBase64} from "./lib/Base64";
import {fromHex} from "./lib/Hex";
import {fromDecimal} from "./lib/Decimal";
import {fromBinary} from "./lib/Binary";
/**
@@ -298,7 +299,7 @@ class Utils {
* Accepts hex, Base64, UTF8 and Latin1 strings.
*
* @param {string} str
* @param {string} type - One of "Hex", "Decimal", "Base64", "UTF8" or "Latin1"
* @param {string} type - One of "Binary", "Hex", "Decimal", "Base64", "UTF8" or "Latin1"
* @returns {byteArray}
*
* @example
@@ -313,6 +314,8 @@ class Utils {
*/
static convertToByteArray(str, type) {
switch (type.toLowerCase()) {
case "binary":
return fromBinary(str);
case "hex":
return fromHex(str);
case "decimal":
@@ -333,7 +336,7 @@ class Utils {
* Accepts hex, Base64, UTF8 and Latin1 strings.
*
* @param {string} str
* @param {string} type - One of "Hex", "Decimal", "Base64", "UTF8" or "Latin1"
* @param {string} type - One of "Binary", "Hex", "Decimal", "Base64", "UTF8" or "Latin1"
* @returns {string}
*
* @example
@@ -348,6 +351,8 @@ class Utils {
*/
static convertToByteString(str, type) {
switch (type.toLowerCase()) {
case "binary":
return Utils.byteArrayToChars(fromBinary(str));
case "hex":
return Utils.byteArrayToChars(fromHex(str));
case "decimal":

View File

@@ -168,6 +168,7 @@
"ops": [
"Encode text",
"Decode text",
"Remove Diacritics",
"Unescape Unicode Characters"
]
},

70
src/core/lib/Binary.mjs Normal file
View File

@@ -0,0 +1,70 @@
/**
* Binary functions.
*
* @author n1474335 [n1474335@gmail.com]
* @copyright Crown Copyright 2018
* @license Apache-2.0
*/
import Utils from "../Utils";
/**
* Convert a byte array into a binary string.
*
* @param {Uint8Array|byteArray} data
* @param {string} [delim="Space"]
* @param {number} [padding=8]
* @returns {string}
*
* @example
* // returns "00010000 00100000 00110000"
* toHex([10,20,30]);
*
* // returns "00010000 00100000 00110000"
* toHex([10,20,30], ":");
*/
export function toBinary(data, delim="Space", padding=8) {
if (!data) return "";
delim = Utils.charRep(delim);
let output = "";
for (let i = 0; i < data.length; i++) {
output += data[i].toString(2).padStart(padding, "0") + delim;
}
if (delim.length) {
return output.slice(0, -delim.length);
} else {
return output;
}
}
/**
* Convert a binary string into a byte array.
*
* @param {string} data
* @param {string} [delim]
* @param {number} [byteLen=8]
* @returns {byteArray}
*
* @example
* // returns [10,20,30]
* fromBinary("00010000 00100000 00110000");
*
* // returns [10,20,30]
* fromBinary("00010000:00100000:00110000", "Colon");
*/
export function fromBinary(data, delim="Space", byteLen=8) {
const delimRegex = Utils.regexRep(delim);
data = data.replace(delimRegex, "");
const output = [];
for (let i = 0; i < data.length; i += byteLen) {
output.push(parseInt(data.substr(i, byteLen), 2));
}
return output;
}

View File

@@ -116,3 +116,9 @@ export function sub(operand, key) {
const result = operand - key;
return (result < 0) ? 256 + result : result;
}
/**
* Delimiter options for bitwise operations
*/
export const BITWISE_OP_DELIMS = ["Hex", "Decimal", "Binary", "Base64", "UTF8", "Latin1"];

View File

@@ -6,7 +6,7 @@
import Operation from "../Operation";
import Utils from "../Utils";
import { bitOp, add } from "../lib/BitwiseOp";
import { bitOp, add, BITWISE_OP_DELIMS } from "../lib/BitwiseOp";
/**
* ADD operation
@@ -30,7 +30,7 @@ class ADD extends Operation {
"name": "Key",
"type": "toggleString",
"value": "",
"toggleValues": ["Hex", "Decimal", "Base64", "UTF8", "Latin1"]
"toggleValues": BITWISE_OP_DELIMS
}
];
}

View File

@@ -6,7 +6,7 @@
import Operation from "../Operation";
import Utils from "../Utils";
import { bitOp, and } from "../lib/BitwiseOp";
import { bitOp, and, BITWISE_OP_DELIMS } from "../lib/BitwiseOp";
/**
* AND operation
@@ -30,7 +30,7 @@ class AND extends Operation {
"name": "Key",
"type": "toggleString",
"value": "",
"toggleValues": ["Hex", "Decimal", "Base64", "UTF8", "Latin1"]
"toggleValues": BITWISE_OP_DELIMS
}
];
}

View File

@@ -7,6 +7,7 @@
import Operation from "../Operation";
import Utils from "../Utils";
import {BIN_DELIM_OPTIONS} from "../lib/Delim";
import {fromBinary} from "../lib/Binary";
/**
* From Binary operation
@@ -77,15 +78,7 @@ class FromBinary extends Operation {
* @returns {byteArray}
*/
run(input, args) {
const delimRegex = Utils.regexRep(args[0] || "Space");
input = input.replace(delimRegex, "");
const output = [];
const byteLen = 8;
for (let i = 0; i < input.length; i += byteLen) {
output.push(parseInt(input.substr(i, byteLen), 2));
}
return output;
return fromBinary(input, args[0]);
}
/**

View File

@@ -6,7 +6,7 @@
import Operation from "../Operation";
import Utils from "../Utils";
import { bitOp, or } from "../lib/BitwiseOp";
import { bitOp, or, BITWISE_OP_DELIMS } from "../lib/BitwiseOp";
/**
* OR operation
@@ -30,7 +30,7 @@ class OR extends Operation {
"name": "Key",
"type": "toggleString",
"value": "",
"toggleValues": ["Hex", "Decimal", "Base64", "UTF8", "Latin1"]
"toggleValues": BITWISE_OP_DELIMS
}
];
}

View File

@@ -0,0 +1,41 @@
/**
* @author Klaxon [klaxon@veyr.com]
* @copyright Crown Copyright 2018
* @license Apache-2.0
*/
import Operation from "../Operation";
/**
* Remove Diacritics operation
*/
class RemoveDiacritics extends Operation {
/**
* RemoveDiacritics constructor
*/
constructor() {
super();
this.name = "Remove Diacritics";
this.module = "Default";
this.description = "Replaces accented characters with their latin character equivalent.";
this.infoURL = "https://wikipedia.org/wiki/Diacritic";
this.inputType = "string";
this.outputType = "string";
this.args = [];
}
/**
* @param {string} input
* @param {Object[]} args
* @returns {string}
*/
run(input, args) {
// reference: https://stackoverflow.com/questions/990904/remove-accents-diacritics-in-a-string-in-javascript/37511463
return input.normalize("NFD").replace(/[\u0300-\u036f]/g, "");
}
}
export default RemoveDiacritics;

View File

@@ -6,7 +6,7 @@
import Operation from "../Operation";
import Utils from "../Utils";
import { bitOp, sub } from "../lib/BitwiseOp";
import { bitOp, sub, BITWISE_OP_DELIMS } from "../lib/BitwiseOp";
/**
* SUB operation
@@ -30,7 +30,7 @@ class SUB extends Operation {
"name": "Key",
"type": "toggleString",
"value": "",
"toggleValues": ["Hex", "Decimal", "Base64", "UTF8", "Latin1"]
"toggleValues": BITWISE_OP_DELIMS
}
];
}

View File

@@ -38,7 +38,7 @@ class Sort extends Operation {
{
"name": "Order",
"type": "option",
"value": ["Alphabetical (case sensitive)", "Alphabetical (case insensitive)", "IP address", "Numeric"]
"value": ["Alphabetical (case sensitive)", "Alphabetical (case insensitive)", "IP address", "Numeric", "Numeric (hexadecimal)"]
}
];
}
@@ -62,6 +62,8 @@ class Sort extends Operation {
sorted = sorted.sort(Sort._ipSort);
} else if (order === "Numeric") {
sorted = sorted.sort(Sort._numericSort);
} else if (order === "Numeric (hexadecimal)") {
sorted = sorted.sort(Sort._hexadecimalSort);
}
if (sortReverse) sorted.reverse();
@@ -131,6 +133,44 @@ class Sort extends Operation {
return a.localeCompare(b);
}
/**
* Comparison operation for sorting of hexadecimal values.
*
* @author Chris van Marle
* @private
* @param {string} a
* @param {string} b
* @returns {number}
*/
static _hexadecimalSort(a, b) {
let a_ = a.split(/([^\da-f]+)/i),
b_ = b.split(/([^\da-f]+)/i);
a_ = a_.map(v => {
const t = parseInt(v, 16);
return isNaN(t) ? v : t;
});
b_ = b_.map(v => {
const t = parseInt(v, 16);
return isNaN(t) ? v : t;
});
for (let i = 0; i < a_.length && i < b.length; ++i) {
if (isNaN(a_[i]) && !isNaN(b_[i])) return 1; // Numbers after non-numbers
if (!isNaN(a_[i]) && isNaN(b_[i])) return -1;
if (isNaN(a_[i]) && isNaN(b_[i])) {
const ret = a_[i].localeCompare(b_[i]); // Compare strings
if (ret !== 0) return ret;
}
if (!isNaN(a_[i]) && !isNaN(a_[i])) { // Compare numbers
if (a_[i] - b_[i] !== 0) return a_[i] - b_[i];
}
}
return a.localeCompare(b);
}
}
export default Sort;

View File

@@ -7,6 +7,7 @@
import Operation from "../Operation";
import Utils from "../Utils";
import {BIN_DELIM_OPTIONS} from "../lib/Delim";
import {toBinary} from "../lib/Binary";
/**
* To Binary operation
@@ -40,19 +41,7 @@ class ToBinary extends Operation {
* @returns {string}
*/
run(input, args) {
const delim = Utils.charRep(args[0] || "Space"),
padding = 8;
let output = "";
for (let i = 0; i < input.length; i++) {
output += input[i].toString(2).padStart(padding, "0") + delim;
}
if (delim.length) {
return output.slice(0, -delim.length);
} else {
return output;
}
return toBinary(input, args[0]);
}
/**

View File

@@ -6,7 +6,7 @@
import Operation from "../Operation";
import Utils from "../Utils";
import { bitOp, xor } from "../lib/BitwiseOp";
import { bitOp, xor, BITWISE_OP_DELIMS } from "../lib/BitwiseOp";
/**
* XOR operation
@@ -30,7 +30,7 @@ class XOR extends Operation {
"name": "Key",
"type": "toggleString",
"value": "",
"toggleValues": ["Hex", "Decimal", "Base64", "UTF8", "Latin1"]
"toggleValues": BITWISE_OP_DELIMS
},
{
"name": "Scheme",

View File

@@ -63,6 +63,7 @@ import "./tests/operations/ParseIPRange";
import "./tests/operations/PowerSet";
import "./tests/operations/Regex";
import "./tests/operations/Register";
import "./tests/operations/RemoveDiacritics";
import "./tests/operations/Rotate";
import "./tests/operations/SeqUtils";
import "./tests/operations/SetDifference";

View File

@@ -0,0 +1,22 @@
/**
* Remove Diacritics tests.
*
* @author Klaxon [klaxon@veyr.com]
* @copyright Crown Copyright 2017
* @license Apache-2.0
*/
import TestRegister from "../../TestRegister";
TestRegister.addTests([
{
name: "Remove Diacritics",
input: "\xe0, \xe8, \xec, \xf2, \xf9 \xc0, \xc8, \xcc, \xd2, \xd9\n\xe1, \xe9, \xed, \xf3, \xfa, \xfd \xc1, \xc9, \xcd, \xd3, \xda, \xdd\n\xe2, \xea, \xee, \xf4, \xfb \xc2, \xca, \xce, \xd4, \xdb\n\xe3, \xf1, \xf5 \xc3, \xd1, \xd5\n\xe4, \xeb, \xef, \xf6, \xfc, \xff \xc4, \xcb, \xcf, \xd6, \xdc, \u0178\n\xe5, \xc5",
expectedOutput: "a, e, i, o, u A, E, I, O, U\na, e, i, o, u, y A, E, I, O, U, Y\na, e, i, o, u A, E, I, O, U\na, n, o A, N, O\na, e, i, o, u, y A, E, I, O, U, Y\na, A",
recipeConfig: [
{
"op": "Remove Diacritics",
"args": []
},
],
},
]);

View File

@@ -30,4 +30,15 @@ TestRegister.addTests([
}
],
},
{
name: "SeqUtils - Hexadecimal sort",
input: "06,08,0a,0d,0f,1,10,11,12,13,14,15,16,17,18,19,1a,1b,1c,1d,1e,1f,2,3,4,5,7,9,b,c,e",
expectedOutput: "1,2,3,4,5,06,7,08,9,0a,b,c,0d,e,0f,10,11,12,13,14,15,16,17,18,19,1a,1b,1c,1d,1e,1f",
recipeConfig: [
{
"op": "Sort",
"args": ["Comma", false, "Numeric (hexadecimal)"]
}
],
},
]);