mirror of
https://github.com/gchq/CyberChef
synced 2025-12-05 23:53:27 +00:00
Compare commits
46 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
be231f3a91 | ||
|
|
39f36c9184 | ||
|
|
7e7da26f29 | ||
|
|
4375a151dd | ||
|
|
0f02fb5d05 | ||
|
|
05edc1f9c4 | ||
|
|
2c0f0d9a20 | ||
|
|
d081ff745d | ||
|
|
dea214bd2e | ||
|
|
07bb095e73 | ||
|
|
e409029bb3 | ||
|
|
6201176852 | ||
|
|
7d958cc20e | ||
|
|
68e855e3d2 | ||
|
|
bf91352fce | ||
|
|
a840504b3d | ||
|
|
c60e99288f | ||
|
|
d9006d6e37 | ||
|
|
9121b83bd1 | ||
|
|
fad3db1556 | ||
|
|
9d4862b5c8 | ||
|
|
2a07999db6 | ||
|
|
ce2ffcafd3 | ||
|
|
3093794f72 | ||
|
|
abd05f5105 | ||
|
|
dcb2ad9d2d | ||
|
|
44d2e100bd | ||
|
|
8d9c114acd | ||
|
|
bce0950498 | ||
|
|
dcac64fb9a | ||
|
|
1770205ee1 | ||
|
|
5c7dfcb4a2 | ||
|
|
35e7460be8 | ||
|
|
87ebe77dfb | ||
|
|
5f85bff315 | ||
|
|
03ad87d651 | ||
|
|
a36c9ca339 | ||
|
|
f07709e80b | ||
|
|
7272c86592 | ||
|
|
706423462d | ||
|
|
bace0c5b2c | ||
|
|
3788a9161a | ||
|
|
7ab6c88774 | ||
|
|
96e40a6479 | ||
|
|
497824ff21 | ||
|
|
b8ce10ae96 |
@@ -10,6 +10,8 @@ script:
|
||||
- grunt docs
|
||||
- grunt node
|
||||
- grunt prod
|
||||
before_deploy:
|
||||
- grunt copy:ghPages
|
||||
deploy:
|
||||
- provider: pages
|
||||
skip_cleanup: true
|
||||
@@ -21,7 +23,7 @@ deploy:
|
||||
- provider: releases
|
||||
skip_cleaup: true
|
||||
api_key:
|
||||
secure: Lbya9e1a6bUeJLKsjuqRaNF/BNr7iqSjV0/9rhWbTCc5d1cd+A6DGnDqvw47S2x/+8b08XR5Umas5dS6KU4lLAZQ5DFJgKEuOqUDqz7fOfIZyaRKe8HBTrUn3c1zaqpbrIDQHAOwwEMSx3W+SXmFuniIHRkBFALfK/luyHb4u6e1vq9AsX59A6ICOl5fpGD8kHDtdFZtgCrrZ5tkX5wweiRUbro+LBNlfBCaXeuUwnigU0chAGx8wJWeSvHrndGoPPFEXc0MT4QPlI+q6R3AiO/mwS2/nLhEIGt4jrWUtyFQD9gFLZXg7Z6GC5pKqyf2EQXzgC8Kggybmbg5/MiWj1ns0d1XMK26r50bHD/9K7Kzlh5vq8Sum4DYWtuT4AsWgL/PfUEvB1FbF4InRJoIlbT3pWj9zNFKTyBNcvUchPk1uBE1Ldn5yPPZoSgdKO0ZiGjn/Qx0ByaDMGJbM5KMg3ALewJmaCiCbnvAaVvAm2UY6GrVK15JiGVn08GhliSzsx6E48ZcFtNJBwHK8MAimbTRyHR6aStJbEYIgoNiAjVv5m0twee/XknDvhULG2tor9chwhnqKb4kvaYPqbVuHNPyDT8VkLsHcpgeD2MKxGTq81NBgPz3rP3T1yWMxsuvhxoH91tIT8mU1jo8/e3BJYogKyRZXxwIHaF7ScDQZ4c=
|
||||
secure: "HV1WSKv4l/0Y2bKKs1iBJocBcmLj08PCRUeEM/jTwA4jqJ8EiLHWiXtER/D5sEg2iibRVKd2OQjfrmS6bo4AiwdeVgAKmv0FtS2Jw+391N8Nd5AkEANHa5Om/IpHLTL2YRAjpJTsDpY72bMUTJIwjQA3TFJkgrpOw6KYfohOcgbxLpZ4XuNJRU3VL4Hsxdv5V9aOVmfFOmMOVPQlakXy7NgtW5POp1f2WJwgcZxylkR1CjwaqMyXmSoVl46pyH3tr5+dptsQoKSGdi6sIHGA60oDotFPcm+0ifa47wZw+vapuuDi4tdNxhrHGaDMG8xiE0WFDHwQUDlk2/+W7j9SEX0H3Em7us371JXRp56EDwEcDa34VpVkC6i8HGcHK55hnxVbMZXGf3qhOFD8wY7qMbjMRvIpucrMHBi86OfkDfv0vDj2LyvIl5APj/AX50BrE0tfH1MZbH26Jkx4NdlkcxQ14GumarmUqfmVvbX/fsoA6oUuAAE9ZgRRi3KHO4wci6KUcRfdm+XOeUkaBFsL86G3EEYIvrtBTuaypdz+Cx7nd1iPZyWMx5Y1gXnVzha4nBdV4+7l9JIsFggD8QVpw2uHXQiS1KXFjOeqA3DBD8tjMB7q26Fl2fD3jkOo4BTbQ2NrRIZUu/iL+fOmMPsyMt2qulB0yaSBCfkbEq8xrUA="
|
||||
file:
|
||||
- build/prod/cyberchef.htm
|
||||
- build/node/CyberChef.js
|
||||
|
||||
29
Gruntfile.js
29
Gruntfile.js
@@ -28,10 +28,6 @@ module.exports = function (grunt) {
|
||||
"Creates a production-ready build. Use the --msg flag to add a compile message.",
|
||||
["eslint", "clean:prod", "webpack:webProd", "inline", "chmod"]);
|
||||
|
||||
grunt.registerTask("release",
|
||||
"Prepares and deploys a production version of CyberChef to the gh-pages branch.",
|
||||
["copy:ghPages", "exec:deployGhPages"]);
|
||||
|
||||
grunt.registerTask("default",
|
||||
"Lints the code base",
|
||||
["eslint", "exec:repoSize"]);
|
||||
@@ -54,6 +50,7 @@ module.exports = function (grunt) {
|
||||
grunt.loadNpmTasks("grunt-chmod");
|
||||
grunt.loadNpmTasks("grunt-exec");
|
||||
grunt.loadNpmTasks("grunt-execute");
|
||||
grunt.loadNpmTasks("grunt-accessibility");
|
||||
|
||||
|
||||
// Project configuration
|
||||
@@ -137,6 +134,18 @@ module.exports = function (grunt) {
|
||||
],
|
||||
}
|
||||
},
|
||||
accessibility: {
|
||||
options: {
|
||||
accessibilityLevel: "WCAG2A",
|
||||
verbose: false,
|
||||
ignore: [
|
||||
"WCAG2A.Principle1.Guideline1_3.1_3_1.H42.2"
|
||||
]
|
||||
},
|
||||
test: {
|
||||
src: ["build/**/*.html"]
|
||||
}
|
||||
},
|
||||
webpack: {
|
||||
options: {
|
||||
plugins: [
|
||||
@@ -295,7 +304,7 @@ module.exports = function (grunt) {
|
||||
process: function (content, srcpath) {
|
||||
// Add Google Analytics code to index.html
|
||||
content = content.replace("</body></html>",
|
||||
grunt.file.read("src/static/ga.html") + "</body></html>");
|
||||
grunt.file.read("src/web/static/ga.html") + "</body></html>");
|
||||
return grunt.template.process(content);
|
||||
}
|
||||
},
|
||||
@@ -328,16 +337,6 @@ module.exports = function (grunt) {
|
||||
cleanGit: {
|
||||
command: "git gc --prune=now --aggressive"
|
||||
},
|
||||
deployGhPages: {
|
||||
command: [
|
||||
"git add build/prod/index.html -v",
|
||||
"COMMIT_HASH=$(git rev-parse HEAD)",
|
||||
"git commit -m \"GitHub Pages release for ${COMMIT_HASH}\"",
|
||||
"git push origin `git subtree split --prefix build/prod master`:gh-pages --force",
|
||||
"git reset HEAD~",
|
||||
"git checkout build/prod/index.html"
|
||||
].join(";")
|
||||
}
|
||||
},
|
||||
execute: {
|
||||
test: "build/test/index.js"
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# CyberChef
|
||||
|
||||
[](https://travis-ci.org/gchq/CyberChef)
|
||||
|
||||
#### *The Cyber Swiss Army Knife*
|
||||
|
||||
CyberChef is a simple, intuitive web app for carrying out all manner of "cyber" operations within a web browser. These operations include creating hexdumps, simple encoding like XOR or Base64, more complex encryption like AES, DES and Blowfish, data compression and decompression, calculating hashes and checksums, IPv6 and X.509 parsing, and much more.
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"templates": {
|
||||
"systemName": "CyberChef",
|
||||
"footer": "",
|
||||
"copyright": "© Crown Copyright 2016",
|
||||
"copyright": "© Crown Copyright 2017",
|
||||
"navType": "inline",
|
||||
"theme": "cerulean",
|
||||
"linenums": true,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "cyberchef",
|
||||
"version": "5.0.0",
|
||||
"version": "5.2.2",
|
||||
"description": "CyberChef is a simple, intuitive web app for analysing and decoding data within a web browser.",
|
||||
"author": "n1474335 <n1474335@gmail.com>",
|
||||
"homepage": "https://gchq.github.io/CyberChef",
|
||||
@@ -35,6 +35,7 @@
|
||||
"extract-text-webpack-plugin": "^2.1.0",
|
||||
"file-loader": "^0.10.1",
|
||||
"grunt": ">=0.4.5",
|
||||
"grunt-accessibility": "~5.0.0",
|
||||
"grunt-chmod": "~1.1.1",
|
||||
"grunt-contrib-clean": "~1.0.0",
|
||||
"grunt-contrib-copy": "~1.0.0",
|
||||
|
||||
@@ -212,7 +212,7 @@ const Utils = {
|
||||
* @returns {string}
|
||||
*/
|
||||
printable: function(str, preserveWs) {
|
||||
if (window && window.app && !window.app.options.treatAsUtf8) {
|
||||
if (typeof window !== "undefined" && window.app && !window.app.options.treatAsUtf8) {
|
||||
str = Utils.byteArrayToChars(Utils.strToByteArray(str));
|
||||
}
|
||||
|
||||
@@ -388,8 +388,9 @@ const Utils = {
|
||||
var wordArray = CryptoJS.enc.Utf8.parse(str),
|
||||
byteArray = Utils.wordArrayToByteArray(wordArray);
|
||||
|
||||
if (window && str.length !== wordArray.sigBytes)
|
||||
if (typeof window !== "undefined" && str.length !== wordArray.sigBytes) {
|
||||
window.app.options.attemptHighlight = false;
|
||||
}
|
||||
return byteArray;
|
||||
},
|
||||
|
||||
@@ -440,7 +441,7 @@ const Utils = {
|
||||
var wordArray = new CryptoJS.lib.WordArray.init(words, byteArray.length),
|
||||
str = CryptoJS.enc.Utf8.stringify(wordArray);
|
||||
|
||||
if (window && str.length !== wordArray.sigBytes)
|
||||
if (typeof window !== "undefined" && str.length !== wordArray.sigBytes)
|
||||
window.app.options.attemptHighlight = false;
|
||||
return str;
|
||||
} catch (err) {
|
||||
|
||||
@@ -35,6 +35,8 @@ const Categories = [
|
||||
"From Decimal",
|
||||
"To Binary",
|
||||
"From Binary",
|
||||
"To Octal",
|
||||
"From Octal",
|
||||
"To Base64",
|
||||
"From Base64",
|
||||
"Show Base64 offsets",
|
||||
@@ -160,6 +162,8 @@ const Categories = [
|
||||
"Unique",
|
||||
"Split",
|
||||
"Filter",
|
||||
"Head",
|
||||
"Tail",
|
||||
"Count occurrences",
|
||||
"Expand alphabet range",
|
||||
"Parse escaped string",
|
||||
|
||||
@@ -425,7 +425,7 @@ const OperationConfig = {
|
||||
]
|
||||
},
|
||||
"From Hex": {
|
||||
description: "Converts a hexadecimal byte string back into a its raw value.<br><br>e.g. <code>ce 93 ce b5 ce b9 ce ac 20 cf 83 ce bf cf 85 0a</code> becomes the UTF-8 encoded string <code>Γειά σου</code>",
|
||||
description: "Converts a hexadecimal byte string back into its raw value.<br><br>e.g. <code>ce 93 ce b5 ce b9 ce ac 20 cf 83 ce bf cf 85 0a</code> becomes the UTF-8 encoded string <code>Γειά σου</code>",
|
||||
run: ByteRepr.runFromHex,
|
||||
highlight: ByteRepr.highlightFrom,
|
||||
highlightReverse: ByteRepr.highlightTo,
|
||||
@@ -454,6 +454,36 @@ const OperationConfig = {
|
||||
}
|
||||
]
|
||||
},
|
||||
"From Octal": {
|
||||
description: "Converts an octal byte string back into its raw value.<br><br>e.g. <code>316 223 316 265 316 271 316 254 40 317 203 316 277 317 205</code> becomes the UTF-8 encoded string <code>Γειά σου</code>",
|
||||
run: ByteRepr.runFromOct,
|
||||
highlight: false,
|
||||
highlightReverse: false,
|
||||
inputType: "string",
|
||||
outputType: "byteArray",
|
||||
args: [
|
||||
{
|
||||
name: "Delimiter",
|
||||
type: "option",
|
||||
value: ByteRepr.DELIM_OPTIONS
|
||||
}
|
||||
]
|
||||
},
|
||||
"To Octal": {
|
||||
description: "Converts the input string to octal bytes separated by the specified delimiter.<br><br>e.g. The UTF-8 encoded string <code>Γειά σου</code> becomes <code>316 223 316 265 316 271 316 254 40 317 203 316 277 317 205</code>",
|
||||
run: ByteRepr.runToOct,
|
||||
highlight: false,
|
||||
highlightReverse: false,
|
||||
inputType: "byteArray",
|
||||
outputType: "string",
|
||||
args: [
|
||||
{
|
||||
name: "Delimiter",
|
||||
type: "option",
|
||||
value: ByteRepr.DELIM_OPTIONS
|
||||
}
|
||||
]
|
||||
},
|
||||
"From Charcode": {
|
||||
description: "Converts unicode character codes back into text.<br><br>e.g. <code>0393 03b5 03b9 03ac 20 03c3 03bf 03c5</code> becomes <code>Γειά σου</code>",
|
||||
run: ByteRepr.runFromCharcode,
|
||||
@@ -3166,7 +3196,59 @@ const OperationConfig = {
|
||||
outputType: "html",
|
||||
args: [
|
||||
]
|
||||
}
|
||||
},
|
||||
"Head": {
|
||||
description: [
|
||||
"Like the UNIX head utility.",
|
||||
"<br>",
|
||||
"Gets the first n lines.",
|
||||
"<br>",
|
||||
"You can select all but the last n lines by entering a negative value for n.",
|
||||
"<br>",
|
||||
"The delimiter can be changed so that instead of lines, fields (i.e. commas) are selected instead.",
|
||||
].join("\n"),
|
||||
run: StrUtils.runHead,
|
||||
inputType: "string",
|
||||
outputType: "string",
|
||||
args: [
|
||||
{
|
||||
name: "Delimiter",
|
||||
type: "option",
|
||||
value: StrUtils.DELIMITER_OPTIONS
|
||||
},
|
||||
{
|
||||
name: "Number",
|
||||
type: "number",
|
||||
value: 10,
|
||||
},
|
||||
]
|
||||
},
|
||||
"Tail": {
|
||||
description: [
|
||||
"Like the UNIX tail utility.",
|
||||
"<br>",
|
||||
"Gets the last n lines.",
|
||||
"<br>",
|
||||
"Optionally you can select all lines after line n by entering a negative value for n.",
|
||||
"<br>",
|
||||
"The delimiter can be changed so that instead of lines, fields (i.e. commas) are selected instead.",
|
||||
].join("\n"),
|
||||
run: StrUtils.runTail,
|
||||
inputType: "string",
|
||||
outputType: "string",
|
||||
args: [
|
||||
{
|
||||
name: "Delimiter",
|
||||
type: "option",
|
||||
value: StrUtils.DELIMITER_OPTIONS
|
||||
},
|
||||
{
|
||||
name: "Number",
|
||||
type: "number",
|
||||
value: 10,
|
||||
},
|
||||
]
|
||||
},
|
||||
};
|
||||
|
||||
export default OperationConfig;
|
||||
|
||||
@@ -46,7 +46,19 @@ const Base = {
|
||||
if (radix < 2 || radix > 36) {
|
||||
throw "Error: Radix argument must be between 2 and 36";
|
||||
}
|
||||
return parseInt(input.replace(/\s/g, ""), radix);
|
||||
|
||||
var number = input.replace(/\s/g, "").split("."),
|
||||
result = parseInt(number[0], radix) || 0;
|
||||
|
||||
if (number.length === 1) return result;
|
||||
|
||||
// Fractional part
|
||||
for (var i = 0; i < number[1].length; i++) {
|
||||
var digit = parseInt(number[1][i], radix);
|
||||
result += digit / Math.pow(radix, i+1);
|
||||
}
|
||||
|
||||
return result;
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
@@ -55,6 +55,35 @@ const ByteRepr = {
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* To Octal operation.
|
||||
*
|
||||
* @author Matt C [matt@artemisbot.pw]
|
||||
* @param {byteArray} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
runToOct: function(input, args) {
|
||||
var delim = Utils.charRep[args[0] || "Space"];
|
||||
return input.map(val => val.toString(8)).join(delim);
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* From Octal operation.
|
||||
*
|
||||
* @author Matt C [matt@artemisbot.pw]
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {byteArray}
|
||||
*/
|
||||
runFromOct: function(input, args) {
|
||||
var delim = Utils.charRep[args[0] || "Space"];
|
||||
if (input.length === 0) return [];
|
||||
return input.split(delim).map(val => parseInt(val, 8));
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* @constant
|
||||
* @default
|
||||
|
||||
@@ -225,25 +225,20 @@ const Code = {
|
||||
regexes.lastIndex = m.index;
|
||||
}
|
||||
|
||||
// Create newlines after ;
|
||||
code = code.replace(/;/g, ";\n");
|
||||
|
||||
// Create newlines after { and around }
|
||||
code = code.replace(/{/g, "{\n");
|
||||
code = code.replace(/}/g, "\n}\n");
|
||||
|
||||
// Remove carriage returns
|
||||
code = code.replace(/\r/g, "");
|
||||
|
||||
// Remove all indentation
|
||||
code = code.replace(/^\s+/g, "");
|
||||
code = code.replace(/\n\s+/g, "\n");
|
||||
|
||||
// Remove trailing spaces
|
||||
code = code.replace(/\s*$/g, "");
|
||||
|
||||
// Remove newlines before {
|
||||
code = code.replace(/\n{/g, "{");
|
||||
code = code
|
||||
// Create newlines after ;
|
||||
.replace(/;/g, ";\n")
|
||||
// Create newlines after { and around }
|
||||
.replace(/{/g, "{\n")
|
||||
.replace(/}/g, "\n}\n")
|
||||
// Remove carriage returns
|
||||
.replace(/\r/g, "")
|
||||
// Remove all indentation
|
||||
.replace(/^\s+/g, "")
|
||||
.replace(/\n\s+/g, "\n")
|
||||
// Remove trailing spaces
|
||||
.replace(/\s*$/g, "")
|
||||
.replace(/\n{/g, "{");
|
||||
|
||||
// Indent
|
||||
var i = 0,
|
||||
@@ -266,30 +261,28 @@ const Code = {
|
||||
i++;
|
||||
}
|
||||
|
||||
// Add strategic spaces
|
||||
code = code.replace(/\s*([!<>=+-/*]?)=\s*/g, " $1= ");
|
||||
code = code.replace(/\s*<([=]?)\s*/g, " <$1 ");
|
||||
code = code.replace(/\s*>([=]?)\s*/g, " >$1 ");
|
||||
code = code.replace(/([^+])\+([^+=])/g, "$1 + $2");
|
||||
code = code.replace(/([^-])-([^-=])/g, "$1 - $2");
|
||||
code = code.replace(/([^*])\*([^*=])/g, "$1 * $2");
|
||||
code = code.replace(/([^/])\/([^/=])/g, "$1 / $2");
|
||||
code = code.replace(/\s*,\s*/g, ", ");
|
||||
code = code.replace(/\s*{/g, " {");
|
||||
code = code.replace(/}\n/g, "}\n\n");
|
||||
|
||||
// Just... don't look at this
|
||||
code = code.replace(/(if|for|while|with|elif|elseif)\s*\(([^\n]*)\)\s*\n([^{])/gim, "$1 ($2)\n $3");
|
||||
code = code.replace(/(if|for|while|with|elif|elseif)\s*\(([^\n]*)\)([^{])/gim, "$1 ($2) $3");
|
||||
code = code.replace(/else\s*\n([^{])/gim, "else\n $1");
|
||||
code = code.replace(/else\s+([^{])/gim, "else $1");
|
||||
|
||||
// Remove strategic spaces
|
||||
code = code.replace(/\s+;/g, ";");
|
||||
code = code.replace(/\{\s+\}/g, "{}");
|
||||
code = code.replace(/\[\s+\]/g, "[]");
|
||||
code = code.replace(/}\s*(else|catch|except|finally|elif|elseif|else if)/gi, "} $1");
|
||||
|
||||
code = code
|
||||
// Add strategic spaces
|
||||
.replace(/\s*([!<>=+-/*]?)=\s*/g, " $1= ")
|
||||
.replace(/\s*<([=]?)\s*/g, " <$1 ")
|
||||
.replace(/\s*>([=]?)\s*/g, " >$1 ")
|
||||
.replace(/([^+])\+([^+=])/g, "$1 + $2")
|
||||
.replace(/([^-])-([^-=])/g, "$1 - $2")
|
||||
.replace(/([^*])\*([^*=])/g, "$1 * $2")
|
||||
.replace(/([^/])\/([^/=])/g, "$1 / $2")
|
||||
.replace(/\s*,\s*/g, ", ")
|
||||
.replace(/\s*{/g, " {")
|
||||
.replace(/}\n/g, "}\n\n")
|
||||
// Hacky horribleness
|
||||
.replace(/(if|for|while|with|elif|elseif)\s*\(([^\n]*)\)\s*\n([^{])/gim, "$1 ($2)\n $3")
|
||||
.replace(/(if|for|while|with|elif|elseif)\s*\(([^\n]*)\)([^{])/gim, "$1 ($2) $3")
|
||||
.replace(/else\s*\n([^{])/gim, "else\n $1")
|
||||
.replace(/else\s+([^{])/gim, "else $1")
|
||||
// Remove strategic spaces
|
||||
.replace(/\s+;/g, ";")
|
||||
.replace(/\{\s+\}/g, "{}")
|
||||
.replace(/\[\s+\]/g, "[]")
|
||||
.replace(/}\s*(else|catch|except|finally|elif|elseif|else if)/gi, "} $1");
|
||||
|
||||
// Replace preserved tokens
|
||||
var ptokens = /###preservedToken(\d+)###/g;
|
||||
|
||||
@@ -460,6 +460,62 @@ const StrUtils = {
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Head lines operation.
|
||||
*
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
runHead: function(input, args) {
|
||||
let delimiter = args[0],
|
||||
number = args[1];
|
||||
|
||||
delimiter = Utils.charRep[delimiter];
|
||||
let splitInput = input.split(delimiter);
|
||||
|
||||
return splitInput
|
||||
.filter((line, lineIndex) => {
|
||||
lineIndex += 1;
|
||||
|
||||
if (number < 0) {
|
||||
return lineIndex <= splitInput.length + number;
|
||||
} else {
|
||||
return lineIndex <= number;
|
||||
}
|
||||
})
|
||||
.join(delimiter);
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Tail lines operation.
|
||||
*
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
runTail: function(input, args) {
|
||||
let delimiter = args[0],
|
||||
number = args[1];
|
||||
|
||||
delimiter = Utils.charRep[delimiter];
|
||||
let splitInput = input.split(delimiter);
|
||||
|
||||
return splitInput
|
||||
.filter((line, lineIndex) => {
|
||||
lineIndex += 1;
|
||||
|
||||
if (number < 0) {
|
||||
return lineIndex > -number;
|
||||
} else {
|
||||
return lineIndex > splitInput.length - number;
|
||||
}
|
||||
})
|
||||
.join(delimiter);
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Adds HTML highlights to matches within a string.
|
||||
*
|
||||
|
||||
@@ -13,7 +13,13 @@ const CyberChef = module.exports = {
|
||||
|
||||
bake: function(input, recipeConfig) {
|
||||
this.chef = new Chef();
|
||||
return this.chef.bake(input, recipeConfig, {}, 0, false);
|
||||
return this.chef.bake(
|
||||
input,
|
||||
recipeConfig,
|
||||
{},
|
||||
0,
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@@ -244,7 +244,7 @@ ControlsWaiter.prototype.loadClick = function() {
|
||||
* Saves the recipe specified in the save textarea to local storage.
|
||||
*/
|
||||
ControlsWaiter.prototype.saveButtonClick = function() {
|
||||
var recipeName = document.getElementById("save-name").value,
|
||||
var recipeName = Utils.escapeHtml(document.getElementById("save-name").value),
|
||||
recipeStr = document.getElementById("save-text").value;
|
||||
|
||||
if (!recipeName) {
|
||||
@@ -288,7 +288,8 @@ ControlsWaiter.prototype.populateLoadRecipesList = function() {
|
||||
for (i = 0; i < savedRecipes.length; i++) {
|
||||
var opt = document.createElement("option");
|
||||
opt.value = savedRecipes[i].id;
|
||||
opt.innerHTML = savedRecipes[i].name;
|
||||
// Unescape then re-escape in case localStorage has been corrupted
|
||||
opt.innerHTML = Utils.escapeHtml(Utils.unescapeHtml(savedRecipes[i].name));
|
||||
|
||||
loadNameEl.appendChild(opt);
|
||||
}
|
||||
|
||||
@@ -73,7 +73,9 @@ OperationsWaiter.prototype.searchOperations = function(e) {
|
||||
str = el.value;
|
||||
|
||||
while (searchResultsEl.firstChild) {
|
||||
$(searchResultsEl.firstChild).popover("destroy");
|
||||
try {
|
||||
$(searchResultsEl.firstChild).popover("destroy");
|
||||
} catch (err) {}
|
||||
searchResultsEl.removeChild(searchResultsEl.firstChild);
|
||||
}
|
||||
|
||||
@@ -209,7 +211,10 @@ OperationsWaiter.prototype.editFavouritesClick = function(e) {
|
||||
}
|
||||
},
|
||||
onEnd: function(evt) {
|
||||
if (this.removeIntent) evt.item.remove();
|
||||
if (this.removeIntent) {
|
||||
$(evt.item).popover("destroy");
|
||||
evt.item.remove();
|
||||
}
|
||||
}.bind(this),
|
||||
});
|
||||
|
||||
|
||||
@@ -26,7 +26,6 @@ var RecipeWaiter = function(app, manager) {
|
||||
RecipeWaiter.prototype.initialiseOperationDragNDrop = function() {
|
||||
var recList = document.getElementById("rec-list");
|
||||
|
||||
|
||||
// Recipe list
|
||||
Sortable.create(recList, {
|
||||
group: "recipe",
|
||||
@@ -43,6 +42,11 @@ RecipeWaiter.prototype.initialiseOperationDragNDrop = function() {
|
||||
evt.item.remove();
|
||||
evt.target.dispatchEvent(this.manager.operationremove);
|
||||
}
|
||||
}.bind(this),
|
||||
onSort: function(evt) {
|
||||
if (evt.from.id === "rec-list") {
|
||||
document.dispatchEvent(this.manager.statechange);
|
||||
}
|
||||
}.bind(this)
|
||||
});
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
-->
|
||||
<!-- htmlmin:ignore -->
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>CyberChef</title>
|
||||
@@ -32,7 +32,7 @@
|
||||
<link rel="icon" type="image/ico" href="<%- require('../static/images/favicon.ico') %>" />
|
||||
</head>
|
||||
<body>
|
||||
<span id="edit-favourites" class="btn btn-default btn-sm"><img src="<%- require('../static/images/favourite-16x16.png') %>" /> Edit</span>
|
||||
<span id="edit-favourites" class="btn btn-default btn-sm"><img aria-hidden="true" src="<%- require('../static/images/favourite-16x16.png') %>" alt="Star Icon"/> Edit</span>
|
||||
<div id="alert" class="alert alert-danger">
|
||||
<button type="button" class="close" id="alert-close">×</button>
|
||||
<span id="alert-content"></span>
|
||||
@@ -42,7 +42,7 @@
|
||||
<% if (htmlWebpackPlugin.options.inline) { %>
|
||||
<span style="float: left; margin-left: 10px;">Compile time: <%= htmlWebpackPlugin.options.compileTime %></span>
|
||||
<% } else { %>
|
||||
<a href="cyberchef.htm" style="float: left; margin-left: 10px; margin-right: 80px;" download>Download CyberChef<img src="<%- require('../static/images/download-24x24.png') %>" /></a>
|
||||
<a href="cyberchef.htm" style="float: left; margin-left: 10px; margin-right: 80px;" download>Download CyberChef<img aria-hidden="true" src="<%- require('../static/images/download-24x24.png') %>" alt="Download Icon"/></a>
|
||||
<% } %>
|
||||
<span id="notice">
|
||||
<script type="text/javascript">
|
||||
@@ -54,8 +54,8 @@
|
||||
</script>
|
||||
<noscript>JavaScript is not enabled. Good luck.</noscript>
|
||||
</span>
|
||||
<a href="#" id="support" class="banner-right" data-toggle="modal" data-target="#support-modal">About / Support<img src="<%- require('../static/images/help-22x22.png') %>" /></a>
|
||||
<a href="#" id="options" class="banner-right">Options<img src="<%- require('../static/images/settings-22x22.png') %>" /></a>
|
||||
<a href="#" id="support" class="banner-right" data-toggle="modal" data-target="#support-modal">About / Support<img aria-hidden="true" src="<%- require('../static/images/help-22x22.png') %>" alt="Question Mark Icon"/></a>
|
||||
<a href="#" id="options" class="banner-right">Options<img aria-hidden="true" src="<%- require('../static/images/settings-22x22.png') %>" alt="Settings Icon"/></a>
|
||||
</div>
|
||||
<div id="wrapper">
|
||||
<div id="operations" class="split split-horizontal no-select">
|
||||
@@ -73,25 +73,25 @@
|
||||
<div id="operational-controls">
|
||||
<div id="bake-group">
|
||||
<button type="button" class="btn btn-success btn-lg" id="bake">
|
||||
<img src="<%- require('../static/images/cook_male-32x32.png') %>" />
|
||||
<img aria-hidden="true" src="<%- require('../static/images/cook_male-32x32.png') %>" alt="Chef Icon"/>
|
||||
Bake!
|
||||
</button>
|
||||
<label class="btn btn-success btn-lg" id="auto-bake-label">
|
||||
<label class="btn btn-success btn-lg" id="auto-bake-label" for="auto-bake">
|
||||
<input type="checkbox" checked="checked" id="auto-bake">
|
||||
<div>Auto Bake</div>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="btn-group" style="padding-top: 10px;">
|
||||
<button type="button" class="btn btn-default" id="step"><img src="<%- require('../static/images/step-16x16.png') %>" /> Step through</button>
|
||||
<button type="button" class="btn btn-default" id="clr-breaks"><img src="<%- require('../static/images/erase-16x16.png') %>" /> Clear breakpoints</button>
|
||||
<button type="button" class="btn btn-default" id="step"><img aria-hidden="true" src="<%- require('../static/images/step-16x16.png') %>" alt="Footstep Icon"/> Step through</button>
|
||||
<button type="button" class="btn btn-default" id="clr-breaks"><img aria-hidden="true" src="<%- require('../static/images/erase-16x16.png') %>" alt="Eraser Icon"/> Clear breakpoints</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="btn-group-vertical" id="extra-controls">
|
||||
<button type="button" class="btn btn-default" id="save"><img src="<%- require('../static/images/save-16x16.png') %>" /> Save recipe</button>
|
||||
<button type="button" class="btn btn-default" id="load"><img src="<%- require('../static/images/open_yellow-16x16.png') %>" /> Load recipe</button>
|
||||
<button type="button" class="btn btn-default" id="clr-recipe"><img src="<%- require('../static/images/clean-16x16.png') %>" /> Clear recipe</button>
|
||||
<button type="button" class="btn btn-default" id="save"><img aria-hidden="true" src="<%- require('../static/images/save-16x16.png') %>" alt="Save Icon"/> Save recipe</button>
|
||||
<button type="button" class="btn btn-default" id="load"><img aria-hidden="true" src="<%- require('../static/images/open_yellow-16x16.png') %>" alt="Open Icon"/> Load recipe</button>
|
||||
<button type="button" class="btn btn-default" id="clr-recipe"><img aria-hidden="true" src="<%- require('../static/images/clean-16x16.png') %>" alt="Broom Icon"/> Clear recipe</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -99,10 +99,10 @@
|
||||
<div class="split split-horizontal" id="IO">
|
||||
<div id="input" class="split no-select">
|
||||
<div class="title no-select">
|
||||
Input
|
||||
<label for="input-text">Input</label>
|
||||
<div class="btn-group io-btn-group">
|
||||
<button type="button" class="btn btn-default btn-sm" id="clr-io"><img src="<%- require('../static/images/recycle-16x16.png') %>" /> Clear I/O</button>
|
||||
<button type="button" class="btn btn-default btn-sm" id="reset-layout"><img src="<%- require('../static/images/layout-16x16.png') %>" /> Reset layout</button>
|
||||
<button type="button" class="btn btn-default btn-sm" id="clr-io"><img aria-hidden="true" src="<%- require('../static/images/recycle-16x16.png') %>" alt="Recycle Icon"/> Clear I/O</button>
|
||||
<button type="button" class="btn btn-default btn-sm" id="reset-layout"><img aria-hidden="true" src="<%- require('../static/images/layout-16x16.png') %>" alt="Grid Icon"/> Reset layout</button>
|
||||
</div>
|
||||
<div class="io-info" id="input-info"></div>
|
||||
<div class="io-info" id="input-selection-info"></div>
|
||||
@@ -115,12 +115,12 @@
|
||||
|
||||
<div id="output" class="split">
|
||||
<div class="title no-select">
|
||||
Output
|
||||
<label for="output-text">Output</label>
|
||||
<div class="btn-group io-btn-group">
|
||||
<button type="button" class="btn btn-default btn-sm" id="save-to-file" title="Save to file"><img src="<%- require('../static/images/save_as-16x16.png') %>" /> Save to file</button>
|
||||
<button type="button" class="btn btn-default btn-sm" id="switch" title="Move output to input"><img src="<%- require('../static/images/switch-16x16.png') %>" /> Move output to input</button>
|
||||
<button type="button" class="btn btn-default btn-sm" id="undo-switch" title="Undo move" disabled="disabled"><img src="<%- require('../static/images/undo-16x16.png') %>" /> Undo</button>
|
||||
<button type="button" class="btn btn-default btn-sm" id="maximise-output" title="Maximise"><img src="<%- require('../static/images/maximise-16x16.png') %>" /> Max</button>
|
||||
<button type="button" class="btn btn-default btn-sm" id="save-to-file" title="Save to file"><img aria-hidden="true" src="<%- require('../static/images/save_as-16x16.png') %>" alt="Save Icon"/> Save to file</button>
|
||||
<button type="button" class="btn btn-default btn-sm" id="switch" title="Move output to input"><img aria-hidden="true" src="<%- require('../static/images/switch-16x16.png') %>" alt="Switch Icon"/> Move output to input</button>
|
||||
<button type="button" class="btn btn-default btn-sm" id="undo-switch" title="Undo move" disabled="disabled"><img aria-hidden="true" src="<%- require('../static/images/undo-16x16.png') %>" alt="Undo Icon"/> Undo</button>
|
||||
<button type="button" class="btn btn-default btn-sm" id="maximise-output" title="Maximise"><img aria-hidden="true" src="<%- require('../static/images/maximise-16x16.png') %>" alt="Maximise Icon"/> Max</button>
|
||||
</div>
|
||||
<div class="io-info" id="output-info"></div>
|
||||
<div class="io-info" id="output-selection-info"></div>
|
||||
@@ -139,7 +139,7 @@
|
||||
<div class="modal-dialog modal-lg">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<img class="pull-right" src="<%- require('../static/images/save-22x22.png') %>" />
|
||||
<img aria-hidden="true" class="pull-right" src="<%- require('../static/images/save-22x22.png') %>" alt="Save Icon"/>
|
||||
<h4 class="modal-title">Save recipe</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
@@ -160,8 +160,8 @@
|
||||
<div class="form-group" id="save-link-group">
|
||||
<label>Data link</label>
|
||||
<div class="save-link-options">
|
||||
<input type="checkbox" id="save-link-recipe-checkbox" checked> Include recipe
|
||||
<input type="checkbox" id="save-link-input-checkbox" checked> Include input
|
||||
<input type="checkbox" id="save-link-recipe-checkbox" checked> <label for="save-link-recipe-checkbox"> Include recipe </label>
|
||||
<input type="checkbox" id="save-link-input-checkbox" checked> <label for="save-link-input-checkbox"> Include input </label>
|
||||
</div>
|
||||
<a id="save-link" style="word-wrap: break-word;"></a>
|
||||
</div>
|
||||
@@ -174,15 +174,16 @@
|
||||
<div class="modal-dialog modal-lg">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<img class="pull-right" src="<%- require('../static/images/open_yellow-24x24.png') %>" />
|
||||
<img aria-hidden="true" class="pull-right" src="<%- require('../static/images/open_yellow-24x24.png') %>" alt="Open Icon"/>
|
||||
<h4 class="modal-title">Load recipe</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="form-group">
|
||||
<label for="load-name">Load your recipe from local storage or paste it into the box below</label>
|
||||
<label for="load-name">Load your recipe from local storage by selecting its name from the drop-down</label>
|
||||
<select class="form-control" id="load-name"></select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="load-text">Load your recipe by pasting it in the box below</label>
|
||||
<textarea class="form-control" id="load-text" rows="5"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
@@ -199,38 +200,38 @@
|
||||
<div class="modal-dialog modal-lg">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<img class="pull-right" src="<%- require('../static/images/settings-22x22.png') %>" />
|
||||
<img aria-hidden="true" class="pull-right" src="<%- require('../static/images/settings-22x22.png') %>" alt="Settings Icon"/>
|
||||
<h4 class="modal-title">Options</h4>
|
||||
</div>
|
||||
<div class="modal-body" id="options-body">
|
||||
<p style="font-weight: bold">Please note that these options will persist between sessions.</p>
|
||||
<div class="option-item">
|
||||
<input type="checkbox" option="update_url" checked />
|
||||
Update the URL when the input or recipe changes
|
||||
<input type="checkbox" option="update_url" id="update_url" checked />
|
||||
<label for="update_url"> Update the URL when the input or recipe changes </label>
|
||||
</div>
|
||||
<div class="option-item">
|
||||
<input type="checkbox" option="show_highlighter" checked />
|
||||
Highlight selected bytes in output and input (when possible)
|
||||
<input type="checkbox" option="show_highlighter" id="show_highlighter" checked />
|
||||
<label for="show_highlighter"> Highlight selected bytes in output and input (when possible) </label>
|
||||
</div>
|
||||
<div class="option-item">
|
||||
<input type="checkbox" option="treat_as_utf8" checked />
|
||||
Treat output as UTF-8 if possible
|
||||
<input type="checkbox" option="treat_as_utf8" id="treat_as_utf8" checked />
|
||||
<label for="treat_as_utf8"> Treat output as UTF-8 if possible </label>
|
||||
</div>
|
||||
<div class="option-item">
|
||||
<input type="checkbox" option="word_wrap" checked />
|
||||
Word wrap the input and output
|
||||
<input type="checkbox" option="word_wrap" id="word_wrap" checked />
|
||||
<label for="word_wrap"> Word wrap the input and output </label>
|
||||
</div>
|
||||
<div class="option-item">
|
||||
<input type="checkbox" option="show_errors" checked />
|
||||
Operation error reporting (recommended)
|
||||
<input type="checkbox" option="show_errors" id="show_errors" checked />
|
||||
<label for="show_errors"> Operation error reporting (recommended) </label>
|
||||
</div>
|
||||
<div class="option-item">
|
||||
<input type="number" option="error_timeout" />
|
||||
Operation error timeout in ms (0 for never)
|
||||
<input type="number" option="error_timeout" id="error_timeout" />
|
||||
<label for="error_timeout"> Operation error timeout in ms (0 for never) </label>
|
||||
</div>
|
||||
<div class="option-item">
|
||||
<input type="number" option="auto_bake_threshold" />
|
||||
Auto Bake threshold in ms
|
||||
<input type="number" option="auto_bake_threshold" id="auto_bake_threshold"/>
|
||||
<label for="auto_bake_threshold"> Auto Bake threshold in ms </label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
@@ -245,10 +246,10 @@
|
||||
<div class="modal-dialog modal-lg">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<img class="pull-right" src="<%- require('../static/images/favourite-24x24.png') %>" />
|
||||
<img aria-hidden="true" class="pull-right" src="<%- require('../static/images/favourite-24x24.png') %>" alt="Star Icon"/>
|
||||
<h4 class="modal-title">Edit Favourites</h4>
|
||||
</div>
|
||||
<div class="modal-body" id="options-body">
|
||||
<div class="modal-body" id="favourites-body">
|
||||
<ul>
|
||||
<li><span style="font-weight: bold">To add:</span> drag the operation over the favourites category</li>
|
||||
<li><span style="font-weight: bold">To reorder:</span> drag up and down in the list below</li>
|
||||
@@ -272,11 +273,11 @@
|
||||
<div class="modal-dialog modal-lg">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<img class="pull-right" src="<%- require('../static/images/help-22x22.png') %>" />
|
||||
<img aria-hidden="true" class="pull-right" src="<%- require('../static/images/help-22x22.png') %>" alt="Question Mark Icon"/>
|
||||
<h4 class="modal-title">CyberChef - The Cyber Swiss Army Knife</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<img class="about-img-left" src="<%- require('../static/images/cyberchef-128x128.png') %>" />
|
||||
<img aria-hidden="true" class="about-img-left" src="<%- require('../static/images/cyberchef-128x128.png') %>" alt="CyberChef Logo"/>
|
||||
<p class="subtext">Compile time: <%= htmlWebpackPlugin.options.compileTime %></p>
|
||||
<p>© Crown Copyright 2016.</p>
|
||||
<p>Licenced under the Apache Licence, Version 2.0.</p>
|
||||
@@ -285,15 +286,15 @@
|
||||
<div>
|
||||
<ul class="nav nav-tabs" role="tablist">
|
||||
<li role="presentation" class="active"><a href="#faqs" aria-controls="profile" role="tab" data-toggle="tab">
|
||||
<img src="<%- require('../static/images/help-16x16.png') %>" />
|
||||
<img aria-hidden="true" src="<%- require('../static/images/help-16x16.png') %>" alt="Question Mark Icon"/>
|
||||
FAQs
|
||||
</a></li>
|
||||
<li role="presentation"><a href="#report-bug" aria-controls="messages" role="tab" data-toggle="tab">
|
||||
<img src="<%- require('../static/images/bug-16x16.png') %>" />
|
||||
<img aria-hidden="true" src="<%- require('../static/images/bug-16x16.png') %>" alt="Bug Icon"/>
|
||||
Report a bug
|
||||
</a></li>
|
||||
<li role="presentation"><a href="#about" aria-controls="messages" role="tab" data-toggle="tab">
|
||||
<img src="<%- require('../static/images/speech-16x16.png') %>" />
|
||||
<img aria-hidden="true" src="<%- require('../static/images/speech-16x16.png') %>" alt="Speech Balloon Icon"/>
|
||||
About
|
||||
</a></li>
|
||||
</ul>
|
||||
@@ -372,7 +373,7 @@
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
|
||||
</div>
|
||||
<a href="https://github.com/gchq/CyberChef">
|
||||
<img style="position: absolute; top: 0; right: 0; border: 0;" src="<%- require('../static/images/fork_me.png') %>" alt="Fork me on GitHub">
|
||||
<img aria-hidden="true" style="position: absolute; top: 0; right: 0; border: 0;" src="<%- require('../static/images/fork_me.png') %>" alt="Fork me on GitHub">
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@@ -387,11 +388,11 @@
|
||||
<div class="modal-body" id="confirm-body"></div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-success" id="confirm-yes">
|
||||
<img src="<%- require('../static/images/thumb_up-16x16.png') %>" />
|
||||
<img aria-hidden="true" src="<%- require('../static/images/thumb_up-16x16.png') %>" alt="Thumbs Up"/>
|
||||
Yes
|
||||
</button>
|
||||
<button type="button" class="btn btn-danger" id="confirm-no" data-dismiss="modal">
|
||||
<img src="<%- require('../static/images/thumb_down-16x16.png') %>" />
|
||||
<img aria-hidden="true" src="<%- require('../static/images/thumb_down-16x16.png') %>" alt="Thumbs Down"/>
|
||||
No
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -12,6 +12,7 @@ import "babel-polyfill";
|
||||
|
||||
import TestRegister from "./TestRegister.js";
|
||||
import "./tests/operations/Base58.js";
|
||||
import "./tests/operations/ByteRepr.js";
|
||||
import "./tests/operations/Compress.js";
|
||||
import "./tests/operations/FlowControl.js";
|
||||
import "./tests/operations/MorseCode.js";
|
||||
|
||||
77
test/tests/operations/ByteRepr.js
Normal file
77
test/tests/operations/ByteRepr.js
Normal file
@@ -0,0 +1,77 @@
|
||||
/**
|
||||
* ByteRepr tests.
|
||||
*
|
||||
* @author Matt C [matt@artemisbot.pw]
|
||||
* @copyright Crown Copyright 2017
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
import TestRegister from "../../TestRegister.js";
|
||||
|
||||
TestRegister.addTests([
|
||||
{
|
||||
name: "To Octal: nothing",
|
||||
input: "",
|
||||
expectedOutput: "",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "To Octal",
|
||||
"args": ["Space"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "From Octal: nothing",
|
||||
input: "",
|
||||
expectedOutput: "",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "From Octal",
|
||||
"args": ["Space"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "To Octal: hello world",
|
||||
input: "hello world", // [104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100],
|
||||
expectedOutput: "150 145 154 154 157 40 167 157 162 154 144",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "To Octal",
|
||||
"args": ["Space"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "From Octal: hello world",
|
||||
input: "150 145 154 154 157 40 167 157 162 154 144",
|
||||
expectedOutput: "hello world",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "From Octal",
|
||||
"args": ["Space"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "To Octal: Γειά σου",
|
||||
input: "Γειά σου", //[206,147,206,181,206,185,206,172,32,207,131,206,191,207,133],
|
||||
expectedOutput: "316 223 316 265 316 271 316 254 40 317 203 316 277 317 205",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "To Octal",
|
||||
"args": ["Space"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "From Octal: Γειά σου",
|
||||
input: "316 223 316 265 316 271 316 254 40 317 203 316 277 317 205",
|
||||
expectedOutput: "Γειά σου",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "From Octal",
|
||||
"args": ["Space"]
|
||||
}
|
||||
]
|
||||
},
|
||||
]);
|
||||
@@ -34,4 +34,202 @@ TestRegister.addTests([
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Head 0",
|
||||
input: [1, 2, 3, 4, 5, 6].join("\n"),
|
||||
expectedOutput: [].join("\n"),
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Head",
|
||||
"args": ["Line feed", 0]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Head 1",
|
||||
input: [1, 2, 3, 4, 5, 6].join("\n"),
|
||||
expectedOutput: [1].join("\n"),
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Head",
|
||||
"args": ["Line feed", 1]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Head 2",
|
||||
input: [1, 2, 3, 4, 5, 6].join("\n"),
|
||||
expectedOutput: [1, 2].join("\n"),
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Head",
|
||||
"args": ["Line feed", 2]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Head 6",
|
||||
input: [1, 2, 3, 4, 5, 6].join("\n"),
|
||||
expectedOutput: [1, 2, 3, 4, 5, 6].join("\n"),
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Head",
|
||||
"args": ["Line feed", 6]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Head big",
|
||||
input: [1, 2, 3, 4, 5, 6].join("\n"),
|
||||
expectedOutput: [1, 2, 3, 4, 5, 6].join("\n"),
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Head",
|
||||
"args": ["Line feed", 100]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Head all but 1",
|
||||
input: [1, 2, 3, 4, 5, 6].join("\n"),
|
||||
expectedOutput: [1, 2, 3, 4, 5].join("\n"),
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Head",
|
||||
"args": ["Line feed", -1]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Head all but 2",
|
||||
input: [1, 2, 3, 4, 5, 6].join("\n"),
|
||||
expectedOutput: [1, 2, 3, 4].join("\n"),
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Head",
|
||||
"args": ["Line feed", -2]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Head all but 6",
|
||||
input: [1, 2, 3, 4, 5, 6].join("\n"),
|
||||
expectedOutput: [].join("\n"),
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Head",
|
||||
"args": ["Line feed", -6]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Head all but big",
|
||||
input: [1, 2, 3, 4, 5, 6].join("\n"),
|
||||
expectedOutput: [].join("\n"),
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Head",
|
||||
"args": ["Line feed", -100]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Tail 0",
|
||||
input: [1, 2, 3, 4, 5, 6].join("\n"),
|
||||
expectedOutput: [].join("\n"),
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Tail",
|
||||
"args": ["Line feed", 0]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Tail 1",
|
||||
input: [1, 2, 3, 4, 5, 6].join("\n"),
|
||||
expectedOutput: [6].join("\n"),
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Tail",
|
||||
"args": ["Line feed", 1]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Tail 2",
|
||||
input: [1, 2, 3, 4, 5, 6].join("\n"),
|
||||
expectedOutput: [5, 6].join("\n"),
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Tail",
|
||||
"args": ["Line feed", 2]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Tail 6",
|
||||
input: [1, 2, 3, 4, 5, 6].join("\n"),
|
||||
expectedOutput: [1, 2, 3, 4, 5, 6].join("\n"),
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Tail",
|
||||
"args": ["Line feed", 6]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Tail big",
|
||||
input: [1, 2, 3, 4, 5, 6].join("\n"),
|
||||
expectedOutput: [1, 2, 3, 4, 5, 6].join("\n"),
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Tail",
|
||||
"args": ["Line feed", 100]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Tail all but 1",
|
||||
input: [1, 2, 3, 4, 5, 6].join("\n"),
|
||||
expectedOutput: [2, 3, 4, 5, 6].join("\n"),
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Tail",
|
||||
"args": ["Line feed", -1]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Tail all but 2",
|
||||
input: [1, 2, 3, 4, 5, 6].join("\n"),
|
||||
expectedOutput: [3, 4, 5, 6].join("\n"),
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Tail",
|
||||
"args": ["Line feed", -2]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Tail all but 6",
|
||||
input: [1, 2, 3, 4, 5, 6].join("\n"),
|
||||
expectedOutput: [].join("\n"),
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Tail",
|
||||
"args": ["Line feed", -6]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Tail all but big",
|
||||
input: [1, 2, 3, 4, 5, 6].join("\n"),
|
||||
expectedOutput: [].join("\n"),
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Tail",
|
||||
"args": ["Line feed", -100]
|
||||
}
|
||||
],
|
||||
},
|
||||
]);
|
||||
|
||||
Reference in New Issue
Block a user