mirror of
https://github.com/gchq/CyberChef
synced 2025-12-15 15:53:30 +00:00
Compare commits
74 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
44ed372f21 | ||
|
|
4d1f970105 | ||
|
|
b28a891a40 | ||
|
|
834ff95702 | ||
|
|
3472484601 | ||
|
|
826a8c8a74 | ||
|
|
c66703f0ca | ||
|
|
874e7d8d54 | ||
|
|
4e2b85b8c8 | ||
|
|
5314a456cb | ||
|
|
ba2a5b195c | ||
|
|
f8115671ee | ||
|
|
494279edd8 | ||
|
|
bd6673afed | ||
|
|
210daf7324 | ||
|
|
06708949a1 | ||
|
|
da901e20d9 | ||
|
|
6810f38808 | ||
|
|
087cc6b8fd | ||
|
|
10c8101476 | ||
|
|
22028b074a | ||
|
|
3d086beed2 | ||
|
|
777d814e70 | ||
|
|
15c26a95c5 | ||
|
|
f87d3bd1cb | ||
|
|
b9ea1e8c71 | ||
|
|
db232f4ff2 | ||
|
|
70f705afbc | ||
|
|
880df212d5 | ||
|
|
b06acd99ec | ||
|
|
a59de80d18 | ||
|
|
1e8dee9935 | ||
|
|
928f1c3e4b | ||
|
|
014e70a7b1 | ||
|
|
5148b16246 | ||
|
|
b4ae4c5a00 | ||
|
|
70346bce35 | ||
|
|
3539e065fa | ||
|
|
8ffc58b340 | ||
|
|
503e733c81 | ||
|
|
7eabaf0de6 | ||
|
|
a8ad10757c | ||
|
|
111546ad1a | ||
|
|
a8fbd5164e | ||
|
|
8dde732514 | ||
|
|
f1659af5e4 | ||
|
|
e68fb51f44 | ||
|
|
95453131c8 | ||
|
|
c60d5c8e85 | ||
|
|
b31f32a7e7 | ||
|
|
f0b3bd0ede | ||
|
|
de5243ec67 | ||
|
|
c6de3eb2ae | ||
|
|
d7b6f29c81 | ||
|
|
5bebd71a44 | ||
|
|
eb769c7fb4 | ||
|
|
5bc5c0df90 | ||
|
|
cfc3684a16 | ||
|
|
0590020130 | ||
|
|
2a91af152d | ||
|
|
d8120d4e13 | ||
|
|
0ac211ce77 | ||
|
|
32c0d6f253 | ||
|
|
aa5afadcce | ||
|
|
d23a584b9e | ||
|
|
950a12360e | ||
|
|
48831225ac | ||
|
|
4e8a79d8f1 | ||
|
|
ad571e6019 | ||
|
|
14d924f6c7 | ||
|
|
282f02f4d5 | ||
|
|
d36cede0c7 | ||
|
|
a262d70b88 | ||
|
|
77b098c5fe |
33
.github/ISSUE_TEMPLATE/bug-report.md
vendored
Normal file
33
.github/ISSUE_TEMPLATE/bug-report.md
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: 'Bug report: <Insert title here>'
|
||||
labels: bug
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behaviour or a link to the recipe / input used to cause the bug:
|
||||
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Expected behaviour**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Desktop (if relevant, please complete the following information):**
|
||||
- OS: [e.g. Windows]
|
||||
- Browser [e.g. chrome, safari]
|
||||
- Version [e.g. 22]
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
1
.github/ISSUE_TEMPLATE/bug_report.md
vendored
1
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -32,4 +32,3 @@ If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
|
||||
|
||||
4
.github/ISSUE_TEMPLATE/feature_request.md
vendored
4
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@@ -6,9 +6,9 @@ labels: feature
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
<!-- Prefix the title above with 'Feature request:' -->
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
A clear and concise description of what the problem is. E.g. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
2
.github/ISSUE_TEMPLATE/operation-request.md
vendored
2
.github/ISSUE_TEMPLATE/operation-request.md
vendored
@@ -7,8 +7,6 @@ assignees: ''
|
||||
|
||||
---
|
||||
|
||||
<!-- Prefix the title above with 'Operation request:' -->
|
||||
|
||||
## Summary
|
||||
|
||||
### Example Input
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -4,7 +4,6 @@ travis.log
|
||||
build
|
||||
.vscode
|
||||
.*.swp
|
||||
.DS_Store
|
||||
src/core/config/modules/*
|
||||
src/core/config/OperationConfig.json
|
||||
src/core/operations/index.mjs
|
||||
|
||||
16
CHANGELOG.md
16
CHANGELOG.md
@@ -2,6 +2,15 @@
|
||||
All major and minor version changes will be documented in this file. Details of patch-level version changes can be found in [commit messages](https://github.com/gchq/CyberChef/commits/master).
|
||||
|
||||
|
||||
### [9.7.0] - 2019-09-13
|
||||
- 'Optical Character Recognition' operation added [@MShwed] [@n1474335] | [#632]
|
||||
|
||||
### [9.6.0] - 2019-09-04
|
||||
- 'Bacon Cipher Encode' and 'Bacon Cipher Decode' operations added [@kassi] | [#500]
|
||||
|
||||
### [9.5.0] - 2019-09-04
|
||||
- Various Steganography operations added: 'Extract LSB', 'Extract RGBA', 'Randomize Colour Palette', and 'View Bit Plane' [@Ge0rg3] | [#625]
|
||||
|
||||
### [9.4.0] - 2019-08-30
|
||||
- 'Render Markdown' operation added [@j433866] | [#627]
|
||||
|
||||
@@ -176,6 +185,9 @@ All major and minor version changes will be documented in this file. Details of
|
||||
|
||||
|
||||
|
||||
[9.7.0]: https://github.com/gchq/CyberChef/releases/tag/v9.7.0
|
||||
[9.6.0]: https://github.com/gchq/CyberChef/releases/tag/v9.6.0
|
||||
[9.5.0]: https://github.com/gchq/CyberChef/releases/tag/v9.5.0
|
||||
[9.4.0]: https://github.com/gchq/CyberChef/releases/tag/v9.4.0
|
||||
[9.3.0]: https://github.com/gchq/CyberChef/releases/tag/v9.3.0
|
||||
[9.2.0]: https://github.com/gchq/CyberChef/releases/tag/v9.2.0
|
||||
@@ -249,6 +261,7 @@ All major and minor version changes will be documented in this file. Details of
|
||||
[@masq]: https://github.com/masq
|
||||
[@Ge0rg3]: https://github.com/Ge0rg3
|
||||
[@MShwed]: https://github.com/MShwed
|
||||
[@kassi]: https://github.com/kassi
|
||||
|
||||
[#95]: https://github.com/gchq/CyberChef/pull/299
|
||||
[#173]: https://github.com/gchq/CyberChef/pull/173
|
||||
@@ -290,6 +303,7 @@ All major and minor version changes will be documented in this file. Details of
|
||||
[#477]: https://github.com/gchq/CyberChef/pull/477
|
||||
[#489]: https://github.com/gchq/CyberChef/pull/489
|
||||
[#496]: https://github.com/gchq/CyberChef/pull/496
|
||||
[#500]: https://github.com/gchq/CyberChef/pull/500
|
||||
[#506]: https://github.com/gchq/CyberChef/pull/506
|
||||
[#515]: https://github.com/gchq/CyberChef/pull/515
|
||||
[#516]: https://github.com/gchq/CyberChef/pull/516
|
||||
@@ -305,4 +319,6 @@ All major and minor version changes will be documented in this file. Details of
|
||||
[#591]: https://github.com/gchq/CyberChef/pull/591
|
||||
[#595]: https://github.com/gchq/CyberChef/pull/595
|
||||
[#614]: https://github.com/gchq/CyberChef/pull/614
|
||||
[#625]: https://github.com/gchq/CyberChef/pull/625
|
||||
[#627]: https://github.com/gchq/CyberChef/pull/627
|
||||
[#632]: https://github.com/gchq/CyberChef/pull/632
|
||||
|
||||
@@ -140,8 +140,7 @@ module.exports = function (grunt) {
|
||||
mode: "production",
|
||||
target: "web",
|
||||
entry: Object.assign({
|
||||
main: "./src/web/index.js",
|
||||
sitemap: "./src/web/static/sitemap.js"
|
||||
main: "./src/web/index.js"
|
||||
}, moduleEntryPoints),
|
||||
output: {
|
||||
path: __dirname + "/build/prod",
|
||||
@@ -232,7 +231,6 @@ module.exports = function (grunt) {
|
||||
"build/prod/**/*",
|
||||
"!build/prod/index.html",
|
||||
"!build/prod/BundleAnalyzerReport.html",
|
||||
"!build/prod/sitemap.js"
|
||||
],
|
||||
dest: `build/prod/CyberChef_v${pkg.version}.zip`
|
||||
}
|
||||
@@ -328,7 +326,7 @@ module.exports = function (grunt) {
|
||||
command: "git gc --prune=now --aggressive"
|
||||
},
|
||||
sitemap: {
|
||||
command: "node build/prod/sitemap.js > build/prod/sitemap.xml"
|
||||
command: "node --experimental-modules --no-warnings --no-deprecation src/web/static/sitemap.mjs > build/prod/sitemap.xml"
|
||||
},
|
||||
generateConfig: {
|
||||
command: [
|
||||
|
||||
2643
package-lock.json
generated
2643
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
67
package.json
67
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "cyberchef",
|
||||
"version": "9.4.0",
|
||||
"version": "9.7.11",
|
||||
"description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.",
|
||||
"author": "n1474335 <n1474335@gmail.com>",
|
||||
"homepage": "https://gchq.github.io/CyberChef",
|
||||
@@ -36,19 +36,20 @@
|
||||
"node >= 10"
|
||||
],
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.5.0",
|
||||
"@babel/plugin-transform-runtime": "^7.5.0",
|
||||
"@babel/preset-env": "^7.5.0",
|
||||
"autoprefixer": "^9.6.0",
|
||||
"babel-eslint": "^10.0.2",
|
||||
"@babel/core": "^7.5.5",
|
||||
"@babel/plugin-transform-runtime": "^7.5.5",
|
||||
"@babel/preset-env": "^7.5.5",
|
||||
"autoprefixer": "^9.6.1",
|
||||
"babel-eslint": "^10.0.3",
|
||||
"babel-loader": "^8.0.6",
|
||||
"babel-plugin-dynamic-import-node": "^2.2.0",
|
||||
"chromedriver": "^75.0.1",
|
||||
"babel-plugin-dynamic-import-node": "^2.3.0",
|
||||
"chromedriver": "^76.0.1",
|
||||
"colors": "^1.3.3",
|
||||
"css-loader": "^3.0.0",
|
||||
"eslint": "^6.0.1",
|
||||
"copy-webpack-plugin": "^5.0.4",
|
||||
"css-loader": "^3.2.0",
|
||||
"eslint": "^6.2.2",
|
||||
"exports-loader": "^0.7.0",
|
||||
"file-loader": "^4.0.0",
|
||||
"file-loader": "^4.2.0",
|
||||
"grunt": "^1.0.4",
|
||||
"grunt-accessibility": "~6.0.0",
|
||||
"grunt-chmod": "~1.1.1",
|
||||
@@ -63,27 +64,27 @@
|
||||
"grunt-zip": "^0.18.2",
|
||||
"html-webpack-plugin": "^3.2.0",
|
||||
"imports-loader": "^0.8.0",
|
||||
"mini-css-extract-plugin": "^0.7.0",
|
||||
"nightwatch": "^1.1.13",
|
||||
"mini-css-extract-plugin": "^0.8.0",
|
||||
"nightwatch": "^1.2.1",
|
||||
"node-sass": "^4.12.0",
|
||||
"postcss-css-variables": "^0.13.0",
|
||||
"postcss-import": "^12.0.1",
|
||||
"postcss-loader": "^3.0.0",
|
||||
"prompt": "^1.0.0",
|
||||
"sass-loader": "^7.1.0",
|
||||
"sitemap": "^3.2.0",
|
||||
"style-loader": "^0.23.1",
|
||||
"svg-url-loader": "^3.0.0",
|
||||
"url-loader": "^2.0.1",
|
||||
"webpack": "^4.35.2",
|
||||
"webpack-bundle-analyzer": "^3.3.2",
|
||||
"webpack-dev-server": "^3.7.2",
|
||||
"sass-loader": "^8.0.0",
|
||||
"sitemap": "^4.1.1",
|
||||
"style-loader": "^1.0.0",
|
||||
"svg-url-loader": "^3.0.1",
|
||||
"url-loader": "^2.1.0",
|
||||
"webpack": "^4.39.3",
|
||||
"webpack-bundle-analyzer": "^3.4.1",
|
||||
"webpack-dev-server": "^3.8.0",
|
||||
"webpack-node-externals": "^1.7.2",
|
||||
"worker-loader": "^2.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/polyfill": "^7.4.4",
|
||||
"@babel/runtime": "^7.5.0",
|
||||
"@babel/runtime": "^7.5.5",
|
||||
"arrive": "^2.4.1",
|
||||
"babel-plugin-transform-builtin-extend": "1.1.2",
|
||||
"bcryptjs": "^2.4.3",
|
||||
@@ -95,22 +96,22 @@
|
||||
"bson": "^4.0.2",
|
||||
"chi-squared": "^1.1.0",
|
||||
"clippyjs": "0.0.3",
|
||||
"core-js": "^3.1.4",
|
||||
"crypto-api": "^0.8.3",
|
||||
"core-js": "^3.2.1",
|
||||
"crypto-api": "^0.8.5",
|
||||
"crypto-js": "^3.1.9-1",
|
||||
"ctph.js": "0.0.5",
|
||||
"d3": "^5.9.7",
|
||||
"d3": "^5.11.0",
|
||||
"d3-hexbin": "^0.2.2",
|
||||
"diff": "^4.0.1",
|
||||
"es6-promisify": "^6.0.1",
|
||||
"escodegen": "^1.11.1",
|
||||
"es6-promisify": "^6.0.2",
|
||||
"escodegen": "^1.12.0",
|
||||
"esm": "^3.2.25",
|
||||
"esmangle": "^1.0.1",
|
||||
"esprima": "^4.0.1",
|
||||
"exif-parser": "^0.1.12",
|
||||
"file-saver": "^2.0.2",
|
||||
"geodesy": "^1.1.3",
|
||||
"highlight.js": "^9.15.8",
|
||||
"highlight.js": "^9.15.10",
|
||||
"jimp": "^0.6.4",
|
||||
"jquery": "3.4.1",
|
||||
"js-crc": "^0.2.0",
|
||||
@@ -120,17 +121,17 @@
|
||||
"jsonwebtoken": "^8.5.1",
|
||||
"jsqr": "^1.2.0",
|
||||
"jsrsasign": "8.0.12",
|
||||
"kbpgp": "2.1.2",
|
||||
"kbpgp": "2.1.3",
|
||||
"libbzip2-wasm": "0.0.4",
|
||||
"libyara-wasm": "0.0.12",
|
||||
"lodash": "^4.17.15",
|
||||
"loglevel": "^1.6.3",
|
||||
"loglevel-message-prefix": "^3.0.0",
|
||||
"markdown-it": "^9.0.0",
|
||||
"markdown-it": "^9.1.0",
|
||||
"moment": "^2.24.0",
|
||||
"moment-timezone": "^0.5.25",
|
||||
"moment-timezone": "^0.5.26",
|
||||
"ngeohash": "^0.6.3",
|
||||
"node-forge": "^0.8.5",
|
||||
"node-forge": "^0.9.1",
|
||||
"node-md6": "^0.1.0",
|
||||
"nodom": "^2.2.0",
|
||||
"notepack.io": "^2.2.0",
|
||||
@@ -143,6 +144,7 @@
|
||||
"sortablejs": "^1.9.0",
|
||||
"split.js": "^1.5.11",
|
||||
"ssdeep.js": "0.0.2",
|
||||
"tesseract.js": "^2.0.0-alpha.15",
|
||||
"ua-parser-js": "^0.7.20",
|
||||
"utf8": "^3.0.0",
|
||||
"vkbeautify": "^0.99.3",
|
||||
@@ -158,6 +160,7 @@
|
||||
"test": "grunt test",
|
||||
"test-node-consumer": "grunt testnodeconsumer",
|
||||
"testui": "grunt testui",
|
||||
"testuidev": "npx nightwatch --env=dev",
|
||||
"lint": "grunt lint",
|
||||
"newop": "node --experimental-modules src/core/config/scripts/newOperation.mjs"
|
||||
}
|
||||
|
||||
@@ -177,7 +177,7 @@ class Dish {
|
||||
this.type = type;
|
||||
|
||||
if (!this.valid()) {
|
||||
const sample = Utils.truncate(JSON.stringify(this.value), 13);
|
||||
const sample = Utils.truncate(JSON.stringify(this.value), 25);
|
||||
throw new DishError(`Data is not a valid ${Dish.enumLookup(type)}: ${sample}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,6 +85,8 @@
|
||||
"Vigenère Decode",
|
||||
"To Morse Code",
|
||||
"From Morse Code",
|
||||
"Bacon Cipher Encode",
|
||||
"Bacon Cipher Decode",
|
||||
"Bifid Cipher Encode",
|
||||
"Bifid Cipher Decode",
|
||||
"Affine Cipher Encode",
|
||||
@@ -121,6 +123,7 @@
|
||||
"Generate PGP Key Pair",
|
||||
"PGP Encrypt",
|
||||
"PGP Decrypt",
|
||||
"PGP Verify",
|
||||
"PGP Encrypt and Sign",
|
||||
"PGP Decrypt and Verify",
|
||||
"Parse SSH Host Key"
|
||||
@@ -282,6 +285,7 @@
|
||||
"Zip",
|
||||
"Unzip",
|
||||
"Bzip2 Decompress",
|
||||
"Bzip2 Compress",
|
||||
"Tar",
|
||||
"Untar"
|
||||
]
|
||||
@@ -368,8 +372,13 @@
|
||||
"Detect File Type",
|
||||
"Scan for Embedded Files",
|
||||
"Extract Files",
|
||||
"YARA Rules",
|
||||
"Remove EXIF",
|
||||
"Extract EXIF"
|
||||
"Extract EXIF",
|
||||
"Extract RGBA",
|
||||
"View Bit Plane",
|
||||
"Randomize Colour Palette",
|
||||
"Extract LSB"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -377,6 +386,7 @@
|
||||
"ops": [
|
||||
"Render Image",
|
||||
"Play Media",
|
||||
"Optical Character Recognition",
|
||||
"Remove EXIF",
|
||||
"Extract EXIF",
|
||||
"Split Colour Channels",
|
||||
@@ -394,6 +404,7 @@
|
||||
"Cover Image",
|
||||
"Image Hue/Saturation/Lightness",
|
||||
"Sharpen Image",
|
||||
"Normalise Image",
|
||||
"Convert Image Format",
|
||||
"Add Text To Image",
|
||||
"Hex Density chart",
|
||||
|
||||
9
src/core/errors/index.mjs
Normal file
9
src/core/errors/index.mjs
Normal file
@@ -0,0 +1,9 @@
|
||||
import OperationError from "./OperationError.mjs";
|
||||
import DishError from "./DishError.mjs";
|
||||
import ExcludedOperationError from "./ExcludedOperationError";
|
||||
|
||||
export {
|
||||
OperationError,
|
||||
DishError,
|
||||
ExcludedOperationError,
|
||||
};
|
||||
66
src/core/lib/Bacon.mjs
Normal file
66
src/core/lib/Bacon.mjs
Normal file
@@ -0,0 +1,66 @@
|
||||
/**
|
||||
* Bacon Cipher resources.
|
||||
*
|
||||
* @author Karsten Silkenbäumer [github.com/kassi]
|
||||
* @copyright Karsten Silkenbäumer 2019
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Bacon definitions.
|
||||
*/
|
||||
export const BACON_ALPHABETS = {
|
||||
"Standard (I=J and U=V)": {
|
||||
alphabet: "ABCDEFGHIKLMNOPQRSTUWXYZ",
|
||||
codes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 23]
|
||||
},
|
||||
"Complete": {
|
||||
alphabet: "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
}
|
||||
};
|
||||
export const BACON_TRANSLATION_01 = "0/1";
|
||||
export const BACON_TRANSLATION_AB = "A/B";
|
||||
export const BACON_TRANSLATION_CASE = "Case";
|
||||
export const BACON_TRANSLATION_AMNZ = "A-M/N-Z first letter";
|
||||
export const BACON_TRANSLATIONS = [
|
||||
BACON_TRANSLATION_01,
|
||||
BACON_TRANSLATION_AB,
|
||||
BACON_TRANSLATION_CASE,
|
||||
BACON_TRANSLATION_AMNZ,
|
||||
];
|
||||
export const BACON_TRANSLATIONS_FOR_ENCODING = [
|
||||
BACON_TRANSLATION_01,
|
||||
BACON_TRANSLATION_AB
|
||||
];
|
||||
export const BACON_CLEARER_MAP = {
|
||||
[BACON_TRANSLATION_01]: /[^01]/g,
|
||||
[BACON_TRANSLATION_AB]: /[^ABab]/g,
|
||||
[BACON_TRANSLATION_CASE]: /[^A-Za-z]/g,
|
||||
};
|
||||
export const BACON_NORMALIZE_MAP = {
|
||||
[BACON_TRANSLATION_AB]: {
|
||||
"A": "0",
|
||||
"B": "1",
|
||||
"a": "0",
|
||||
"b": "1"
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Swaps zeros to ones and ones to zeros.
|
||||
*
|
||||
* @param {string} data
|
||||
* @returns {string}
|
||||
*
|
||||
* @example
|
||||
* // returns "11001 01010"
|
||||
* swapZeroAndOne("00110 10101");
|
||||
*/
|
||||
export function swapZeroAndOne(string) {
|
||||
return string.replace(/[01]/g, function (c) {
|
||||
return {
|
||||
"0": "1",
|
||||
"1": "0"
|
||||
}[c];
|
||||
});
|
||||
}
|
||||
@@ -7,12 +7,12 @@
|
||||
*/
|
||||
|
||||
import Utils from "../Utils.mjs";
|
||||
|
||||
import OperationError from "../errors/OperationError.mjs";
|
||||
|
||||
/**
|
||||
* Base64's the input byte array using the given alphabet, returning a string.
|
||||
*
|
||||
* @param {byteArray|Uint8Array|string} data
|
||||
* @param {byteArray|Uint8Array|ArrayBuffer|string} data
|
||||
* @param {string} [alphabet="A-Za-z0-9+/="]
|
||||
* @returns {string}
|
||||
*
|
||||
@@ -25,11 +25,17 @@ import Utils from "../Utils.mjs";
|
||||
*/
|
||||
export function toBase64(data, alphabet="A-Za-z0-9+/=") {
|
||||
if (!data) return "";
|
||||
if (data instanceof ArrayBuffer) {
|
||||
data = new Uint8Array(data);
|
||||
}
|
||||
if (typeof data == "string") {
|
||||
data = Utils.strToByteArray(data);
|
||||
}
|
||||
|
||||
alphabet = Utils.expandAlphRange(alphabet).join("");
|
||||
if (alphabet.length !== 64 && alphabet.length !== 65) { // Allow for padding
|
||||
throw new OperationError(`Invalid Base64 alphabet length (${alphabet.length}): ${alphabet}`);
|
||||
}
|
||||
|
||||
let output = "",
|
||||
chr1, chr2, chr3,
|
||||
@@ -83,6 +89,9 @@ export function fromBase64(data, alphabet="A-Za-z0-9+/=", returnType="string", r
|
||||
|
||||
alphabet = alphabet || "A-Za-z0-9+/=";
|
||||
alphabet = Utils.expandAlphRange(alphabet).join("");
|
||||
if (alphabet.length !== 64 && alphabet.length !== 65) { // Allow for padding
|
||||
throw new OperationError(`Invalid Base64 alphabet length (${alphabet.length}): ${alphabet}`);
|
||||
}
|
||||
|
||||
const output = [];
|
||||
let chr1, chr2, chr3,
|
||||
|
||||
@@ -6,9 +6,22 @@
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import geohash from "ngeohash";
|
||||
import geodesy from "geodesy";
|
||||
import OperationError from "../errors/OperationError.mjs";
|
||||
import geohash from "ngeohash";
|
||||
/*
|
||||
Currently unable to update to geodesy v2 as we cannot load .js modules into a .mjs file.
|
||||
When we do update, imports will look like this:
|
||||
|
||||
import LatLonEllipsoidal from "geodesy/latlon-ellipsoidal.js";
|
||||
import Mgrs from "geodesy/mgrs.js";
|
||||
import OsGridRef from "geodesy/osgridref.js";
|
||||
import Utm from "geodesy/utm.js";
|
||||
*/
|
||||
import geodesy from "geodesy";
|
||||
const LatLonEllipsoidal = geodesy.LatLonEllipsoidal,
|
||||
Mgrs = geodesy.Mgrs,
|
||||
OsGridRef = geodesy.OsGridRef,
|
||||
Utm = geodesy.Utm;
|
||||
|
||||
/**
|
||||
* Co-ordinate formats
|
||||
@@ -116,22 +129,22 @@ export function convertCoordinates (input, inFormat, inDelim, outFormat, outDeli
|
||||
switch (inFormat) {
|
||||
case "Geohash":
|
||||
hash = geohash.decode(input.replace(/[^A-Za-z0-9]/g, ""));
|
||||
latlon = new geodesy.LatLonEllipsoidal(hash.latitude, hash.longitude);
|
||||
latlon = new LatLonEllipsoidal(hash.latitude, hash.longitude);
|
||||
break;
|
||||
case "Military Grid Reference System":
|
||||
utm = geodesy.Mgrs.parse(input.replace(/[^A-Za-z0-9]/g, "")).toUtm();
|
||||
utm = Mgrs.parse(input.replace(/[^A-Za-z0-9]/g, "")).toUtm();
|
||||
latlon = utm.toLatLonE();
|
||||
break;
|
||||
case "Ordnance Survey National Grid":
|
||||
osng = geodesy.OsGridRef.parse(input.replace(/[^A-Za-z0-9]/g, ""));
|
||||
latlon = geodesy.OsGridRef.osGridToLatLon(osng);
|
||||
osng = OsGridRef.parse(input.replace(/[^A-Za-z0-9]/g, ""));
|
||||
latlon = OsGridRef.osGridToLatLon(osng);
|
||||
break;
|
||||
case "Universal Transverse Mercator":
|
||||
// Geodesy needs a space between the first 2 digits and the next letter
|
||||
if (/^[\d]{2}[A-Za-z]/.test(input)) {
|
||||
input = input.slice(0, 2) + " " + input.slice(2);
|
||||
}
|
||||
utm = geodesy.Utm.parse(input);
|
||||
utm = Utm.parse(input);
|
||||
latlon = utm.toLatLonE();
|
||||
break;
|
||||
case "Degrees Minutes Seconds":
|
||||
@@ -143,7 +156,7 @@ export function convertCoordinates (input, inFormat, inDelim, outFormat, outDeli
|
||||
if (splitLat.length >= 3 && splitLong.length >= 3) {
|
||||
lat = convDMSToDD(splitLat[0], splitLat[1], splitLat[2], 10);
|
||||
lon = convDMSToDD(splitLong[0], splitLong[1], splitLong[2], 10);
|
||||
latlon = new geodesy.LatLonEllipsoidal(lat.degrees, lon.degrees);
|
||||
latlon = new LatLonEllipsoidal(lat.degrees, lon.degrees);
|
||||
} else {
|
||||
throw new OperationError("Invalid co-ordinate format for Degrees Minutes Seconds");
|
||||
}
|
||||
@@ -152,7 +165,7 @@ export function convertCoordinates (input, inFormat, inDelim, outFormat, outDeli
|
||||
splitLat = splitInput(split[0]);
|
||||
if (splitLat.length >= 3) {
|
||||
lat = convDMSToDD(splitLat[0], splitLat[1], splitLat[2]);
|
||||
latlon = new geodesy.LatLonEllipsoidal(lat.degrees, lat.degrees);
|
||||
latlon = new LatLonEllipsoidal(lat.degrees, lat.degrees);
|
||||
} else {
|
||||
throw new OperationError("Invalid co-ordinate format for Degrees Minutes Seconds");
|
||||
}
|
||||
@@ -168,7 +181,7 @@ export function convertCoordinates (input, inFormat, inDelim, outFormat, outDeli
|
||||
// Convert to decimal degrees, and then convert to a geodesy object
|
||||
lat = convDDMToDD(splitLat[0], splitLat[1], 10);
|
||||
lon = convDDMToDD(splitLong[0], splitLong[1], 10);
|
||||
latlon = new geodesy.LatLonEllipsoidal(lat.degrees, lon.degrees);
|
||||
latlon = new LatLonEllipsoidal(lat.degrees, lon.degrees);
|
||||
} else {
|
||||
// Not a pair, so only try to convert one set of co-ordinates
|
||||
splitLat = splitInput(input);
|
||||
@@ -176,7 +189,7 @@ export function convertCoordinates (input, inFormat, inDelim, outFormat, outDeli
|
||||
throw new OperationError("Invalid co-ordinate format for Degrees Decimal Minutes.");
|
||||
}
|
||||
lat = convDDMToDD(splitLat[0], splitLat[1], 10);
|
||||
latlon = new geodesy.LatLonEllipsoidal(lat.degrees, lat.degrees);
|
||||
latlon = new LatLonEllipsoidal(lat.degrees, lat.degrees);
|
||||
}
|
||||
break;
|
||||
case "Decimal Degrees":
|
||||
@@ -186,14 +199,14 @@ export function convertCoordinates (input, inFormat, inDelim, outFormat, outDeli
|
||||
if (splitLat.length !== 1 || splitLong.length !== 1) {
|
||||
throw new OperationError("Invalid co-ordinate format for Decimal Degrees.");
|
||||
}
|
||||
latlon = new geodesy.LatLonEllipsoidal(splitLat[0], splitLong[0]);
|
||||
latlon = new LatLonEllipsoidal(splitLat[0], splitLong[0]);
|
||||
} else {
|
||||
// Not a pair, so only try to convert one set of co-ordinates
|
||||
splitLat = splitInput(split[0]);
|
||||
if (splitLat.length !== 1) {
|
||||
throw new OperationError("Invalid co-ordinate format for Decimal Degrees.");
|
||||
}
|
||||
latlon = new geodesy.LatLonEllipsoidal(splitLat[0], splitLat[0]);
|
||||
latlon = new LatLonEllipsoidal(splitLat[0], splitLat[0]);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -260,7 +273,7 @@ export function convertCoordinates (input, inFormat, inDelim, outFormat, outDeli
|
||||
convLat = mgrs.toString(precision);
|
||||
break;
|
||||
case "Ordnance Survey National Grid":
|
||||
osng = geodesy.OsGridRef.latLonToOsGrid(latlon);
|
||||
osng = OsGridRef.latLonToOsGrid(latlon);
|
||||
if (osng.toString() === "") {
|
||||
throw new OperationError("Could not convert co-ordinates to OS National Grid. Are the co-ordinates in range?");
|
||||
}
|
||||
|
||||
@@ -72,3 +72,12 @@ export const JOIN_DELIM_OPTIONS = [
|
||||
{name: "Nothing (join chars)", value: ""}
|
||||
];
|
||||
|
||||
/**
|
||||
* RGBA list delimiters.
|
||||
*/
|
||||
export const RGBA_DELIM_OPTIONS = [
|
||||
{name: "Comma", value: ","},
|
||||
{name: "Space", value: " "},
|
||||
{name: "CRLF", value: "\\r\\n"},
|
||||
{name: "Line Feed", value: "\n"}
|
||||
];
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -75,7 +75,7 @@ function bytesMatch(sig, buf, offset=0) {
|
||||
* Given a buffer, detects magic byte sequences at specific positions and returns the
|
||||
* extension and mime type.
|
||||
*
|
||||
* @param {Uint8Array} buf
|
||||
* @param {Uint8Array|ArrayBuffer} buf
|
||||
* @param {string[]} [categories=All] - Which categories of file to look for
|
||||
* @returns {Object[]} types
|
||||
* @returns {string} type.name - Name of file type
|
||||
@@ -84,6 +84,10 @@ function bytesMatch(sig, buf, offset=0) {
|
||||
* @returns {string} [type.desc] - Description
|
||||
*/
|
||||
export function detectFileType(buf, categories=Object.keys(FILE_SIGNATURES)) {
|
||||
if (buf instanceof ArrayBuffer) {
|
||||
buf = new Uint8Array(buf);
|
||||
}
|
||||
|
||||
if (!(buf && buf.length > 1)) {
|
||||
return [];
|
||||
}
|
||||
@@ -203,7 +207,7 @@ function locatePotentialSig(buf, sig, offset) {
|
||||
* Detects whether the given buffer is a file of the type specified.
|
||||
*
|
||||
* @param {string|RegExp} type
|
||||
* @param {Uint8Array} buf
|
||||
* @param {Uint8Array|ArrayBuffer} buf
|
||||
* @returns {string|false} The mime type or false if the type does not match
|
||||
*/
|
||||
export function isType(type, buf) {
|
||||
@@ -230,7 +234,7 @@ export function isType(type, buf) {
|
||||
/**
|
||||
* Detects whether the given buffer contains an image file.
|
||||
*
|
||||
* @param {Uint8Array} buf
|
||||
* @param {Uint8Array|ArrayBuffer} buf
|
||||
* @returns {string|false} The mime type or false if the type does not match
|
||||
*/
|
||||
export function isImage(buf) {
|
||||
|
||||
@@ -97,6 +97,7 @@ class Magic {
|
||||
|
||||
if (!fileType.length) return null;
|
||||
return {
|
||||
name: fileType[0].name,
|
||||
ext: fileType[0].extension,
|
||||
mime: fileType[0].mime,
|
||||
desc: fileType[0].description
|
||||
|
||||
@@ -121,7 +121,7 @@ class AddTextToImage extends Operation {
|
||||
let xPos = args[3],
|
||||
yPos = args[4];
|
||||
|
||||
if (!isImage(new Uint8Array(input))) {
|
||||
if (!isImage(input)) {
|
||||
throw new OperationError("Invalid file type.");
|
||||
}
|
||||
|
||||
|
||||
107
src/core/operations/BaconCipherDecode.mjs
Normal file
107
src/core/operations/BaconCipherDecode.mjs
Normal file
@@ -0,0 +1,107 @@
|
||||
/**
|
||||
* @author Karsten Silkenbäumer [github.com/kassi]
|
||||
* @copyright Karsten Silkenbäumer 2019
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation";
|
||||
import {
|
||||
BACON_ALPHABETS,
|
||||
BACON_TRANSLATION_CASE, BACON_TRANSLATION_AMNZ, BACON_TRANSLATIONS, BACON_CLEARER_MAP, BACON_NORMALIZE_MAP,
|
||||
swapZeroAndOne
|
||||
} from "../lib/Bacon";
|
||||
|
||||
/**
|
||||
* Bacon Cipher Decode operation
|
||||
*/
|
||||
class BaconCipherDecode extends Operation {
|
||||
/**
|
||||
* BaconCipherDecode constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "Bacon Cipher Decode";
|
||||
this.module = "Default";
|
||||
this.description = "Bacon's cipher or the Baconian cipher is a method of steganography devised by Francis Bacon in 1605. A message is concealed in the presentation of text, rather than its content.";
|
||||
this.infoURL = "https://wikipedia.org/wiki/Bacon%27s_cipher";
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
this.args = [
|
||||
{
|
||||
"name": "Alphabet",
|
||||
"type": "option",
|
||||
"value": Object.keys(BACON_ALPHABETS)
|
||||
},
|
||||
{
|
||||
"name": "Translation",
|
||||
"type": "option",
|
||||
"value": BACON_TRANSLATIONS
|
||||
},
|
||||
{
|
||||
"name": "Invert Translation",
|
||||
"type": "boolean",
|
||||
"value": false
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
const [alphabet, translation, invert] = args;
|
||||
const alphabetObject = BACON_ALPHABETS[alphabet];
|
||||
|
||||
// remove invalid characters
|
||||
input = input.replace(BACON_CLEARER_MAP[translation], "");
|
||||
|
||||
// normalize to unique alphabet
|
||||
if (BACON_NORMALIZE_MAP[translation] !== undefined) {
|
||||
input = input.replace(/./g, function (c) {
|
||||
return BACON_NORMALIZE_MAP[translation][c];
|
||||
});
|
||||
} else if (translation === BACON_TRANSLATION_CASE) {
|
||||
const codeA = "A".charCodeAt(0);
|
||||
const codeZ = "Z".charCodeAt(0);
|
||||
input = input.replace(/./g, function (c) {
|
||||
const code = c.charCodeAt(0);
|
||||
if (code >= codeA && code <= codeZ) {
|
||||
return "1";
|
||||
} else {
|
||||
return "0";
|
||||
}
|
||||
});
|
||||
} else if (translation === BACON_TRANSLATION_AMNZ) {
|
||||
const words = input.split(/\s+/);
|
||||
const letters = words.map(function (e) {
|
||||
if (e) {
|
||||
const code = e[0].toUpperCase().charCodeAt(0);
|
||||
return code >= "N".charCodeAt(0) ? "1" : "0";
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
});
|
||||
input = letters.join("");
|
||||
}
|
||||
|
||||
if (invert) {
|
||||
input = swapZeroAndOne(input);
|
||||
}
|
||||
|
||||
// group into 5
|
||||
const inputArray = input.match(/(.{5})/g) || [];
|
||||
|
||||
let output = "";
|
||||
for (let i = 0; i < inputArray.length; i++) {
|
||||
const code = inputArray[i];
|
||||
const number = parseInt(code, 2);
|
||||
output += number < alphabetObject.alphabet.length ? alphabetObject.alphabet[number] : "?";
|
||||
}
|
||||
return output;
|
||||
}
|
||||
}
|
||||
|
||||
export default BaconCipherDecode;
|
||||
101
src/core/operations/BaconCipherEncode.mjs
Normal file
101
src/core/operations/BaconCipherEncode.mjs
Normal file
@@ -0,0 +1,101 @@
|
||||
/**
|
||||
* @author Karsten Silkenbäumer [github.com/kassi]
|
||||
* @copyright Karsten Silkenbäumer 2019
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation";
|
||||
import {
|
||||
BACON_ALPHABETS,
|
||||
BACON_TRANSLATIONS_FOR_ENCODING, BACON_TRANSLATION_AB,
|
||||
swapZeroAndOne
|
||||
} from "../lib/Bacon";
|
||||
|
||||
/**
|
||||
* Bacon Cipher Encode operation
|
||||
*/
|
||||
class BaconCipherEncode extends Operation {
|
||||
/**
|
||||
* BaconCipherEncode constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "Bacon Cipher Encode";
|
||||
this.module = "Default";
|
||||
this.description = "Bacon's cipher or the Baconian cipher is a method of steganography devised by Francis Bacon in 1605. A message is concealed in the presentation of text, rather than its content.";
|
||||
this.infoURL = "https://wikipedia.org/wiki/Bacon%27s_cipher";
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
this.args = [
|
||||
{
|
||||
"name": "Alphabet",
|
||||
"type": "option",
|
||||
"value": Object.keys(BACON_ALPHABETS)
|
||||
},
|
||||
{
|
||||
"name": "Translation",
|
||||
"type": "option",
|
||||
"value": BACON_TRANSLATIONS_FOR_ENCODING
|
||||
},
|
||||
{
|
||||
"name": "Keep extra characters",
|
||||
"type": "boolean",
|
||||
"value": false
|
||||
},
|
||||
{
|
||||
"name": "Invert Translation",
|
||||
"type": "boolean",
|
||||
"value": false
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
const [alphabet, translation, keep, invert] = args;
|
||||
|
||||
const alphabetObject = BACON_ALPHABETS[alphabet];
|
||||
const charCodeA = "A".charCodeAt(0);
|
||||
const charCodeZ = "Z".charCodeAt(0);
|
||||
|
||||
let output = input.replace(/./g, function (c) {
|
||||
const charCode = c.toUpperCase().charCodeAt(0);
|
||||
if (charCode >= charCodeA && charCode <= charCodeZ) {
|
||||
let code = charCode - charCodeA;
|
||||
if (alphabetObject.codes !== undefined) {
|
||||
code = alphabetObject.codes[code];
|
||||
}
|
||||
const bacon = ("00000" + code.toString(2)).substr(-5, 5);
|
||||
return bacon;
|
||||
} else {
|
||||
return c;
|
||||
}
|
||||
});
|
||||
|
||||
if (invert) {
|
||||
output = swapZeroAndOne(output);
|
||||
}
|
||||
if (!keep) {
|
||||
output = output.replace(/[^01]/g, "");
|
||||
const outputArray = output.match(/(.{5})/g) || [];
|
||||
output = outputArray.join(" ");
|
||||
}
|
||||
if (translation === BACON_TRANSLATION_AB) {
|
||||
output = output.replace(/[01]/g, function (c) {
|
||||
return {
|
||||
"0": "A",
|
||||
"1": "B"
|
||||
}[c];
|
||||
});
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
}
|
||||
|
||||
export default BaconCipherEncode;
|
||||
@@ -53,7 +53,7 @@ class BlurImage extends Operation {
|
||||
async run(input, args) {
|
||||
const [blurAmount, blurType] = args;
|
||||
|
||||
if (!isImage(new Uint8Array(input))) {
|
||||
if (!isImage(input)) {
|
||||
throw new OperationError("Invalid file type.");
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ class Bzip2Decompress extends Operation {
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
async run(input, args) {
|
||||
const [small] = args;
|
||||
if (input.byteLength <= 0) {
|
||||
throw new OperationError("Please provide an input.");
|
||||
|
||||
@@ -107,7 +107,7 @@ class ContainImage extends Operation {
|
||||
"Bottom": jimp.VERTICAL_ALIGN_BOTTOM
|
||||
};
|
||||
|
||||
if (!isImage(new Uint8Array(input))) {
|
||||
if (!isImage(input)) {
|
||||
throw new OperationError("Invalid file type.");
|
||||
}
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ class ConvertDataUnits extends Operation {
|
||||
const DATA_UNITS = [
|
||||
"Bits (b)", "Nibbles", "Octets", "Bytes (B)",
|
||||
"[Binary bits (2^n)]", "Kibibits (Kib)", "Mebibits (Mib)", "Gibibits (Gib)", "Tebibits (Tib)", "Pebibits (Pib)", "Exbibits (Eib)", "Zebibits (Zib)", "Yobibits (Yib)", "[/Binary bits (2^n)]",
|
||||
"[Decimal bits (10^n)]", "Decabits", "Hectobits", "Kilobits (kb)", "Megabits (Mb)", "Gigabits (Gb)", "Terabits (Tb)", "Petabits (Pb)", "Exabits (Eb)", "Zettabits (Zb)", "Yottabits (Yb)", "[/Decimal bits (10^n)]",
|
||||
"[Decimal bits (10^n)]", "Decabits", "Hectobits", "Kilobits (Kb)", "Megabits (Mb)", "Gigabits (Gb)", "Terabits (Tb)", "Petabits (Pb)", "Exabits (Eb)", "Zettabits (Zb)", "Yottabits (Yb)", "[/Decimal bits (10^n)]",
|
||||
"[Binary bytes (8 x 2^n)]", "Kibibytes (KiB)", "Mebibytes (MiB)", "Gibibytes (GiB)", "Tebibytes (TiB)", "Pebibytes (PiB)", "Exbibytes (EiB)", "Zebibytes (ZiB)", "Yobibytes (YiB)", "[/Binary bytes (8 x 2^n)]",
|
||||
"[Decimal bytes (8 x 10^n)]", "Kilobytes (KB)", "Megabytes (MB)", "Gigabytes (GB)", "Terabytes (TB)", "Petabytes (PB)", "Exabytes (EB)", "Zettabytes (ZB)", "Yottabytes (YB)", "[/Decimal bytes (8 x 10^n)]"
|
||||
];
|
||||
|
||||
@@ -93,7 +93,7 @@ class ConvertImageFormat extends Operation {
|
||||
|
||||
const mime = formatMap[format];
|
||||
|
||||
if (!isImage(new Uint8Array(input))) {
|
||||
if (!isImage(input)) {
|
||||
throw new OperationError("Invalid file format.");
|
||||
}
|
||||
let image;
|
||||
|
||||
@@ -102,7 +102,7 @@ class CoverImage extends Operation {
|
||||
"Bottom": jimp.VERTICAL_ALIGN_BOTTOM
|
||||
};
|
||||
|
||||
if (!isImage(new Uint8Array(input))) {
|
||||
if (!isImage(input)) {
|
||||
throw new OperationError("Invalid file type.");
|
||||
}
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@ class CropImage extends Operation {
|
||||
*/
|
||||
async run(input, args) {
|
||||
const [xPos, yPos, width, height, autocrop, autoTolerance, autoFrames, autoSymmetric, autoBorder] = args;
|
||||
if (!isImage(new Uint8Array(input))) {
|
||||
if (!isImage(input)) {
|
||||
throw new OperationError("Invalid file type.");
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,13 @@ import Operation from "../Operation.mjs";
|
||||
import {detectFileType} from "../lib/FileType.mjs";
|
||||
import {FILE_SIGNATURES} from "../lib/FileSignatures.mjs";
|
||||
|
||||
// Concat all supported extensions into a single flat list
|
||||
const exts = [].concat.apply([], Object.keys(FILE_SIGNATURES).map(cat =>
|
||||
[].concat.apply([], FILE_SIGNATURES[cat].map(sig =>
|
||||
sig.extension.split(",")
|
||||
))
|
||||
)).unique().sort().join(", ");
|
||||
|
||||
/**
|
||||
* Detect File Type operation
|
||||
*/
|
||||
@@ -22,11 +29,7 @@ class DetectFileType extends Operation {
|
||||
this.name = "Detect File Type";
|
||||
this.module = "Default";
|
||||
this.description = "Attempts to guess the MIME (Multipurpose Internet Mail Extensions) type of the data based on 'magic bytes'.<br><br>Currently supports the following file types: " +
|
||||
Object.keys(FILE_SIGNATURES).map(cat =>
|
||||
FILE_SIGNATURES[cat].map(sig =>
|
||||
sig.extension.split(",")[0]
|
||||
).join(", ")
|
||||
).join(", ") + ".";
|
||||
exts + ".";
|
||||
this.infoURL = "https://wikipedia.org/wiki/List_of_file_signatures";
|
||||
this.inputType = "ArrayBuffer";
|
||||
this.outputType = "string";
|
||||
|
||||
@@ -38,7 +38,7 @@ class DitherImage extends Operation {
|
||||
* @returns {byteArray}
|
||||
*/
|
||||
async run(input, args) {
|
||||
if (!isImage(new Uint8Array(input))) {
|
||||
if (!isImage(input)) {
|
||||
throw new OperationError("Invalid file type.");
|
||||
}
|
||||
|
||||
|
||||
114
src/core/operations/ExtractLSB.mjs
Normal file
114
src/core/operations/ExtractLSB.mjs
Normal file
@@ -0,0 +1,114 @@
|
||||
/**
|
||||
* @author Ge0rg3 [georgeomnet+cyberchef@gmail.com]
|
||||
* @copyright Crown Copyright 2019
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation.mjs";
|
||||
import OperationError from "../errors/OperationError.mjs";
|
||||
import Utils from "../Utils.mjs";
|
||||
import { fromBinary } from "../lib/Binary.mjs";
|
||||
import { isImage } from "../lib/FileType.mjs";
|
||||
import jimp from "jimp";
|
||||
|
||||
/**
|
||||
* Extract LSB operation
|
||||
*/
|
||||
class ExtractLSB extends Operation {
|
||||
|
||||
/**
|
||||
* ExtractLSB constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "Extract LSB";
|
||||
this.module = "Image";
|
||||
this.description = "Extracts the Least Significant Bit data from each pixel in an image. This is a common way to hide data in Steganography.";
|
||||
this.infoURL = "https://wikipedia.org/wiki/Bit_numbering#Least_significant_bit_in_digital_steganography";
|
||||
this.inputType = "ArrayBuffer";
|
||||
this.outputType = "byteArray";
|
||||
this.args = [
|
||||
{
|
||||
name: "Colour Pattern #1",
|
||||
type: "option",
|
||||
value: COLOUR_OPTIONS,
|
||||
},
|
||||
{
|
||||
name: "Colour Pattern #2",
|
||||
type: "option",
|
||||
value: ["", ...COLOUR_OPTIONS],
|
||||
},
|
||||
{
|
||||
name: "Colour Pattern #3",
|
||||
type: "option",
|
||||
value: ["", ...COLOUR_OPTIONS],
|
||||
},
|
||||
{
|
||||
name: "Colour Pattern #4",
|
||||
type: "option",
|
||||
value: ["", ...COLOUR_OPTIONS],
|
||||
},
|
||||
{
|
||||
name: "Pixel Order",
|
||||
type: "option",
|
||||
value: ["Row", "Column"],
|
||||
},
|
||||
{
|
||||
name: "Bit",
|
||||
type: "number",
|
||||
value: 0
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {ArrayBuffer} input
|
||||
* @param {Object[]} args
|
||||
* @returns {byteArray}
|
||||
*/
|
||||
async run(input, args) {
|
||||
if (!isImage(input)) throw new OperationError("Please enter a valid image file.");
|
||||
|
||||
const bit = 7 - args.pop(),
|
||||
pixelOrder = args.pop(),
|
||||
colours = args.filter(option => option !== "").map(option => COLOUR_OPTIONS.indexOf(option)),
|
||||
parsedImage = await jimp.read(input),
|
||||
width = parsedImage.bitmap.width,
|
||||
height = parsedImage.bitmap.height,
|
||||
rgba = parsedImage.bitmap.data;
|
||||
|
||||
if (bit < 0 || bit > 7) {
|
||||
throw new OperationError("Error: Bit argument must be between 0 and 7");
|
||||
}
|
||||
|
||||
let i, combinedBinary = "";
|
||||
|
||||
if (pixelOrder === "Row") {
|
||||
for (i = 0; i < rgba.length; i += 4) {
|
||||
for (const colour of colours) {
|
||||
combinedBinary += Utils.bin(rgba[i + colour])[bit];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let rowWidth;
|
||||
const pixelWidth = width * 4;
|
||||
for (let col = 0; col < width; col++) {
|
||||
for (let row = 0; row < height; row++) {
|
||||
rowWidth = row * pixelWidth;
|
||||
for (const colour of colours) {
|
||||
i = rowWidth + (col + colour * 4);
|
||||
combinedBinary += Utils.bin(rgba[i])[bit];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return fromBinary(combinedBinary);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const COLOUR_OPTIONS = ["R", "G", "B", "A"];
|
||||
|
||||
export default ExtractLSB;
|
||||
65
src/core/operations/ExtractRGBA.mjs
Normal file
65
src/core/operations/ExtractRGBA.mjs
Normal file
@@ -0,0 +1,65 @@
|
||||
/**
|
||||
* @author Ge0rg3 [georgeomnet+cyberchef@gmail.com]
|
||||
* @copyright Crown Copyright 2019
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation.mjs";
|
||||
import OperationError from "../errors/OperationError.mjs";
|
||||
import { isImage } from "../lib/FileType.mjs";
|
||||
import jimp from "jimp";
|
||||
|
||||
import {RGBA_DELIM_OPTIONS} from "../lib/Delim.mjs";
|
||||
|
||||
/**
|
||||
* Extract RGBA operation
|
||||
*/
|
||||
class ExtractRGBA extends Operation {
|
||||
|
||||
/**
|
||||
* ExtractRGBA constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "Extract RGBA";
|
||||
this.module = "Image";
|
||||
this.description = "Extracts each pixel's RGBA value in an image. These are sometimes used in Steganography to hide text or data.";
|
||||
this.infoURL = "https://wikipedia.org/wiki/RGBA_color_space";
|
||||
this.inputType = "ArrayBuffer";
|
||||
this.outputType = "string";
|
||||
this.args = [
|
||||
{
|
||||
name: "Delimiter",
|
||||
type: "editableOption",
|
||||
value: RGBA_DELIM_OPTIONS
|
||||
},
|
||||
{
|
||||
name: "Include Alpha",
|
||||
type: "boolean",
|
||||
value: true
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {ArrayBuffer} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
async run(input, args) {
|
||||
if (!isImage(input)) throw new OperationError("Please enter a valid image file.");
|
||||
|
||||
const delimiter = args[0],
|
||||
includeAlpha = args[1],
|
||||
parsedImage = await jimp.read(input);
|
||||
|
||||
let bitmap = parsedImage.bitmap.data;
|
||||
bitmap = includeAlpha ? bitmap : bitmap.filter((val, idx) => idx % 4 !== 3);
|
||||
|
||||
return bitmap.join(delimiter);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default ExtractRGBA;
|
||||
@@ -45,7 +45,7 @@ class FlipImage extends Operation {
|
||||
*/
|
||||
async run(input, args) {
|
||||
const [flipAxis] = args;
|
||||
if (!isImage(new Uint8Array(input))) {
|
||||
if (!isImage(input)) {
|
||||
throw new OperationError("Invalid input file type.");
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ class FromQuotedPrintable extends Operation {
|
||||
|
||||
this.name = "From Quoted Printable";
|
||||
this.module = "Default";
|
||||
this.description = "Converts QP-encoded text back to standard text.";
|
||||
this.description = "Converts QP-encoded text back to standard text.<br><br>e.g. The quoted-printable encoded string <code>hello=20world</code> becomes <code>hello world</code>";
|
||||
this.infoURL = "https://wikipedia.org/wiki/Quoted-printable";
|
||||
this.inputType = "string";
|
||||
this.outputType = "byteArray";
|
||||
|
||||
@@ -58,7 +58,7 @@ class GeneratePGPKeyPair extends Operation {
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
async run(input, args) {
|
||||
const [keyType, keySize] = args[0].split("-"),
|
||||
password = args[1],
|
||||
name = args[2],
|
||||
|
||||
@@ -54,7 +54,7 @@ class ImageBrightnessContrast extends Operation {
|
||||
*/
|
||||
async run(input, args) {
|
||||
const [brightness, contrast] = args;
|
||||
if (!isImage(new Uint8Array(input))) {
|
||||
if (!isImage(input)) {
|
||||
throw new OperationError("Invalid file type.");
|
||||
}
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ class ImageFilter extends Operation {
|
||||
*/
|
||||
async run(input, args) {
|
||||
const [filterType] = args;
|
||||
if (!isImage(new Uint8Array(input))) {
|
||||
if (!isImage(input)) {
|
||||
throw new OperationError("Invalid file type.");
|
||||
}
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ class ImageHueSaturationLightness extends Operation {
|
||||
async run(input, args) {
|
||||
const [hue, saturation, lightness] = args;
|
||||
|
||||
if (!isImage(new Uint8Array(input))) {
|
||||
if (!isImage(input)) {
|
||||
throw new OperationError("Invalid file type.");
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ class ImageOpacity extends Operation {
|
||||
*/
|
||||
async run(input, args) {
|
||||
const [opacity] = args;
|
||||
if (!isImage(new Uint8Array(input))) {
|
||||
if (!isImage(input)) {
|
||||
throw new OperationError("Invalid file type.");
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ class InvertImage extends Operation {
|
||||
* @returns {byteArray}
|
||||
*/
|
||||
async run(input, args) {
|
||||
if (!isImage(new Uint8Array(input))) {
|
||||
if (!isImage(input)) {
|
||||
throw new OperationError("Invalid input file format.");
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ class NormaliseImage extends Operation {
|
||||
* @returns {byteArray}
|
||||
*/
|
||||
async run(input, args) {
|
||||
if (!isImage(new Uint8Array(input))) {
|
||||
if (!isImage(input)) {
|
||||
throw new OperationError("Invalid file type.");
|
||||
}
|
||||
|
||||
|
||||
87
src/core/operations/OpticalCharacterRecognition.mjs
Normal file
87
src/core/operations/OpticalCharacterRecognition.mjs
Normal file
@@ -0,0 +1,87 @@
|
||||
/**
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
* @author mshwed [m@ttshwed.com]
|
||||
* @copyright Crown Copyright 2019
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation.mjs";
|
||||
import OperationError from "../errors/OperationError.mjs";
|
||||
import { isImage } from "../lib/FileType.mjs";
|
||||
import { toBase64 } from "../lib/Base64.mjs";
|
||||
import { isWorkerEnvironment } from "../Utils.mjs";
|
||||
|
||||
import Tesseract from "tesseract.js";
|
||||
const { TesseractWorker } = Tesseract;
|
||||
|
||||
import process from "process";
|
||||
|
||||
/**
|
||||
* Optical Character Recognition operation
|
||||
*/
|
||||
class OpticalCharacterRecognition extends Operation {
|
||||
|
||||
/**
|
||||
* OpticalCharacterRecognition constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "Optical Character Recognition";
|
||||
this.module = "OCR";
|
||||
this.description = "Optical character recognition or optical character reader (OCR) is the mechanical or electronic conversion of images of typed, handwritten or printed text into machine-encoded text.<br><br>Supported image formats: png, jpg, bmp, pbm.";
|
||||
this.infoURL = "https://wikipedia.org/wiki/Optical_character_recognition";
|
||||
this.inputType = "ArrayBuffer";
|
||||
this.outputType = "string";
|
||||
this.args = [
|
||||
{
|
||||
name: "Show confidence",
|
||||
type: "boolean",
|
||||
value: true
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {ArrayBuffer} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
async run(input, args) {
|
||||
const [showConfidence] = args;
|
||||
|
||||
if (!isWorkerEnvironment()) throw OperationError("This operation only works in a browser");
|
||||
|
||||
const type = isImage(input);
|
||||
if (!type) {
|
||||
throw new OperationError("Invalid File Type");
|
||||
}
|
||||
|
||||
const assetDir = isWorkerEnvironment() ? `${self.docURL}/assets/` : `${process.cwd()}/src/core/vendor/`;
|
||||
|
||||
try {
|
||||
const image = `data:${type};base64,${toBase64(input)}`;
|
||||
const worker = new TesseractWorker({
|
||||
workerPath: `${assetDir}tesseract/worker.min.js`,
|
||||
langPath: `${assetDir}tesseract/lang-data`,
|
||||
corePath: `${assetDir}tesseract/tesseract-core.wasm.js`,
|
||||
});
|
||||
const result = await worker.recognize(image)
|
||||
.progress(progress => {
|
||||
if (isWorkerEnvironment()) {
|
||||
self.sendStatusMessage(`Status: ${progress.status} - ${(parseFloat(progress.progress)*100).toFixed(2)}%`);
|
||||
}
|
||||
});
|
||||
|
||||
if (showConfidence) {
|
||||
return `Confidence: ${result.confidence}%\n\n${result.text}`;
|
||||
} else {
|
||||
return result.text;
|
||||
}
|
||||
} catch (err) {
|
||||
throw new OperationError(`Error performing OCR on image. (${err})`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default OpticalCharacterRecognition;
|
||||
@@ -51,7 +51,7 @@ class ParseQRCode extends Operation {
|
||||
async run(input, args) {
|
||||
const [normalise] = args;
|
||||
|
||||
if (!isImage(new Uint8Array(input))) {
|
||||
if (!isImage(input)) {
|
||||
throw new OperationError("Invalid file type.");
|
||||
}
|
||||
return await parseQrCode(input, normalise);
|
||||
|
||||
83
src/core/operations/RandomizeColourPalette.mjs
Normal file
83
src/core/operations/RandomizeColourPalette.mjs
Normal file
@@ -0,0 +1,83 @@
|
||||
/**
|
||||
* @author Ge0rg3 [georgeomnet+cyberchef@gmail.com]
|
||||
* @copyright Crown Copyright 2019
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation.mjs";
|
||||
import OperationError from "../errors/OperationError.mjs";
|
||||
import Utils from "../Utils.mjs";
|
||||
import { isImage } from "../lib/FileType.mjs";
|
||||
import { runHash } from "../lib/Hash.mjs";
|
||||
import { toBase64 } from "../lib/Base64.mjs";
|
||||
import jimp from "jimp";
|
||||
|
||||
/**
|
||||
* Randomize Colour Palette operation
|
||||
*/
|
||||
class RandomizeColourPalette extends Operation {
|
||||
|
||||
/**
|
||||
* RandomizeColourPalette constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "Randomize Colour Palette";
|
||||
this.module = "Image";
|
||||
this.description = "Randomizes each colour in an image's colour palette. This can often reveal text or symbols that were previously a very similar colour to their surroundings, a technique sometimes used in Steganography.";
|
||||
this.infoURL = "https://wikipedia.org/wiki/Indexed_color";
|
||||
this.inputType = "ArrayBuffer";
|
||||
this.outputType = "ArrayBuffer";
|
||||
this.presentType = "html";
|
||||
this.args = [
|
||||
{
|
||||
name: "Seed",
|
||||
type: "string",
|
||||
value: ""
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {ArrayBuffer} input
|
||||
* @param {Object[]} args
|
||||
* @returns {ArrayBuffer}
|
||||
*/
|
||||
async run(input, args) {
|
||||
if (!isImage(input)) throw new OperationError("Please enter a valid image file.");
|
||||
|
||||
const seed = args[0] || (Math.random().toString().substr(2)),
|
||||
parsedImage = await jimp.read(input),
|
||||
width = parsedImage.bitmap.width,
|
||||
height = parsedImage.bitmap.height;
|
||||
|
||||
let rgbString, rgbHash, rgbHex;
|
||||
|
||||
parsedImage.scan(0, 0, width, height, function(x, y, idx) {
|
||||
rgbString = this.bitmap.data.slice(idx, idx+3).join(".");
|
||||
rgbHash = runHash("md5", Utils.strToArrayBuffer(seed + rgbString));
|
||||
rgbHex = rgbHash.substr(0, 6) + "ff";
|
||||
parsedImage.setPixelColor(parseInt(rgbHex, 16), x, y);
|
||||
});
|
||||
|
||||
const imageBuffer = await parsedImage.getBufferAsync(jimp.AUTO);
|
||||
|
||||
return new Uint8Array(imageBuffer).buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the extracted data as an image for web apps.
|
||||
* @param {ArrayBuffer} data
|
||||
* @returns {html}
|
||||
*/
|
||||
present(data) {
|
||||
if (!data.byteLength) return "";
|
||||
const type = isImage(data);
|
||||
|
||||
return `<img src="data:${type};base64,${toBase64(data)}">`;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default RandomizeColourPalette;
|
||||
@@ -87,7 +87,7 @@ class ResizeImage extends Operation {
|
||||
"Bezier": jimp.RESIZE_BEZIER
|
||||
};
|
||||
|
||||
if (!isImage(new Uint8Array(input))) {
|
||||
if (!isImage(input)) {
|
||||
throw new OperationError("Invalid file type.");
|
||||
}
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ class RotateImage extends Operation {
|
||||
async run(input, args) {
|
||||
const [degrees] = args;
|
||||
|
||||
if (!isImage(new Uint8Array(input))) {
|
||||
if (!isImage(input)) {
|
||||
throw new OperationError("Invalid file type.");
|
||||
}
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ class SharpenImage extends Operation {
|
||||
async run(input, args) {
|
||||
const [radius, amount, threshold] = args;
|
||||
|
||||
if (!isImage(new Uint8Array(input))) {
|
||||
if (!isImage(input)) {
|
||||
throw new OperationError("Invalid file type.");
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ class ToBase64 extends Operation {
|
||||
*/
|
||||
run(input, args) {
|
||||
const alphabet = args[0];
|
||||
return toBase64(new Uint8Array(input), alphabet);
|
||||
return toBase64(input, alphabet);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
107
src/core/operations/ViewBitPlane.mjs
Normal file
107
src/core/operations/ViewBitPlane.mjs
Normal file
@@ -0,0 +1,107 @@
|
||||
/**
|
||||
* @author Ge0rg3 [georgeomnet+cyberchef@gmail.com]
|
||||
* @copyright Crown Copyright 2019
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation.mjs";
|
||||
import OperationError from "../errors/OperationError.mjs";
|
||||
import Utils from "../Utils.mjs";
|
||||
import { isImage } from "../lib/FileType.mjs";
|
||||
import { toBase64 } from "../lib/Base64.mjs";
|
||||
import jimp from "jimp";
|
||||
|
||||
/**
|
||||
* View Bit Plane operation
|
||||
*/
|
||||
class ViewBitPlane extends Operation {
|
||||
|
||||
/**
|
||||
* ViewBitPlane constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "View Bit Plane";
|
||||
this.module = "Image";
|
||||
this.description = "Extracts and displays a bit plane of any given image. These show only a single bit from each pixel, and can be used to hide messages in Steganography.";
|
||||
this.infoURL = "https://wikipedia.org/wiki/Bit_plane";
|
||||
this.inputType = "ArrayBuffer";
|
||||
this.outputType = "ArrayBuffer";
|
||||
this.presentType = "html";
|
||||
this.args = [
|
||||
{
|
||||
name: "Colour",
|
||||
type: "option",
|
||||
value: COLOUR_OPTIONS
|
||||
},
|
||||
{
|
||||
name: "Bit",
|
||||
type: "number",
|
||||
value: 0
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {ArrayBuffer} input
|
||||
* @param {Object[]} args
|
||||
* @returns {ArrayBuffer}
|
||||
*/
|
||||
async run(input, args) {
|
||||
if (!isImage(input)) throw new OperationError("Please enter a valid image file.");
|
||||
|
||||
const [colour, bit] = args,
|
||||
parsedImage = await jimp.read(input),
|
||||
width = parsedImage.bitmap.width,
|
||||
height = parsedImage.bitmap.height,
|
||||
colourIndex = COLOUR_OPTIONS.indexOf(colour),
|
||||
bitIndex = 7-bit;
|
||||
|
||||
if (bit < 0 || bit > 7) {
|
||||
throw new OperationError("Error: Bit argument must be between 0 and 7");
|
||||
}
|
||||
|
||||
let pixel, bin, newPixelValue;
|
||||
|
||||
parsedImage.scan(0, 0, width, height, function(x, y, idx) {
|
||||
pixel = this.bitmap.data[idx + colourIndex];
|
||||
bin = Utils.bin(pixel);
|
||||
newPixelValue = 255;
|
||||
|
||||
if (bin.charAt(bitIndex) === "1") newPixelValue = 0;
|
||||
|
||||
for (let i=0; i < 3; i++) {
|
||||
this.bitmap.data[idx + i] = newPixelValue;
|
||||
}
|
||||
this.bitmap.data[idx + 3] = 255;
|
||||
|
||||
});
|
||||
|
||||
const imageBuffer = await parsedImage.getBufferAsync(jimp.AUTO);
|
||||
|
||||
return new Uint8Array(imageBuffer).buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the extracted data as an image for web apps.
|
||||
* @param {ArrayBuffer} data
|
||||
* @returns {html}
|
||||
*/
|
||||
present(data) {
|
||||
if (!data.length) return "";
|
||||
const type = isImage(data);
|
||||
|
||||
return `<img src="data:${type};base64,${toBase64(data)}">`;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const COLOUR_OPTIONS = [
|
||||
"Red",
|
||||
"Green",
|
||||
"Blue",
|
||||
"Alpha"
|
||||
];
|
||||
|
||||
export default ViewBitPlane;
|
||||
BIN
src/core/vendor/tesseract/lang-data/eng.traineddata.gz
vendored
Normal file
BIN
src/core/vendor/tesseract/lang-data/eng.traineddata.gz
vendored
Normal file
Binary file not shown.
24
src/core/vendor/tesseract/tesseract-core.wasm.js
vendored
Normal file
24
src/core/vendor/tesseract/tesseract-core.wasm.js
vendored
Normal file
File diff suppressed because one or more lines are too long
17
src/core/vendor/tesseract/worker.min.js
vendored
Normal file
17
src/core/vendor/tesseract/worker.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -43,11 +43,13 @@ class NodeRecipe {
|
||||
} else {
|
||||
throw new TypeError("Inputted function not a Chef operation.");
|
||||
}
|
||||
// CASE: op with configuration
|
||||
} else if (ing.op && ing.args) {
|
||||
// Return op and args pair for opList item.
|
||||
// CASE: op, maybe with configuration
|
||||
} else if (ing.op) {
|
||||
const sanitisedOp = this._validateIngredient(ing.op);
|
||||
return {op: sanitisedOp, args: ing.args};
|
||||
if (ing.args) {
|
||||
return {op: sanitisedOp, args: ing.args};
|
||||
}
|
||||
return sanitisedOp;
|
||||
} else {
|
||||
throw new TypeError("Recipe can only contain function names or functions");
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@ let code = `/**
|
||||
import NodeDish from "./NodeDish.mjs";
|
||||
import { _wrap, help, bake, _explainExludedFunction } from "./api.mjs";
|
||||
import File from "./File.mjs";
|
||||
import { OperationError, DishError, ExcludedOperationError } from "../core/errors/index";
|
||||
import {
|
||||
// import as core_ to avoid name clashes after wrap.
|
||||
`;
|
||||
@@ -115,6 +116,9 @@ Object.keys(operations).forEach((op) => {
|
||||
code += " NodeDish as Dish,\n";
|
||||
code += " prebaked as bake,\n";
|
||||
code += " help,\n";
|
||||
code += " OperationError,\n";
|
||||
code += " ExcludedOperationError,\n";
|
||||
code += " DishError,\n";
|
||||
code += "};\n";
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import sm from "sitemap";
|
||||
import Sitemap from "sitemap";
|
||||
import OperationConfig from "../../core/config/OperationConfig.json";
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ import OperationConfig from "../../core/config/OperationConfig.json";
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
const sitemap = sm.createSitemap({
|
||||
const sitemap = Sitemap.createSitemap({
|
||||
hostname: "https://gchq.github.io/CyberChef",
|
||||
});
|
||||
|
||||
@@ -1046,15 +1046,25 @@ class OutputWaiter {
|
||||
* @param {Object[]} options
|
||||
*/
|
||||
backgroundMagicResult(options) {
|
||||
if (!options.length ||
|
||||
!options[0].recipe.length)
|
||||
return;
|
||||
if (!options.length) return;
|
||||
|
||||
const currentRecipeConfig = this.app.getRecipeConfig();
|
||||
const newRecipeConfig = currentRecipeConfig.concat(options[0].recipe);
|
||||
const opSequence = options[0].recipe.map(o => o.op).join(", ");
|
||||
let msg = "",
|
||||
newRecipeConfig;
|
||||
|
||||
this.showMagicButton(opSequence, options[0].data, newRecipeConfig);
|
||||
if (options[0].recipe.length) {
|
||||
const opSequence = options[0].recipe.map(o => o.op).join(", ");
|
||||
newRecipeConfig = currentRecipeConfig.concat(options[0].recipe);
|
||||
msg = `<i>${opSequence}</i> will produce <span class="data-text">"${Utils.escapeHtml(Utils.truncate(options[0].data), 30)}"</span>`;
|
||||
} else if (options[0].fileType && options[0].fileType.name) {
|
||||
const ft = options[0].fileType;
|
||||
newRecipeConfig = currentRecipeConfig.concat([{op: "Detect File Type", args: []}]);
|
||||
msg = `<i>${ft.name}</i> file detected`;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
this.showMagicButton(msg, newRecipeConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1072,15 +1082,14 @@ class OutputWaiter {
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the Magic button with a title and adds a link to a complete recipe.
|
||||
* Displays the Magic button with a title and adds a link to a recipe.
|
||||
*
|
||||
* @param {string} opSequence
|
||||
* @param {string} result
|
||||
* @param {string} msg
|
||||
* @param {Object[]} recipeConfig
|
||||
*/
|
||||
showMagicButton(opSequence, result, recipeConfig) {
|
||||
showMagicButton(msg, recipeConfig) {
|
||||
const magicButton = document.getElementById("magic");
|
||||
magicButton.setAttribute("data-original-title", `<i>${opSequence}</i> will produce <span class="data-text">"${Utils.escapeHtml(Utils.truncate(result), 30)}"</span>`);
|
||||
magicButton.setAttribute("data-original-title", msg);
|
||||
magicButton.setAttribute("data-recipe", JSON.stringify(recipeConfig), null, "");
|
||||
magicButton.classList.remove("hidden");
|
||||
magicButton.classList.add("pulse");
|
||||
|
||||
@@ -104,8 +104,6 @@ class TestRegister {
|
||||
* Run all api related tests and wrap results in report format
|
||||
*/
|
||||
runApiTests() {
|
||||
console.log("Running tests...");
|
||||
|
||||
return Promise.all(this.apiTests.map(async function(test, i) {
|
||||
const result = {
|
||||
test: test,
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
/**
|
||||
* Print useful stack on error
|
||||
*/
|
||||
const wrapRun = (run) => () => {
|
||||
const wrapRun = (run) => async () => {
|
||||
try {
|
||||
run();
|
||||
await run();
|
||||
} catch (e) {
|
||||
console.dir(e);
|
||||
throw e;
|
||||
|
||||
@@ -13,13 +13,14 @@
|
||||
import {
|
||||
setLongTestFailure,
|
||||
logTestReport,
|
||||
} from "../lib/utils";
|
||||
} from "../lib/utils.mjs";
|
||||
|
||||
import TestRegister from "../lib/TestRegister.mjs";
|
||||
import "./tests/nodeApi";
|
||||
import "./tests/operations";
|
||||
import "./tests/File";
|
||||
import "./tests/NodeDish";
|
||||
import "./tests/nodeApi.mjs";
|
||||
import "./tests/operations.mjs";
|
||||
import "./tests/File.mjs";
|
||||
import "./tests/Dish.mjs";
|
||||
import "./tests/NodeDish.mjs";
|
||||
|
||||
const testStatus = {
|
||||
allTestsPassing: true,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import TestRegister from "../../lib/TestRegister.mjs";
|
||||
import Dish from "../../src/core/Dish.mjs";
|
||||
import it from "../node/assertionHandler.mjs";
|
||||
import Dish from "../../../src/core/Dish.mjs";
|
||||
import it from "../../node/assertionHandler.mjs";
|
||||
import assert from "assert";
|
||||
|
||||
TestRegister.addApiTests([
|
||||
@@ -259,6 +259,13 @@ TestRegister.addApiTests([
|
||||
assert.strictEqual(result.toString(), "73:6f:6d:65:20:69:6e:70:75:74");
|
||||
}),
|
||||
|
||||
it("chef.bake: should take single JSON object desribing op with optional args", () => {
|
||||
const result = chef.bake("some input", {
|
||||
op: chef.toHex,
|
||||
});
|
||||
assert.strictEqual(result.toString(), "73 6f 6d 65 20 69 6e 70 75 74");
|
||||
}),
|
||||
|
||||
it("chef.bake: should take single JSON object describing op and args ARRAY", () => {
|
||||
const result = chef.bake("some input", {
|
||||
op: chef.toHex,
|
||||
@@ -295,6 +302,21 @@ TestRegister.addApiTests([
|
||||
assert.strictEqual(result.toString(), "67;63;72;66;146;72;66;144;72;66;65;72;62;60;72;66;71;72;66;145;72;67;60;72;67;65;72;67;64");
|
||||
}),
|
||||
|
||||
it("chef.bake: should take multiple ops in JSON object form, some without args", () => {
|
||||
const result = chef.bake("some input", [
|
||||
{
|
||||
op: chef.toHex,
|
||||
},
|
||||
{
|
||||
op: "to octal",
|
||||
args: {
|
||||
delimiter: "Semi-colon",
|
||||
}
|
||||
}
|
||||
]);
|
||||
assert.strictEqual(result.toString(), "67;63;40;66;146;40;66;144;40;66;65;40;62;60;40;66;71;40;66;145;40;67;60;40;67;65;40;67;64");
|
||||
}),
|
||||
|
||||
it("chef.bake: should handle op with multiple args", () => {
|
||||
const result = chef.bake("some input", {
|
||||
op: "to morse code",
|
||||
@@ -324,6 +346,17 @@ TestRegister.addApiTests([
|
||||
assert.strictEqual(result.toString(), "begin_something_anananaaaaak_da_aaak_da_aaaaananaaaaaaan_da_aaaaaaanan_da_aaak_end_something");
|
||||
}),
|
||||
|
||||
it("chef.bake: should accept Clean JSON format from Chef website - args optional", () => {
|
||||
const result = chef.bake("some input", [
|
||||
{ "op": "To Morse Code" },
|
||||
{ "op": "Hex to PEM",
|
||||
"args": ["SOMETHING"] },
|
||||
{ "op": "To Snake case",
|
||||
"args": [false] }
|
||||
]);
|
||||
assert.strictEqual(result.toString(), "begin_something_aaaaaaaaaaaaaa_end_something");
|
||||
}),
|
||||
|
||||
it("Excluded operations: throw a sensible error when you try and call one", () => {
|
||||
try {
|
||||
chef.fork();
|
||||
|
||||
@@ -70,13 +70,13 @@ TestRegister.addApiTests([
|
||||
}),
|
||||
|
||||
it("AES decrypt: toggleString and option", () => {
|
||||
const result = AESDecrypt("812c34ae6af353244a63c6ce23b7c34286b60be28ea4645523d4494700e7", {
|
||||
const result = AESDecrypt("4a123af235a507bbc9d5871721d61b98504d569a9a5a7847e2d78315fec7", {
|
||||
key: {
|
||||
string: "some longer key1",
|
||||
option: "utf8",
|
||||
},
|
||||
iv: {
|
||||
string: "some iv",
|
||||
string: "some iv some iv1",
|
||||
option: "utf8",
|
||||
},
|
||||
mode: "OFB",
|
||||
@@ -130,11 +130,14 @@ Tiger-128`;
|
||||
it("atBash Cipher", () => {
|
||||
const result = chef.atbashCipher("Happy as a Clam");
|
||||
assert.strictEqual(result.toString(), "Szkkb zh z Xozn");
|
||||
|
||||
}),
|
||||
|
||||
it("Bcrypt", async () => {
|
||||
const result = await chef.bcrypt("Put a Sock In It");
|
||||
assert.strictEqual(result.toString(), "$2a$10$ODeP1.6fMsb.ENk2ngPUCO7qTGVPyHA9TqDVcyupyed8FjsiF65L6");
|
||||
const strResult = result.toString();
|
||||
assert.equal(strResult.length, 60);
|
||||
assert.equal(strResult.slice(0, 7), "$2a$10$");
|
||||
}),
|
||||
|
||||
it("bcryptCompare", async() => {
|
||||
@@ -583,47 +586,7 @@ Password: 034148`;
|
||||
const result = await chef.generatePGPKeyPair("Back To the Drawing Board", {
|
||||
keyType: "ECC-256",
|
||||
});
|
||||
const expected = `-----BEGIN PGP PRIVATE KEY BLOCK-----
|
||||
Version: Keybase OpenPGP v2.0.77
|
||||
Comment: https://keybase.io/crypto
|
||||
|
||||
xYgEW3KciQEBAK96Lx9G0WZiw1yhC35IogdumoxEJXsLdAVIjmskXeAfABEBAAEA
|
||||
AP4wK+OZu3AqojwtRoyIK1pHKU93OAuam1iaLCOGCwCckQCA5PjU0aLNZqy/eKyX
|
||||
T3rpKQCAxDDT5hHGAUfFPUu73KWABwB/WKpeUp7KwurMSbYVhgr1TijszQDCVAQT
|
||||
AQoAHgUCW3KciQIbLwMLCQcDFQoIAh4BAheAAxYCAQIZAQAKCRD0VeyUMgmpz3OE
|
||||
AP9qsnhhoK85Tnu6VKwKm1iMiJAssDQnFztDaMmmVdrN/MeIBFtynIkBAQDDhjIw
|
||||
fxOprqVMYLk6aC45JyPAA2POzu0Zb/rx0tKeBwARAQABAAD/XAr66oiP9ZORHiT0
|
||||
XZH4m7vwZt7AHuq4pYtVlMQXk60AgPw2Mno/wStvE/SBa9R7AtsAgMZ2BkJjvNPZ
|
||||
9YA6cl4lW0UAgI1+kJVLZ5VR9fPENfJR80EtncKDBBgBCgAPBQJbcpyJBQkPCZwA
|
||||
AhsuAEgJEPRV7JQyCanPPSAEGQEKAAYFAltynIkACgkQrewgWMQZ/b2blwD/dbwh
|
||||
/3F9xv+YGAwq8i1mzzswg4qBct6LoSIjGglULT9RIQD/cYd31YfKrEnbSBWD5PLi
|
||||
zcSsxtBGKphwXiPAlQJ1Q5DHiARbcpyJAQEAs8V418lf1T74PpAwdBTiViEUX9jB
|
||||
e+ZrAEVaq5nu1C8AEQEAAQAA/iPWhS23hnRTllealR4/H5OofZRwxvIQrxAJp6z1
|
||||
ICRxAIDayRpCAbK5EC3DzRU2z4VpAIDSWYSs9inI1VTfamJPMWHXAIC3aaukzCP4
|
||||
GEGeFobX/thnKhnCgwQYAQoADwUCW3KciQUJA8JnAAIbLgBICRD0VeyUMgmpzz0g
|
||||
BBkBCgAGBQJbcpyJAAoJEB4jzL1hmQIXamUA/0c1M6BSqVtxNowPcOAXKYIxMca1
|
||||
VFcRWolHnZqdZQ7k/J8A/3HvNLRS3p1HvjQEfXl/qKoRRn843Py09ptDHh+xpGKh
|
||||
=d+Vp
|
||||
-----END PGP PRIVATE KEY BLOCK-----
|
||||
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
Version: Keybase OpenPGP v2.0.77
|
||||
Comment: https://keybase.io/crypto
|
||||
|
||||
xi0EW3KciQEBAK96Lx9G0WZiw1yhC35IogdumoxEJXsLdAVIjmskXeAfABEBAAHN
|
||||
AMJUBBMBCgAeBQJbcpyJAhsvAwsJBwMVCggCHgECF4ADFgIBAhkBAAoJEPRV7JQy
|
||||
CanPc4QA/2qyeGGgrzlOe7pUrAqbWIyIkCywNCcXO0NoyaZV2s38zi0EW3KciQEB
|
||||
AMOGMjB/E6mupUxguTpoLjknI8ADY87O7Rlv+vHS0p4HABEBAAHCgwQYAQoADwUC
|
||||
W3KciQUJDwmcAAIbLgBICRD0VeyUMgmpzz0gBBkBCgAGBQJbcpyJAAoJEK3sIFjE
|
||||
Gf29m5cA/3W8If9xfcb/mBgMKvItZs87MIOKgXLei6EiIxoJVC0/USEA/3GHd9WH
|
||||
yqxJ20gVg+Ty4s3ErMbQRiqYcF4jwJUCdUOQzi0EW3KciQEBALPFeNfJX9U++D6Q
|
||||
MHQU4lYhFF/YwXvmawBFWquZ7tQvABEBAAHCgwQYAQoADwUCW3KciQUJA8JnAAIb
|
||||
LgBICRD0VeyUMgmpzz0gBBkBCgAGBQJbcpyJAAoJEB4jzL1hmQIXamUA/0c1M6BS
|
||||
qVtxNowPcOAXKYIxMca1VFcRWolHnZqdZQ7k/J8A/3HvNLRS3p1HvjQEfXl/qKoR
|
||||
Rn843Py09ptDHh+xpGKh
|
||||
=ySwG
|
||||
-----END PGP PUBLIC KEY BLOCK-----`;
|
||||
assert.strictEqual(result.toString(), expected);
|
||||
assert.strictEqual(result.toString().length, 2005);
|
||||
}),
|
||||
|
||||
it("Generate UUID", () => {
|
||||
@@ -737,43 +700,105 @@ CPU
|
||||
assert.strictEqual(result.toString(), expected);
|
||||
}),
|
||||
|
||||
it("PGP Encrypt", async () => {
|
||||
it("PGP Encrypt and decrypt", async () => {
|
||||
const pbkey = `-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
Version: GnuPG v1
|
||||
|
||||
mI0EVWOihAEEALzwFAVWTrD0KiWCH5tX6q6QsGjlRn4IP2uj/xWsJZDNbCKm+JAe
|
||||
1RvIootpW1+PNNMJlIInwUgtCjtJ9gZbGBpXeqwdSn0oYuj9X86ekXOUnZsRoPCj
|
||||
RwS8kpbrvRVfhWN8hYuXFcXK2J2Ld0ZpVyJzkncpFdpAgzTPMfrO1HS5ABEBAAG0
|
||||
GmdwZyBuYW1lIChjb21tZW50KSA8ZW1AaWw+iLgEEwECACIFAlVjooQCGwMGCwkI
|
||||
BwMCBhUIAgkKCwQWAgMBAh4BAheAAAoJEBg8dTRwi4g5I40D/2+uUuQxa3uMrAeI
|
||||
dXLaJWz3V0cl1rotfBP47apDUGbkm1HVgULJUo8Bo15Ii83ST8TUsyja3XcLutHb
|
||||
IwYSWo41gEV48+NKoN6Oy3HwqBoHfH06bu0If75vdSjnZpB2dO/Ph7L9kz78gc4y
|
||||
tZx4bE64MTlL2AYghZxyYpFyydjXuI0EVWOihAEEANE4UU+4iB2hMAXq93hiBzIh
|
||||
AMtn/DlWbJkpdUgrjKOG6tILs28mrw9rI4PivmT7grkyNW8sa3ATsmWC1xChxGTN
|
||||
T1guyh0Hhbc3Otfng2BFSWcBkPwUoNaOdrVFpP9J51IYrsQHsjbZlY45ghDBzM6t
|
||||
sISfkmmFCsp0l7w/XAcvABEBAAGInwQYAQIACQUCVWOihAIbDAAKCRAYPHU0cIuI
|
||||
OQ2BA/9KWqOhXZW75ac7CuJMfileZR7vRy9CkKyNG21cZtAlqftAX+m8FGdG0duU
|
||||
jKHiPvjXhSfP3lmrQ7brja9LgSzkiBqQzvPW55G67nGQdUC+mqZNJNlRh+8atf9I
|
||||
5nxg2i8zn6F5cLaNWz7cl27m1/mXKcH3gult1PLR4PiYLiC9aw==
|
||||
=xw3e
|
||||
-----END PGP PUBLIC KEY BLOCK-----`;
|
||||
|
||||
const result = await chef.PGPEncrypt("A Fool and His Money are Soon Parted", {
|
||||
publicKeyOfRecipient: pbkey,
|
||||
});
|
||||
const expected = `-----BEGIN PGP MESSAGE-----
|
||||
Version: Keybase OpenPGP v2.0.77
|
||||
Version: Keybase OpenPGP v2.1.3
|
||||
Comment: https://keybase.io/crypto
|
||||
|
||||
wYwDv1kIXPPNwmABA/4syW+oO+S/mfpjdp83/MZJiKh6XNQoPr/N5/1Is/QXYu9V
|
||||
/v8/b+eReOpUVC6cVrJ8U5cB19y1Az3NQWHXLEC0jND2wL3cUM4sv87hlvv2PLhc
|
||||
okv8OHNCitRiweo7NZHVygHGdFvY082G47e1PkyPAuVynvzdD450ta/s/KOxZdJg
|
||||
ARbZIrC6WmjYNLwhbpRYawKD+3N4I5qliRpU2POKRi9UROAW9dth6egy60TTCvyO
|
||||
jmPGsv1elXxVzqs58UZLD2c3vBhGkU2BV6kRKh+lj/EcVrzsFhGCz/7DKxPoDHLS
|
||||
=IBYt
|
||||
-----END PGP MESSAGE-----
|
||||
`;
|
||||
assert.strictEqual(result.toString(), expected);
|
||||
xo0EXZtlowEEAKUqTFownTmqgXWu2KDrtyNYtFck7a16WM5QD95bFoAFFdnlwZ45
|
||||
6Vw8G8LCzHdyRXYp/JF1GknDrAd7nIRE+SuSz2yVK5nlOCfO1HFcg2Ov7e7/pBwd
|
||||
qawx9GUIsCKd/6NxwDuT4YqarLFsuwljRC/eQiibO+ejnhoiKcU69sTNABEBAAHN
|
||||
AMK0BBMBCgAeBQJdm2WjAhsvAwsJBwMVCggCHgECF4ADFgIBAhkBAAoJEGS79V2S
|
||||
7D0owtMD/RT+o4BQJ8NSQBDgkYf42uOOu1Ud6GuN89nX6n20yAZbmqQ8CHnHY+Qc
|
||||
l6ft4HnbIaNrI3arp/C2C+cwFypmt1BKyFEJUXO7ft3i/IxnjpCorDyAMCDckDvq
|
||||
uma1LWtUHLb5s/ZuGMSHnhuji74IRWuIofNPdf7bCZW1GMbW9jNUzo0EXZtlowEE
|
||||
AL38zaNkPmUVQaowP696fayBo18Nxs0yOzC4+0TYv1B/k5aUb0Air2h+o/Xw4E42
|
||||
Jh9gVdPSvhOAEqdV0UDe71wxa4cfAVMDY9v8ta81MWunChj3ISUk1oIQylTJNsY/
|
||||
b4KWOrLaOtBD9dyFGCzss5vLVdqdMjVIW2Cz0hb6IYG7ABEBAAHCwIMEGAEKAA8F
|
||||
Al2bZaMFCQ8JnAACGy4AqAkQZLv1XZLsPSidIAQZAQoABgUCXZtlowAKCRA16MU2
|
||||
u2hFTX+JBACZ27xk0Afny2jjSoRzqLMrhzE7DBGcg2QqecMdNre12hVompAWcS4l
|
||||
NFmPShKRi6UT8Zb38nD43vwfqwZImn60dOPqqAep3YF/Axm1u5HJb0aMEsb8O9jV
|
||||
sVmNJv9jVTzPdlTGFQjuaeJfk5lwxB+5/O9NcgDhPgRAk9xb4FrT+xzmA/4tD11C
|
||||
AdcITUkTZT4ZOo2418DGeaiaEqWcIkZeQG4Vh5TMj4QtZDwsYQhXPl5Zj1zKIN/1
|
||||
gRrKC+ztaQoDG8pJXTTtc9inRU++dhMqnRGrPcz0VfVXFaiH7PUCy+4WpP6r5Bs5
|
||||
YQ9ESHo+FsmIvDzU3e/PD0SfXfO4vqBrFYN8986NBF2bZaMBBADJafe0w9diaCNx
|
||||
3A7e8MqjbNrhrLkD2cPxXspCATX3SuI19d2+hMiHZfKTyadBTIa+ICxvqoxwxyZD
|
||||
raHSY3CWVZd1V4KB5mqf+3Zj5riLeGU0dtXwi/5c0bdUhBUgHiAMhi75p05jYih5
|
||||
KsNxPcK9hEwPu7B+QeHURMiIgojTGQARAQABwsCDBBgBCgAPBQJdm2WjBQkDwmcA
|
||||
AhsuAKgJEGS79V2S7D0onSAEGQEKAAYFAl2bZaMACgkQzdkMJSM5Bqg2rwP/Ue28
|
||||
m3Fdfgh5JxouZ3Dm2KUDhZL95B+vdMk72acdoU7SRjlyDT8cApRqYx+MIXb8WrPN
|
||||
1xCZnOM4zXeWIM0CAPQ1e/sCrK58L+P+eVngNmrW9epKtZ4L6hx+dqqja9vPZGQK
|
||||
CsFAhA6A1gWB++OLk9Y6H23tWIdKEXMeAX7492zDYgP+OSPS79EWAqXL8SvmDrbl
|
||||
WI5eiM6X5hAMrOjQqzXhatD7eP41N/FC3SfhyhX7hFbagO7MJG2AS5bmSvcuCdcN
|
||||
wDwXd94B+7bfYgJIRKbr272yDwkyzGn+zmxzvMUt6ak5PNzfmadvhMZvIfDftswp
|
||||
GYpXIUU0GObOgP2tpCGTErs=
|
||||
=m++F
|
||||
-----END PGP PUBLIC KEY BLOCK-----`;
|
||||
const privateKey = `-----BEGIN PGP PRIVATE KEY BLOCK-----
|
||||
Version: Keybase OpenPGP v2.1.3
|
||||
Comment: https://keybase.io/crypto
|
||||
|
||||
xcEYBF2bZaMBBAClKkxaMJ05qoF1rtig67cjWLRXJO2teljOUA/eWxaABRXZ5cGe
|
||||
OelcPBvCwsx3ckV2KfyRdRpJw6wHe5yERPkrks9slSuZ5TgnztRxXINjr+3u/6Qc
|
||||
HamsMfRlCLAinf+jccA7k+GKmqyxbLsJY0Qv3kIomzvno54aIinFOvbEzQARAQAB
|
||||
AAP7BXVS5aN3/AkNqIvOiUQ7nqrr9s9NHYUOvJllFNucxZP6x2MyQAjjlJKV9kdF
|
||||
cOhxXDjXVHVIGPT4UUeoAgUHg6K0K5WLmmNaO1w7ayf9737OrhrQFblQNqh4J9BV
|
||||
oP/cArJ5+j/4IGKGYuWy3kTpvtabedlWq99E9PYrDJHD8E8CANDjnboIRgmAwHwi
|
||||
ZKqc5rNXIBl7fJgFdf96cWiMF/7j2nJuarJGJRQUGxDaBi5zZSTZnwfVJZrDboyb
|
||||
JCahLTMCAMpqP0wTM4Qs95HhJUBmAdBhqxXjiAMtMDnn0ue8qAtv4JRjPkfxXUsC
|
||||
4J4PExw6eMU7BCGInel5B6+jdpvURf8B/3koVTHTxyBR/OTpP8XiwOwreb/SleIS
|
||||
JMYiXx6akUoPtACfXyBYM0fqCNCq38ZYhNM89oJbu1Rm5LJHe0m0DY6d4c0AwrQE
|
||||
EwEKAB4FAl2bZaMCGy8DCwkHAxUKCAIeAQIXgAMWAgECGQEACgkQZLv1XZLsPSjC
|
||||
0wP9FP6jgFAnw1JAEOCRh/ja4467VR3oa43z2dfqfbTIBluapDwIecdj5ByXp+3g
|
||||
edsho2sjdqun8LYL5zAXKma3UErIUQlRc7t+3eL8jGeOkKisPIAwINyQO+q6ZrUt
|
||||
a1Qctvmz9m4YxIeeG6OLvghFa4ih8091/tsJlbUYxtb2M1THwRgEXZtlowEEAL38
|
||||
zaNkPmUVQaowP696fayBo18Nxs0yOzC4+0TYv1B/k5aUb0Air2h+o/Xw4E42Jh9g
|
||||
VdPSvhOAEqdV0UDe71wxa4cfAVMDY9v8ta81MWunChj3ISUk1oIQylTJNsY/b4KW
|
||||
OrLaOtBD9dyFGCzss5vLVdqdMjVIW2Cz0hb6IYG7ABEBAAEAA/4xkx7hrM2vOL26
|
||||
t/5WPsM+WVGVAxZGAv549zvxuhEp4zBS0Ya6GJLm1GzaRzFwlyaZd1zN+ibJFdlI
|
||||
OtdwcvvIAqNBsJMcjl2eaVtWK/PYvwqS7mVfojK8zUsKKNFIL6z/JKv7gmXzGuKV
|
||||
S5aYUOUMQI3mliTuqQpfLewhYBtOeQIA42jDWJfxjWiejV6QSNmBYhLeOwi/CFrd
|
||||
YE6obpXqX0V3vVOqB1rw/VHfabkWBmdOu55muw9kCLYOR89HNF6NrwIA1d+cTU7p
|
||||
eFgSUm/u1esS1ucAoxdOPZ7pkLv9+NLQNvjLThmOHCFXyTZr4aoHtnqSG8PcUAWs
|
||||
hyQ35+WpKWA7tQH9GqDFogK+8GjzgVl+vCEnaTV7H/69tS93m9z06hFRs4iEZwWC
|
||||
4oCUNqOFj6IFyiBf2cM0pmMX0ODLnIG5SDVfWaIFwsCDBBgBCgAPBQJdm2WjBQkP
|
||||
CZwAAhsuAKgJEGS79V2S7D0onSAEGQEKAAYFAl2bZaMACgkQNejFNrtoRU1/iQQA
|
||||
mdu8ZNAH58to40qEc6izK4cxOwwRnINkKnnDHTa3tdoVaJqQFnEuJTRZj0oSkYul
|
||||
E/GW9/Jw+N78H6sGSJp+tHTj6qgHqd2BfwMZtbuRyW9GjBLG/DvY1bFZjSb/Y1U8
|
||||
z3ZUxhUI7mniX5OZcMQfufzvTXIA4T4EQJPcW+Ba0/sc5gP+LQ9dQgHXCE1JE2U+
|
||||
GTqNuNfAxnmomhKlnCJGXkBuFYeUzI+ELWQ8LGEIVz5eWY9cyiDf9YEaygvs7WkK
|
||||
AxvKSV007XPYp0VPvnYTKp0Rqz3M9FX1VxWoh+z1AsvuFqT+q+QbOWEPREh6PhbJ
|
||||
iLw81N3vzw9En13zuL6gaxWDfPfHwRgEXZtlowEEAMlp97TD12JoI3HcDt7wyqNs
|
||||
2uGsuQPZw/FeykIBNfdK4jX13b6EyIdl8pPJp0FMhr4gLG+qjHDHJkOtodJjcJZV
|
||||
l3VXgoHmap/7dmPmuIt4ZTR21fCL/lzRt1SEFSAeIAyGLvmnTmNiKHkqw3E9wr2E
|
||||
TA+7sH5B4dREyIiCiNMZABEBAAEAA/wJeGeSwtCaSm48OM4kMms8wu4JxW7PnQon
|
||||
C79z2g25CnbXda+O+TxajXMZ+tXX7qq5PtcICxteZCbK8NuWgmF1QqWWhS2ZLbAV
|
||||
5edTc0vw8FSDwiAeiHyKa5Hs4B3uJaB54uADPyOYHPfX/NhEOfNAleDgVoa1Toqf
|
||||
R50lFsGOVwIA/cetzK3+NTZ5W+V8DGShxv4u5qAhhGZRb0GA3TPAoshVjHWY34i1
|
||||
KivtI3/tLLNTaVSVblG2VVoydKelRhsjGwIAyy0E1KI5O2EhLsVsDwx9NtO4SmUG
|
||||
REZt/LRYp1p5+nsarfeCVKQ4qQ6eqdK71Z7tEICT0JXqgSjQsKYVdscR2wH9GiyR
|
||||
LuHX3Nnh+M8lUv36ZM5XrWEypRFQaNYssRzPpqU4f9oViSPxdADonxehDP4ICmFr
|
||||
vqT+etEmjr9dzp4ZSKLswsCDBBgBCgAPBQJdm2WjBQkDwmcAAhsuAKgJEGS79V2S
|
||||
7D0onSAEGQEKAAYFAl2bZaMACgkQzdkMJSM5Bqg2rwP/Ue28m3Fdfgh5JxouZ3Dm
|
||||
2KUDhZL95B+vdMk72acdoU7SRjlyDT8cApRqYx+MIXb8WrPN1xCZnOM4zXeWIM0C
|
||||
APQ1e/sCrK58L+P+eVngNmrW9epKtZ4L6hx+dqqja9vPZGQKCsFAhA6A1gWB++OL
|
||||
k9Y6H23tWIdKEXMeAX7492zDYgP+OSPS79EWAqXL8SvmDrblWI5eiM6X5hAMrOjQ
|
||||
qzXhatD7eP41N/FC3SfhyhX7hFbagO7MJG2AS5bmSvcuCdcNwDwXd94B+7bfYgJI
|
||||
RKbr272yDwkyzGn+zmxzvMUt6ak5PNzfmadvhMZvIfDftswpGYpXIUU0GObOgP2t
|
||||
pCGTErs=
|
||||
=Ya+/
|
||||
-----END PGP PRIVATE KEY BLOCK-----`;
|
||||
|
||||
const message = "A Fool and His Money are Soon Parted";
|
||||
|
||||
const encrypted = await chef.PGPEncrypt(message, {
|
||||
publicKeyOfRecipient: pbkey,
|
||||
});
|
||||
const result = await chef.PGPDecrypt(encrypted, {
|
||||
privateKeyOfRecipient: privateKey,
|
||||
});
|
||||
|
||||
assert.strictEqual(result.toString(), message);
|
||||
}),
|
||||
|
||||
it("Raw deflate", () => {
|
||||
@@ -860,17 +885,17 @@ smothering ampersand abreast
|
||||
it("toBase64: editableOption", () => {
|
||||
const result = toBase64("some input", {
|
||||
alphabet: {
|
||||
value: "0-9A-W"
|
||||
value: "0-9A-W+/a-zXYZ="
|
||||
},
|
||||
});
|
||||
assert.strictEqual(result.toString(), "SPI1R1T0");
|
||||
assert.strictEqual(result.toString(), "StXkPI1gRe1sT0==");
|
||||
}),
|
||||
|
||||
it("toBase64: editableOptions key is value", () => {
|
||||
const result = toBase64("some input", {
|
||||
alphabet: "0-9A-W",
|
||||
alphabet: "0-9A-W+/a-zXYZ=",
|
||||
});
|
||||
assert.strictEqual(result.toString(), "SPI1R1T0");
|
||||
assert.strictEqual(result.toString(), "StXkPI1gRe1sT0==");
|
||||
}),
|
||||
|
||||
it("toBase64: editableOptions default", () => {
|
||||
@@ -916,8 +941,13 @@ smothering ampersand abreast
|
||||
it("Triple DES encrypt / decrypt", () => {
|
||||
assert.strictEqual(
|
||||
chef.tripleDESDecrypt(
|
||||
chef.tripleDESEncrypt("Destroy Money", {key: {string: "30 31 2f 30 34 2f 31 39 39 39 20 32 32 3a 33 33 3a 30 3130 31 2f 30 34", option: "Hex"}}),
|
||||
{key: {string: "30 31 2f 30 34 2f 31 39 39 39 20 32 32 3a 33 33 3a 30 3130 31 2f 30 34", option: "Hex"}}).toString(),
|
||||
chef.tripleDESEncrypt("Destroy Money", {
|
||||
key: {string: "30 31 2f 30 34 2f 31 39 39 39 20 32 32 3a 33 33 3a 30 3130 31 2f 30 34", option: "Hex"},
|
||||
iv: {string: "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0000 00 00 00 00", option: "Hex"}}),
|
||||
{
|
||||
key: {string: "30 31 2f 30 34 2f 31 39 39 39 20 32 32 3a 33 33 3a 30 3130 31 2f 30 34", option: "Hex"},
|
||||
iv: {string: "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0000 00 00 00 00", option: "Hex"}
|
||||
}).toString(),
|
||||
"Destroy Money");
|
||||
}),
|
||||
|
||||
|
||||
19
tests/operations/Categories.mjs
Normal file
19
tests/operations/Categories.mjs
Normal file
@@ -0,0 +1,19 @@
|
||||
import TestRegister from "../lib/TestRegister.mjs";
|
||||
import Categories from "../../src/core/config/Categories.json";
|
||||
import OperationConfig from "../../src/core/config/OperationConfig.json";
|
||||
import it from "../node/assertionHandler.mjs";
|
||||
import assert from "assert";
|
||||
|
||||
TestRegister.addApiTests([
|
||||
it("Categories: operations should be in a category", () => {
|
||||
const catOps = [];
|
||||
Categories.forEach(cat => {
|
||||
catOps.push(...cat.ops);
|
||||
});
|
||||
|
||||
for (const op in OperationConfig) {
|
||||
assert(catOps.includes(op), `'${op}' operation is not present in any category`);
|
||||
}
|
||||
}),
|
||||
|
||||
]);
|
||||
@@ -14,88 +14,91 @@
|
||||
import {
|
||||
setLongTestFailure,
|
||||
logTestReport,
|
||||
} from "../lib/utils";
|
||||
} from "../lib/utils.mjs";
|
||||
|
||||
import TestRegister from "../lib/TestRegister.mjs";
|
||||
import "./tests/BCD";
|
||||
import "./tests/BSON";
|
||||
import "./tests/Base58";
|
||||
import "./tests/Base64";
|
||||
import "./tests/Base62";
|
||||
import "./tests/BitwiseOp";
|
||||
import "./tests/ByteRepr";
|
||||
import "./tests/CartesianProduct";
|
||||
import "./tests/CharEnc";
|
||||
import "./tests/ChangeIPFormat";
|
||||
import "./tests/Charts";
|
||||
import "./tests/Checksum";
|
||||
import "./tests/Ciphers";
|
||||
import "./tests/Code";
|
||||
import "./tests/Comment";
|
||||
import "./tests/Compress";
|
||||
import "./tests/ConditionalJump";
|
||||
import "./tests/Crypt";
|
||||
import "./tests/CSV";
|
||||
import "./tests/DateTime";
|
||||
import "./tests/ExtractEmailAddresses";
|
||||
import "./tests/Fork";
|
||||
import "./tests/FromDecimal";
|
||||
import "./tests/Hash";
|
||||
import "./tests/HaversineDistance";
|
||||
import "./tests/Hexdump";
|
||||
import "./tests/Image";
|
||||
import "./tests/IndexOfCoincidence";
|
||||
import "./tests/Jump";
|
||||
import "./tests/JSONBeautify";
|
||||
import "./tests/JSONMinify";
|
||||
import "./tests/JSONtoCSV";
|
||||
import "./tests/JWTDecode";
|
||||
import "./tests/JWTSign";
|
||||
import "./tests/JWTVerify";
|
||||
import "./tests/MS";
|
||||
import "./tests/Magic";
|
||||
import "./tests/MorseCode";
|
||||
import "./tests/NetBIOS";
|
||||
import "./tests/OTP";
|
||||
import "./tests/PGP";
|
||||
import "./tests/PHP";
|
||||
import "./tests/ParseIPRange";
|
||||
import "./tests/ParseQRCode";
|
||||
import "./tests/PowerSet";
|
||||
import "./tests/Regex";
|
||||
import "./tests/Register";
|
||||
import "./tests/RemoveDiacritics";
|
||||
import "./tests/Rotate";
|
||||
import "./tests/SeqUtils";
|
||||
import "./tests/SetDifference";
|
||||
import "./tests/SetIntersection";
|
||||
import "./tests/SetUnion";
|
||||
import "./tests/StrUtils";
|
||||
import "./tests/SymmetricDifference";
|
||||
import "./tests/TextEncodingBruteForce";
|
||||
import "./tests/TranslateDateTimeFormat";
|
||||
import "./tests/Magic";
|
||||
import "./tests/ParseTLV";
|
||||
import "./tests/Media";
|
||||
import "./tests/ToFromInsensitiveRegex";
|
||||
|
||||
// Generic tests
|
||||
import "./Categories.mjs";
|
||||
|
||||
// Operation tests
|
||||
import "./tests/BCD.mjs";
|
||||
import "./tests/BSON.mjs";
|
||||
import "./tests/BaconCipher.mjs";
|
||||
import "./tests/Base58.mjs";
|
||||
import "./tests/Base64.mjs";
|
||||
import "./tests/Base62.mjs";
|
||||
import "./tests/BitwiseOp.mjs";
|
||||
import "./tests/ByteRepr.mjs";
|
||||
import "./tests/CartesianProduct.mjs";
|
||||
import "./tests/CharEnc.mjs";
|
||||
import "./tests/ChangeIPFormat.mjs";
|
||||
import "./tests/Charts.mjs";
|
||||
import "./tests/Checksum.mjs";
|
||||
import "./tests/Ciphers.mjs";
|
||||
import "./tests/Code.mjs";
|
||||
import "./tests/Comment.mjs";
|
||||
import "./tests/Compress.mjs";
|
||||
import "./tests/ConditionalJump.mjs";
|
||||
import "./tests/Crypt.mjs";
|
||||
import "./tests/CSV.mjs";
|
||||
import "./tests/DateTime.mjs";
|
||||
import "./tests/ExtractEmailAddresses.mjs";
|
||||
import "./tests/Fork.mjs";
|
||||
import "./tests/FromDecimal.mjs";
|
||||
import "./tests/Hash.mjs";
|
||||
import "./tests/HaversineDistance.mjs";
|
||||
import "./tests/Hexdump.mjs";
|
||||
import "./tests/Image.mjs";
|
||||
import "./tests/IndexOfCoincidence.mjs";
|
||||
import "./tests/Jump.mjs";
|
||||
import "./tests/JSONBeautify.mjs";
|
||||
import "./tests/JSONMinify.mjs";
|
||||
import "./tests/JSONtoCSV.mjs";
|
||||
import "./tests/JWTDecode.mjs";
|
||||
import "./tests/JWTSign.mjs";
|
||||
import "./tests/JWTVerify.mjs";
|
||||
import "./tests/MS.mjs";
|
||||
import "./tests/Magic.mjs";
|
||||
import "./tests/MorseCode.mjs";
|
||||
import "./tests/NetBIOS.mjs";
|
||||
import "./tests/OTP.mjs";
|
||||
import "./tests/PGP.mjs";
|
||||
import "./tests/PHP.mjs";
|
||||
import "./tests/ParseIPRange.mjs";
|
||||
import "./tests/ParseQRCode.mjs";
|
||||
import "./tests/PowerSet.mjs";
|
||||
import "./tests/Regex.mjs";
|
||||
import "./tests/Register.mjs";
|
||||
import "./tests/RemoveDiacritics.mjs";
|
||||
import "./tests/Rotate.mjs";
|
||||
import "./tests/SeqUtils.mjs";
|
||||
import "./tests/SetDifference.mjs";
|
||||
import "./tests/SetIntersection.mjs";
|
||||
import "./tests/SetUnion.mjs";
|
||||
import "./tests/StrUtils.mjs";
|
||||
import "./tests/SymmetricDifference.mjs";
|
||||
import "./tests/TextEncodingBruteForce.mjs";
|
||||
import "./tests/TranslateDateTimeFormat.mjs";
|
||||
import "./tests/Magic.mjs";
|
||||
import "./tests/ParseTLV.mjs";
|
||||
import "./tests/Media.mjs";
|
||||
import "./tests/ToFromInsensitiveRegex.mjs";
|
||||
import "./tests/YARA.mjs";
|
||||
import "./tests/ConvertCoordinateFormat";
|
||||
import "./tests/Enigma";
|
||||
import "./tests/Bombe";
|
||||
import "./tests/MultipleBombe";
|
||||
import "./tests/Typex";
|
||||
import "./tests/BLAKE2b";
|
||||
import "./tests/BLAKE2s";
|
||||
import "./tests/Protobuf";
|
||||
import "./tests/ParseSSHHostKey";
|
||||
import "./tests/DefangIP";
|
||||
import "./tests/ParseUDP";
|
||||
import "./tests/ConvertCoordinateFormat.mjs";
|
||||
import "./tests/Enigma.mjs";
|
||||
import "./tests/Bombe.mjs";
|
||||
import "./tests/MultipleBombe.mjs";
|
||||
import "./tests/Typex.mjs";
|
||||
import "./tests/BLAKE2b.mjs";
|
||||
import "./tests/BLAKE2s.mjs";
|
||||
import "./tests/Protobuf.mjs";
|
||||
import "./tests/ParseSSHHostKey.mjs";
|
||||
import "./tests/DefangIP.mjs";
|
||||
import "./tests/ParseUDP.mjs";
|
||||
|
||||
// Cannot test operations that use the File type yet
|
||||
//import "./tests/SplitColourChannels";
|
||||
|
||||
// import "./tests/nodeApi/nodeApi";
|
||||
// import "./tests/nodeApi/ops";
|
||||
// import "./tests/SplitColourChannels.mjs";
|
||||
|
||||
const testStatus = {
|
||||
allTestsPassing: true,
|
||||
@@ -108,6 +111,8 @@ setLongTestFailure();
|
||||
|
||||
const logOpsTestReport = logTestReport.bind(null, testStatus);
|
||||
|
||||
TestRegister.runTests()
|
||||
TestRegister.runApiTests()
|
||||
.then(logOpsTestReport);
|
||||
|
||||
TestRegister.runTests()
|
||||
.then(logOpsTestReport);
|
||||
|
||||
433
tests/operations/tests/BaconCipher.mjs
Normal file
433
tests/operations/tests/BaconCipher.mjs
Normal file
@@ -0,0 +1,433 @@
|
||||
/**
|
||||
* Bacon Cipher tests.
|
||||
*
|
||||
* @author Karsten Silkenbäumer [github.com/kassi]
|
||||
* @copyright Karsten Silkenbäumer 2019
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
import TestRegister from "../../lib/TestRegister";
|
||||
import { BACON_ALPHABETS, BACON_TRANSLATIONS } from "../../../src/core/lib/Bacon";
|
||||
|
||||
const alphabets = Object.keys(BACON_ALPHABETS);
|
||||
const translations = BACON_TRANSLATIONS;
|
||||
|
||||
TestRegister.addTests([
|
||||
{
|
||||
name: "Bacon Decode: no input",
|
||||
input: "",
|
||||
expectedOutput: "",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Bacon Cipher Decode",
|
||||
args: [alphabets[0], translations[0], false]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Bacon Decode: reduced alphabet 0/1",
|
||||
input: "00011 00100 00010 01101 00011 01000 01100 00110 00001 00000 00010 01101 01100 10100 01101 10000 01001 10001",
|
||||
expectedOutput: "DECODINGBACONWORKS",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Bacon Cipher Decode",
|
||||
args: [alphabets[0], translations[0], false]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Bacon Decode: reduced alphabet 0/1 inverse",
|
||||
input: "11100 11011 11101 10010 11100 10111 10011 11001 11110 11111 11101 10010 10011 01011 10010 01111 10110 01110",
|
||||
expectedOutput: "DECODINGBACONWORKS",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Bacon Cipher Decode",
|
||||
args: [alphabets[0], translations[0], true]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Bacon Decode: reduced alphabet A/B lower case",
|
||||
input: "aaabb aabaa aaaba abbab aaabb abaaa abbaa aabba aaaab aaaaa aaaba abbab abbaa babaa abbab baaaa abaab baaab",
|
||||
expectedOutput: "DECODINGBACONWORKS",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Bacon Cipher Decode",
|
||||
args: [alphabets[0], translations[1], false]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Bacon Decode: reduced alphabet A/B lower case inverse",
|
||||
input: "bbbaa bbabb bbbab baaba bbbaa babbb baabb bbaab bbbba bbbbb bbbab baaba baabb ababb baaba abbbb babba abbba",
|
||||
expectedOutput: "DECODINGBACONWORKS",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Bacon Cipher Decode",
|
||||
args: [alphabets[0], translations[1], true]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Bacon Decode: reduced alphabet A/B upper case",
|
||||
input: "AAABB AABAA AAABA ABBAB AAABB ABAAA ABBAA AABBA AAAAB AAAAA AAABA ABBAB ABBAA BABAA ABBAB BAAAA ABAAB BAAAB",
|
||||
expectedOutput: "DECODINGBACONWORKS",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Bacon Cipher Decode",
|
||||
args: [alphabets[0], translations[1], false]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Bacon Decode: reduced alphabet A/B upper case inverse",
|
||||
input: "BBBAA BBABB BBBAB BAABA BBBAA BABBB BAABB BBAAB BBBBA BBBBB BBBAB BAABA BAABB ABABB BAABA ABBBB BABBA ABBBA",
|
||||
expectedOutput: "DECODINGBACONWORKS",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Bacon Cipher Decode",
|
||||
args: [alphabets[0], translations[1], true]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Bacon Decode: reduced alphabet case code",
|
||||
input: "thiS IsaN exampLe oF ThE bacON cIpher WIth upPPercasE letters tRanSLaTiNG to OnEs anD LoWErcase To zERoes. KS",
|
||||
expectedOutput: "DECODINGBACONWORKS",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Bacon Cipher Decode",
|
||||
args: [alphabets[0], translations[2], false]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Bacon Decode: reduced alphabet case code inverse",
|
||||
input: "THIs iS An EXAMPlE Of tHe BACon CiPHER wiTH UPppERCASe LETTERS TrANslAtIng TO oNeS ANd lOweRCASE tO ZerOES. ks",
|
||||
expectedOutput: "DECODINGBACONWORKS",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Bacon Cipher Decode",
|
||||
args: [alphabets[0], translations[2], true]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Bacon Decode: reduced alphabet case code",
|
||||
input: "A little example of the Bacon Cipher to be decoded. It is a working example and shorter than my others, but it anyways works tremendously. And just that's important, correct?",
|
||||
expectedOutput: "DECODE",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Bacon Cipher Decode",
|
||||
args: [alphabets[0], translations[3], false]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Bacon Decode: reduced alphabet case code inverse",
|
||||
input: "Well, there's now another example which will be not only strange to read but sound weird for everyone not knowing what the thing is about. Nevertheless, works great out of the box.",
|
||||
expectedOutput: "DECODE",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Bacon Cipher Decode",
|
||||
args: [alphabets[0], translations[3], true]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Bacon Decode: complete alphabet 0/1",
|
||||
input: "00011 00100 00010 01110 00011 01000 01101 00110 00001 00000 00010 01110 01101 10110 01110 10001 01010 10010",
|
||||
expectedOutput: "DECODINGBACONWORKS",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Bacon Cipher Decode",
|
||||
args: [alphabets[1], translations[0], false]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Bacon Decode: complete alphabet 0/1 inverse",
|
||||
input: "11100 11011 11101 10001 11100 10111 10010 11001 11110 11111 11101 10001 10010 01001 10001 01110 10101 01101",
|
||||
expectedOutput: "DECODINGBACONWORKS",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Bacon Cipher Decode",
|
||||
args: [alphabets[1], translations[0], true]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Bacon Decode: complete alphabet A/B lower case",
|
||||
input: "aaabb aabaa aaaba abbba aaabb abaaa abbab aabba aaaab aaaaa aaaba abbba abbab babba abbba baaab ababa baaba",
|
||||
expectedOutput: "DECODINGBACONWORKS",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Bacon Cipher Decode",
|
||||
args: [alphabets[1], translations[1], false]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Bacon Decode: complete alphabet A/B lower case inverse",
|
||||
input: "bbbaa bbabb bbbab baaab bbbaa babbb baaba bbaab bbbba bbbbb bbbab baaab baaba abaab baaab abbba babab abbab",
|
||||
expectedOutput: "DECODINGBACONWORKS",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Bacon Cipher Decode",
|
||||
args: [alphabets[1], translations[1], true]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Bacon Decode: complete alphabet A/B upper case",
|
||||
input: "AAABB AABAA AAABA ABBBA AAABB ABAAA ABBAB AABBA AAAAB AAAAA AAABA ABBBA ABBAB BABBA ABBBA BAAAB ABABA BAABA",
|
||||
expectedOutput: "DECODINGBACONWORKS",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Bacon Cipher Decode",
|
||||
args: [alphabets[1], translations[1], false]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Bacon Decode: complete alphabet A/B upper case inverse",
|
||||
input: "BBBAA BBABB BBBAB BAAAB BBBAA BABBB BAABA BBAAB BBBBA BBBBB BBBAB BAAAB BAABA ABAAB BAAAB ABBBA BABAB ABBAB",
|
||||
expectedOutput: "DECODINGBACONWORKS",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Bacon Cipher Decode",
|
||||
args: [alphabets[1], translations[1], true]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Bacon Decode: complete alphabet case code",
|
||||
input: "thiS IsaN exampLe oF THe bacON cIpher WItH upPPercasE letters tRanSLAtiNG tO OnES anD LOwErcaSe To ZeRoeS. kS",
|
||||
expectedOutput: "DECODINGBACONWORKS",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Bacon Cipher Decode",
|
||||
args: [alphabets[1], translations[2], false]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Bacon Decode: complete alphabet case code inverse",
|
||||
input: "THIs iSAn EXAMPlE Of thE BACon CiPHER wiTh UPppERCASe LETTERS TrANslaTIng To zEroES and LoWERcAsE tO oNEs. Ks",
|
||||
expectedOutput: "DECODINGBACONWORKS",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Bacon Cipher Decode",
|
||||
args: [alphabets[1], translations[2], true]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Bacon Decode: complete alphabet case code",
|
||||
input: "A little example of the Bacon Cipher to be decoded. It is a working example and shorter than the first, but it anyways works tremendously. And just that's important, correct?",
|
||||
expectedOutput: "DECODE",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Bacon Cipher Decode",
|
||||
args: [alphabets[1], translations[3], false]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Bacon Decode: complete alphabet case code inverse",
|
||||
input: "Well, there's now another example which will be not only strange to read but sound weird for everyone knowing nothing what the thing is about. Nevertheless, works great out of the box. ",
|
||||
expectedOutput: "DECODE",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Bacon Cipher Decode",
|
||||
args: [alphabets[1], translations[3], true]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Bacon Encode: no input",
|
||||
input: "",
|
||||
expectedOutput: "",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Bacon Cipher Encode",
|
||||
args: [alphabets[0], translations[0], false, false]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Bacon Encode: reduced alphabet 0/1",
|
||||
input: "There's a fox, and it jumps over the fence.",
|
||||
expectedOutput: "10010 00111 00100 10000 00100 10001 00000 00101 01101 10101 00000 01100 00011 01000 10010 01000 10011 01011 01110 10001 01101 10011 00100 10000 10010 00111 00100 00101 00100 01100 00010 00100",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Bacon Cipher Encode",
|
||||
args: [alphabets[0], translations[0], false, false]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Bacon Encode: reduced alphabet 0/1 inverse",
|
||||
input: "There's a fox, and it jumps over the fence.",
|
||||
expectedOutput: "01101 11000 11011 01111 11011 01110 11111 11010 10010 01010 11111 10011 11100 10111 01101 10111 01100 10100 10001 01110 10010 01100 11011 01111 01101 11000 11011 11010 11011 10011 11101 11011",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Bacon Cipher Encode",
|
||||
args: [alphabets[0], translations[0], false, true]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Bacon Encode: reduced alphabet 0/1, keeping extra characters",
|
||||
input: "There's a fox, and it jumps over the fence.",
|
||||
expectedOutput: "1001000111001001000000100'10001 00000 001010110110101, 000000110000011 0100010010 0100010011010110111010001 01101100110010010000 100100011100100 0010100100011000001000100.",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Bacon Cipher Encode",
|
||||
args: [alphabets[0], translations[0], true, false]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Bacon Encode: reduced alphabet 0/1 inverse, keeping extra characters",
|
||||
input: "There's a fox, and it jumps over the fence.",
|
||||
expectedOutput: "0110111000110110111111011'01110 11111 110101001001010, 111111001111100 1011101101 1011101100101001000101110 10010011001101101111 011011100011011 1101011011100111110111011.",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Bacon Cipher Encode",
|
||||
args: [alphabets[0], translations[0], true, true]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Bacon Encode: reduced alphabet A/B",
|
||||
input: "There's a fox, and it jumps over the fence.",
|
||||
expectedOutput: "BAABA AABBB AABAA BAAAA AABAA BAAAB AAAAA AABAB ABBAB BABAB AAAAA ABBAA AAABB ABAAA BAABA ABAAA BAABB ABABB ABBBA BAAAB ABBAB BAABB AABAA BAAAA BAABA AABBB AABAA AABAB AABAA ABBAA AAABA AABAA",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Bacon Cipher Encode",
|
||||
args: [alphabets[0], translations[1], false, false]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Bacon Encode: reduced alphabet A/B inverse",
|
||||
input: "There's a fox, and it jumps over the fence.",
|
||||
expectedOutput: "ABBAB BBAAA BBABB ABBBB BBABB ABBBA BBBBB BBABA BAABA ABABA BBBBB BAABB BBBAA BABBB ABBAB BABBB ABBAA BABAA BAAAB ABBBA BAABA ABBAA BBABB ABBBB ABBAB BBAAA BBABB BBABA BBABB BAABB BBBAB BBABB",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Bacon Cipher Encode",
|
||||
args: [alphabets[0], translations[1], false, true]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Bacon Encode: reduced alphabet A/B, keeping extra characters",
|
||||
input: "There's a fox, and it jumps over the fence.",
|
||||
expectedOutput: "BAABAAABBBAABAABAAAAAABAA'BAAAB AAAAA AABABABBABBABAB, AAAAAABBAAAAABB ABAAABAABA ABAAABAABBABABBABBBABAAAB ABBABBAABBAABAABAAAA BAABAAABBBAABAA AABABAABAAABBAAAAABAAABAA.",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Bacon Cipher Encode",
|
||||
args: [alphabets[0], translations[1], true, false]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Bacon Encode: reduced alphabet A/B inverse, keeping extra characters",
|
||||
input: "There's a fox, and it jumps over the fence.",
|
||||
expectedOutput: "ABBABBBAAABBABBABBBBBBABB'ABBBA BBBBB BBABABAABAABABA, BBBBBBAABBBBBAA BABBBABBAB BABBBABBAABABAABAAABABBBA BAABAABBAABBABBABBBB ABBABBBAAABBABB BBABABBABBBAABBBBBABBBABB.",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Bacon Cipher Encode",
|
||||
args: [alphabets[0], translations[1], true, true]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Bacon Encode: complete alphabet 0/1",
|
||||
input: "There's a fox, and it jumps over the fence.",
|
||||
expectedOutput: "10011 00111 00100 10001 00100 10010 00000 00101 01110 10111 00000 01101 00011 01000 10011 01001 10100 01100 01111 10010 01110 10101 00100 10001 10011 00111 00100 00101 00100 01101 00010 00100",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Bacon Cipher Encode",
|
||||
args: [alphabets[1], translations[0], false, false]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Bacon Encode: complete alphabet 0/1 inverse",
|
||||
input: "There's a fox, and it jumps over the fence.",
|
||||
expectedOutput: "01100 11000 11011 01110 11011 01101 11111 11010 10001 01000 11111 10010 11100 10111 01100 10110 01011 10011 10000 01101 10001 01010 11011 01110 01100 11000 11011 11010 11011 10010 11101 11011",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Bacon Cipher Encode",
|
||||
args: [alphabets[1], translations[0], false, true]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Bacon Encode: complete alphabet 0/1, keeping extra characters",
|
||||
input: "There's a fox, and it jumps over the fence.",
|
||||
expectedOutput: "1001100111001001000100100'10010 00000 001010111010111, 000000110100011 0100010011 0100110100011000111110010 01110101010010010001 100110011100100 0010100100011010001000100.",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Bacon Cipher Encode",
|
||||
args: [alphabets[1], translations[0], true, false]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Bacon Encode: complete alphabet 0/1 inverse, keeping extra characters",
|
||||
input: "There's a fox, and it jumps over the fence.",
|
||||
expectedOutput: "0110011000110110111011011'01101 11111 110101000101000, 111111001011100 1011101100 1011001011100111000001101 10001010101101101110 011001100011011 1101011011100101110111011.",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Bacon Cipher Encode",
|
||||
args: [alphabets[1], translations[0], true, true]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Bacon Encode: complete alphabet A/B",
|
||||
input: "There's a fox, and it jumps over the fence.",
|
||||
expectedOutput: "BAABB AABBB AABAA BAAAB AABAA BAABA AAAAA AABAB ABBBA BABBB AAAAA ABBAB AAABB ABAAA BAABB ABAAB BABAA ABBAA ABBBB BAABA ABBBA BABAB AABAA BAAAB BAABB AABBB AABAA AABAB AABAA ABBAB AAABA AABAA",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Bacon Cipher Encode",
|
||||
args: [alphabets[1], translations[1], false, false]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Bacon Encode: complete alphabet A/B inverse",
|
||||
input: "There's a fox, and it jumps over the fence.",
|
||||
expectedOutput: "ABBAA BBAAA BBABB ABBBA BBABB ABBAB BBBBB BBABA BAAAB ABAAA BBBBB BAABA BBBAA BABBB ABBAA BABBA ABABB BAABB BAAAA ABBAB BAAAB ABABA BBABB ABBBA ABBAA BBAAA BBABB BBABA BBABB BAABA BBBAB BBABB",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Bacon Cipher Encode",
|
||||
args: [alphabets[1], translations[1], false, true]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Bacon Encode: complete alphabet A/B, keeping extra characters",
|
||||
input: "There's a fox, and it jumps over the fence.",
|
||||
expectedOutput: "BAABBAABBBAABAABAAABAABAA'BAABA AAAAA AABABABBBABABBB, AAAAAABBABAAABB ABAAABAABB ABAABBABAAABBAAABBBBBAABA ABBBABABABAABAABAAAB BAABBAABBBAABAA AABABAABAAABBABAAABAAABAA.",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Bacon Cipher Encode",
|
||||
args: [alphabets[1], translations[1], true, false]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Bacon Encode: complete alphabet A/B inverse, keeping extra characters",
|
||||
input: "There's a fox, and it jumps over the fence.",
|
||||
expectedOutput: "ABBAABBAAABBABBABBBABBABB'ABBAB BBBBB BBABABAAABABAAA, BBBBBBAABABBBAA BABBBABBAA BABBAABABBBAABBBAAAAABBAB BAAABABABABBABBABBBA ABBAABBAAABBABB BBABABBABBBAABABBBABBBABB.",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Bacon Cipher Encode",
|
||||
args: [alphabets[1], translations[1], true, true]
|
||||
}
|
||||
],
|
||||
},
|
||||
]);
|
||||
@@ -76,7 +76,7 @@ The following algorithms will be used based on the size of the key:
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "AES Encrypt: AES-128-CBC, no IV, ASCII",
|
||||
name: "AES Encrypt: AES-128-CBC with IV0, ASCII",
|
||||
input: "The quick brown fox jumps over the lazy dog.",
|
||||
expectedOutput: "2ef6c3fdb1314b5c2c326a2087fe1a82d5e73bf605ec8431d73e847187fc1c8fbbe969c177df1ecdf8c13f2f505f9498",
|
||||
recipeConfig: [
|
||||
@@ -84,14 +84,14 @@ The following algorithms will be used based on the size of the key:
|
||||
"op": "AES Encrypt",
|
||||
"args": [
|
||||
{"option": "Hex", "string": "00112233445566778899aabbccddeeff"},
|
||||
{"option": "Hex", "string": ""},
|
||||
{"option": "Hex", "string": "00000000000000000000000000000000"},
|
||||
"CBC", "Raw", "Hex"
|
||||
]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "AES Encrypt: AES-128-CTR, no IV, ASCII",
|
||||
name: "AES Encrypt: AES-128-CTR with IV0, ASCII",
|
||||
input: "The quick brown fox jumps over the lazy dog.",
|
||||
expectedOutput: "a98c9e8e3b7c894384d740e4f0f4ed0be2bbb1e0e13a255812c3c6b0a629e4ad759c075b2469c6f4fb2c0cf9",
|
||||
recipeConfig: [
|
||||
@@ -99,14 +99,14 @@ The following algorithms will be used based on the size of the key:
|
||||
"op": "AES Encrypt",
|
||||
"args": [
|
||||
{"option": "Hex", "string": "00112233445566778899aabbccddeeff"},
|
||||
{"option": "Hex", "string": ""},
|
||||
{"option": "Hex", "string": "00000000000000000000000000000000"},
|
||||
"CTR", "Raw", "Hex"
|
||||
]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "AES Encrypt: AES-128-CBC with IV, ASCII",
|
||||
name: "AES Encrypt: AES-128-CBC with IV1, ASCII",
|
||||
input: "The quick brown fox jumps over the lazy dog.",
|
||||
expectedOutput: "4fa077d50cc71a57393e7b542c4e3aea0fb75383b97083f2f568ffc13c0e7a47502ec6d9f25744a061a3a5e55fe95e8d",
|
||||
recipeConfig: [
|
||||
@@ -537,9 +537,10 @@ Triple DES uses a key length of 24 bytes (192 bits).`,
|
||||
],
|
||||
},
|
||||
{
|
||||
// play.golang.org/p/4Qm2hfLGsqc
|
||||
name: "DES Encrypt: DES-CTR, Binary",
|
||||
input: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
|
||||
expectedOutput: "09015087e15b0937ab0ae5a84d66e520893690a6ea066382bf1330e8876cb3aa82ccc634f8f0d458bbe0257df6f4637cdac89f311168ba91208a21ba4bdd13c4b1a92cb93b33364b5b94a5d3d7fba68f6eed5807d9f5afeb7fbffcd94792131d264004ae",
|
||||
expectedOutput: "09015087e15b0937c462fd5974af0c4b5880de136a5680453c99f4500628cbeca769623515d836985110b93eacfea7fa4a7b2b3cb4f67acbb5f7e8ddb5a5d445da74bf6572b0a874befa3888c81110776388e400afd8dc908dcc0c018c7753355f8a1c9f",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "DES Encrypt",
|
||||
@@ -630,9 +631,10 @@ DES uses a key length of 8 bytes (64 bits).`,
|
||||
],
|
||||
},
|
||||
{
|
||||
// play.golang.org/p/RElT6pVeNz2
|
||||
name: "Triple DES Encrypt: DES-EDE3-CTR, Binary",
|
||||
input: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
|
||||
expectedOutput: "874d32cd7bdae52c254687e2d7e7093b077af2ec70878f99315f52a21ded5fb10c80a47e6271384335ac47376c758f675484fd7b8be9568aaec643f0d15cffdf3fe54ef3a1b2da50d5d8c7994d7a4a94e0a13a4d437443f0f1f39e93dd13ff06a80c66e4",
|
||||
expectedOutput: "874d32cd7bdae52cd8630d3ab2bf373e7110e13713caa6a8bfed9d9dd802d0ebe93128ac0d0f05abcc56237b75fb69207dba11e68ddc4b0118a4c75e7248bbd80aaba4dd4436642546ec6ca7fa7526f3b0018ed5194c409dc2c1484530b968af554984f3",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Triple DES Encrypt",
|
||||
@@ -681,7 +683,7 @@ The following algorithms will be used based on the size of the key:
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "AES Decrypt: AES-128-CBC, no IV, ASCII",
|
||||
name: "AES Decrypt: AES-128-CBC with IV0, ASCII",
|
||||
input: "2ef6c3fdb1314b5c2c326a2087fe1a82d5e73bf605ec8431d73e847187fc1c8fbbe969c177df1ecdf8c13f2f505f9498",
|
||||
expectedOutput: "The quick brown fox jumps over the lazy dog.",
|
||||
recipeConfig: [
|
||||
@@ -689,7 +691,7 @@ The following algorithms will be used based on the size of the key:
|
||||
"op": "AES Decrypt",
|
||||
"args": [
|
||||
{"option": "Hex", "string": "00112233445566778899aabbccddeeff"},
|
||||
{"option": "Hex", "string": ""},
|
||||
{"option": "Hex", "string": "00000000000000000000000000000000"},
|
||||
"CBC", "Hex", "Raw",
|
||||
{"option": "Hex", "string": ""}
|
||||
]
|
||||
@@ -697,7 +699,7 @@ The following algorithms will be used based on the size of the key:
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "AES Decrypt: AES-128-CTR, no IV, ASCII",
|
||||
name: "AES Decrypt: AES-128-CTR with IV0, ASCII",
|
||||
input: "a98c9e8e3b7c894384d740e4f0f4ed0be2bbb1e0e13a255812c3c6b0a629e4ad759c075b2469c6f4fb2c0cf9",
|
||||
expectedOutput: "The quick brown fox jumps over the lazy dog.",
|
||||
recipeConfig: [
|
||||
@@ -705,7 +707,7 @@ The following algorithms will be used based on the size of the key:
|
||||
"op": "AES Decrypt",
|
||||
"args": [
|
||||
{"option": "Hex", "string": "00112233445566778899aabbccddeeff"},
|
||||
{"option": "Hex", "string": ""},
|
||||
{"option": "Hex", "string": "00000000000000000000000000000000"},
|
||||
"CTR", "Hex", "Raw",
|
||||
{"option": "Hex", "string": ""}
|
||||
]
|
||||
@@ -1160,9 +1162,10 @@ Triple DES uses a key length of 24 bytes (192 bits).`,
|
||||
],
|
||||
},
|
||||
{
|
||||
// play.golang.org/p/FpvqncmPk7R
|
||||
name: "DES Decrypt: DES-CTR, Binary",
|
||||
input: "09015087e15b0937ab0ae5a84d66e520893690a6ea066382bf1330e8876cb3aa82ccc634f8f0d458bbe0257df6f4637cdac89f311168ba91208a21ba4bdd13c4b1a92cb93b33364b5b94a5d3d7fba68f6eed5807d9f5afeb7fbffcd94792131d264004ae",
|
||||
expectedOutput: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
|
||||
expectedOutput: "7a0e643132750e96b76dc9efa7810bea2b8feaa5b97887e44f96c0e6d506cc4dd4665683c6f63139221f8d887fd0a05b39741f8a67d87d6ac6f8dc6b668bd3e4a97b8bd3a19eafd5cdf50c3e1b3f17d61087d0b67cf6db31fec338b75f5954942c852829",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "DES Decrypt",
|
||||
@@ -1253,9 +1256,10 @@ DES uses a key length of 8 bytes (64 bits).`,
|
||||
],
|
||||
},
|
||||
{
|
||||
// play.golang.org/p/iBacN9kX_RO
|
||||
name: "Triple DES Decrypt: DES-EDE3-CTR, Binary",
|
||||
input: "874d32cd7bdae52c254687e2d7e7093b077af2ec70878f99315f52a21ded5fb10c80a47e6271384335ac47376c758f675484fd7b8be9568aaec643f0d15cffdf3fe54ef3a1b2da50d5d8c7994d7a4a94e0a13a4d437443f0f1f39e93dd13ff06a80c66e4",
|
||||
expectedOutput: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
|
||||
expectedOutput: "7a0e643132750e9625205bc6fb10dc848c53b7cb5a654d1242aecb6191ad3b5114727e5044a0ee11311575873c54829a80f9471ac473a0bbe5e791a23be75062f7e8f2210d998f9fbbaf3a5bb3dacd494d42d82950e3ab273f821eb979168315a80ad20f",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Triple DES Decrypt",
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
* Image operation tests.
|
||||
*
|
||||
* @author tlwr [toby@toby.codes]
|
||||
* @author Ge0rg3 [georgeomnet+cyberchef@gmail.com]
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
*
|
||||
* @copyright Crown Copyright 2017
|
||||
* @copyright Crown Copyright 2019
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
import TestRegister from "../../lib/TestRegister.mjs";
|
||||
@@ -175,4 +176,91 @@ TestRegister.addTests([
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Extract RGBA",
|
||||
input: "424d460400000000000036040000280000000400000004000000010008000000000010000000120b0000120b0000000100000001000000c8000000cf000000d7000000df000000e7000000ef000000f7000000ff000083000000ac000000d5000000ff000000000083000000ac000000d5000000ff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f070d05030b01090c040e060008020a",
|
||||
expectedOutput: "0 200 0 0 0 131 0 215 0 0 0 213 131 0 0 0 231 0 213 0 0 0 247 0 0 223 0 0 0 255 0 207 0 0 0 172 255 0 0 0 255 0 172 0 0 0 239 0",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "From Hex",
|
||||
args: ["None"]
|
||||
},
|
||||
{
|
||||
op: "Extract RGBA",
|
||||
args: [" ", false]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Extract LSB",
|
||||
input: "89504e470d0a1a0a0000000d4948445200000020000000200806000000737a7af400000449494441547801cc9703782b5914c783b56ddbb659db6e9f6ddbb66dd45e6fddc6aecd24cff67b99397b6ebe9d6216d99bcceebefb7dffbaf9ff0e7347e4e491eeddbbf7f5bcbcbc41b9b9b943376cd8f00ef9194afcfb67094ac0d3ed85870d1b764755555592c562616a6a6a18ad560b28b6a0a0203b3d3d7d4e494989fed75f7fdd45fe5e10e38c8c8c0f2a2b2b7737343468ebeaea8a516aabd50a441c00278d46c392cf2a95eaf475d75d7767525252505656565f67332296c9644330d2cbc48c2f3e005f656565ed08c410656666c653bb63e4ef9acd66ce9c0a8027164b430d20aea8a8d84e4c5c05c02c1ebce9a69b6e27af49d5e5f5f5f56a4700b5b5b5ac0300ae1cad3ffdf4d3321a0809365bc93f007068cea9b8b8584e35197abd7e8e5019c032983103aba8ca306fdebc07dadada2c02f4c0a15b6eb9e50ea746313535f5ade6e6e63a57008870170c14397b9e7cf2c97bc838d20294969636e30eb0a1181ce9de2217ce2d087089060037e139b1587ce7fefdfbfd30fa3ef4e9771140a1501cc3ffbb91deea2a05b8991640a9541ec5ffbb5e2800497272f20f7880afad5bb73273e7ce05bea64c99922ee49de07a9d4ed760341a812fbc9030696969c0574a4a8a11ffef5a979d5fbaffe61be604bf3dc698b9d966cade0add555ffa13ab91c96cbb76ed62e7cf9fdf43b367cf3ef7c5175f78ba9cfac5fe2f6cd62e88828a65f13c25c0595d09542b95cceeddbb212020007c7d7d7bc8c7c7e7b2bbbbfbf34ebbc7bcf3e0a33ba25eb992d8f70330ace8df692e9b1703478b7300dadaec00782784799be7815b9c1b676e070a0a0a2a78f7dd77ef7573737b468a871a60b6e733513ba35e818d612fc111b50cce5768a15f983fcc9c311d4a3233e1427d3dfc9c98c8e6e4e4c07d89f7c1dbd96fc3a8ef47c1f6eddb61c78e1dd0b76fdf8b090909c67efdfa31616161b154e6833e7ef4c96d112f1fe5008e6995f688372f5902512121d0a152c1711cb7cc8d1b01b71d4c2a9b64875893b70648461213138fa1794dfffefd01c54645458da102581df8c26a62ce07e0646b6981530a851d60f5ead5c4b48770f7d77b7b7bfb1180e8e8e82db43764c986d017cbfe0ee05c6d2d5cd268ec003366cce00390516c0c0f0f5f4c007af7ee5d4dfa800640bc2ef8c5744719384300366d62478d1a05a40fba03e0430b8bb5070240141717b792aa0433dd9f76db11f98a8d0fd05d6c6b2b54cae56c76763631e503407c7cbc2130303018cd777dfdf5d78f53df8a17fa3cdb7f7bc4cba7ba03301879bbc904c770024e3637c37eec7834204d4622be826fbd2c07803f5b2e72f584bdf1c0fd13be7e32fe54b9e92417f9653437e3fb40c39e3db067c10216f73eb36edd3a06cb6037479155dcfef9e79f3f2cd87361555e5ec4a5c64633bf0cdc22ea2ecc8265e7ce9dfe22a1cfe4a143ef32ab54532e363434f10038e30e9cffdfd650545424c8404bc0c4c4c47664cd1a83c7274ec41fdeb62d0f58192501a3c04c5e5e9e8d1cf30084683c77e1e9adc80000000049454e44ae426082",
|
||||
expectedOutput: "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000240000000000000000000000208000000000000000000008000000000000000000000000248000000200240000000208908000000200240000000200821000000200240000000061249000000240000000000209b69000001a49b00000000a204a1200001a49b00000009800414000001a49b0000000035db6c00000094924000000086dffc20000df6dec8000001e10014a0000df6dec800002564924b00000df6dec80000009a6db20000007edb4124804177fffba0002fffff69249044e0924bc4002fffff6924905fb2db6d04002fffff692490416d2490040001bfffcc92030dbffffdc00037fffffdb6d302c6db6d700037fffffdb6d327eb6db6148037fffffdb6d30db4000014800dffffeb6d9aefffffff640",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "From Hex",
|
||||
args: ["None"]
|
||||
},
|
||||
{
|
||||
op: "Extract LSB",
|
||||
args: ["B", "G", "A", "", "Column", 2]
|
||||
},
|
||||
{
|
||||
op: "To Hex",
|
||||
args: ["None"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "View Bit Plane",
|
||||
input: "89504e470d0a1a0a0000000d4948445200000020000000200806000000737a7af400000449494441547801cc9703782b5914c783b56ddbb659db6e9f6ddbb66dd45e6fddc6aecd24cff67b99397b6ebe9d6216d99bcceebefb7dffbaf9ff0e7347e4e491eeddbbf7f5bcbcbc41b9b9b943376cd8f00ef9194afcfb67094ac0d3ed85870d1b764755555592c562616a6a6a18ad560b28b6a0a0203b3d3d7d4e494989fed75f7fdd45fe5e10e38c8c8c0f2a2b2b7737343468ebeaea8a516aabd50a441c00278d46c392cf2a95eaf475d75d7767525252505656565f67332296c9644330d2cbc48c2f3e005f656565ed08c410656666c653bb63e4ef9acd66ce9c0a8027164b430d20aea8a8d84e4c5c05c02c1ebce9a69b6e27af49d5e5f5f5f56a4700b5b5b5ac0300ae1cad3ffdf4d3321a0809365bc93f007068cea9b8b8584e35197abd7e8e5019c032983103aba8ca306fdebc07dadada2c02f4c0a15b6eb9e50ea746313535f5ade6e6e63a57008870170c14397b9e7cf2c97bc838d20294969636e30eb0a1181ce9de2217ce2d087089060037e139b1587ce7fefdfbfd30fa3ef4e9771140a1501cc3ffbb91deea2a05b8991640a9541ec5ffbb5e2800497272f20f7880afad5bb73273e7ce05bea64c99922ee49de07a9d4ed760341a812fbc9030696969c0574a4a8a11ffef5a979d5fbaffe61be604bf3dc698b9d966cade0add555ffa13ab91c96cbb76ed62e7cf9fdf43b367cf3ef7c5175f78ba9cfac5fe2f6cd62e88828a65f13c25c0595d09542b95cceeddbb212020007c7d7d7bc8c7c7e7b2bbbbfbf34ebbc7bcf3e0a33ba25eb992d8f70330ace8df692e9b1703478b7300dadaec00782784799be7815b9c1b676e070a0a0a2a78f7dd77ef7573737b468a871a60b6e733513ba35e818d612fc111b50cce5768a15f983fcc9c311d4a3233e1427d3dfc9c98c8e6e4e4c07d89f7c1dbd96fc3a8ef47c1f6eddb61c78e1dd0b76fdf8b090909c67efdfa31616161b154e6833e7ef4c96d112f1fe5008e6995f688372f5902512121d0a152c1711cb7cc8d1b01b71d4c2a9b64875893b70648461213138fa1794dfffefd01c54645458da102581df8c26a62ce07e0646b6981530a851d60f5ead5c4b48770f7d77b7b7bfb1180e8e8e82db43764c986d017cbfe0ee05c6d2d5cd268ec003366cce00390516c0c0f0f5f4c007af7ee5d4dfa800640bc2ef8c5744719384300366d62478d1a05a40fba03e0430b8bb5070240141717b792aa0433dd9f76db11f98a8d0fd05d6c6b2b54cae56c76763631e503407c7cbc2130303018cd777dfdf5d78f53df8a17fa3cdb7f7bc4cba7ba03301879bbc904c770024e3637c37eec7834204d4622be826fbd2c07803f5b2e72f584bdf1c0fd13be7e32fe54b9e92417f9653437e3fb40c39e3db067c10216f73eb36edd3a06cb6037479155dcfef9e79f3f2cd87361555e5ec4a5c64633bf0cdc22ea2ecc8265e7ce9dfe22a1cfe4a143ef32ab54532e363434f10038e30e9cffdfd650545424c8404bc0c4c4c47664cd1a83c7274ec41fdeb62d0f58192501a3c04c5e5e9e8d1cf30084683c77e1e9adc80000000049454e44ae426082",
|
||||
expectedOutput: "89504e470d0a1a0a0000000d4948445200000020000000200806000000737a7af400000140494441547801c5c1416ea3400000c1ee11ffff726fe6808410186ce26c95fde0432a154f0cdea4b2aa505151519954ee1a5c50995454aea8ac54ae2c5ca8982a3ea132551c199c507942e58ec1898adf50f1cae084ca15952b2a152a47067f40a5e2c8e00f54a81c199ca8b85271a542a5e2c8e005159527542ace0c5ea8a8f844c54ae5ccc217555c197c41c55d83ff6cf0052a772ddca052b1a752b1a772d7c2432a4f2c3c50f1d4c20b2a1593ca918a4965afe2cac29b2a562a93ca56c55d0b2754b62a269555c554b15251a9b8637040e5884ac54a654ba5a2624be5cce040c5918a55c55ec5a4a232a9549c197c48655239523155bc3278a862af624be5ccc2072aaea854a8549c5978834a85ca5ec5918a57ec076f50a958a9546ca94c1557ec071754a68a2d958a270637544c2a2abf69e1a68a95ca54b152a978d73f2e08bd57b6f839a00000000049454e44ae426082",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "From Hex",
|
||||
args: ["None"]
|
||||
},
|
||||
{
|
||||
op: "View Bit Plane",
|
||||
args: ["Green", 3]
|
||||
},
|
||||
{
|
||||
op: "To Hex",
|
||||
args: ["None"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Randomize Colour Palette",
|
||||
"input": "89504e470d0a1a0a0000000d4948445200000020000000200806000000737a7af400000674494441547801c5970394244b1686bf44b9aaddd5fdfcc6330f63af6ddbdea3b56ddbb66ddbdeb16dcf5497d219b137f3d44363ba7b70cede73be74c6fd6f4454e45ffcbfc398ecdef7bef7bd35c562f1c59669de0fc32818467a590ec7bca635bab38fe27823b0278aa29f3cf0810ffc12a02e4680f9fdef7fff1903d5eaa766cd98412e9f2793c91204216118c83e052509b3d96c4aaeb3775d07152b1a8d3a478f1ee5452f7a5101f0384fd88b172f666c6cd8b0215f2e973fb576f56a40e37901be248ce34888514a9192542edcfebcb7a7977a7d844e70e4c891d2a402e401c6c6631ffbd82b92864dd3948ac3b4f1e4bc13c91008a6a0097c1fa7dd927d20421d9acd16beef1fdbba75eb8f5ef9ca577eee6286c010867ef5ab5f1dbfd7bdee858c2569d7cb5ec4488206b55a8d76bb8de7ba64b2198af9025ddddd5c71e5951cd8bf9f37bef18d4f9121fc0f705aa80bc1797b80f1a11392ea034968c8be561be1e4a913d425719ab054a6af7f003b63532a1629e4f3140a058a42d25b3367ce6c02870467aa1eb09938a2fffef7bf6f035e8661d85ac3cd37dfcc82053726e39c56ef380e511c89400bd34ab001b06c9beeee9e00f0264f3eb900f7e52f7ff9e7819f0995bffe6bddcf77ef3f8c8a0fa20123c1209d1771ace47a9cce0b3b63093656363f6a782f4680271c13ce093dcf7ae09d9ef8f47bf77c05a5c964f2686c1a4d9f43474e72e7bbaf65c5da9b3876ec0c9ff8c84fe8abf4b1eff4a118d04c234c260e25381d012756cfee5b15eb1c37ad5c4dbe7b8062ff20f778f0bd78c7c7dfc4fd1e716f8add7dcc98338365775a8c952bb260c6d58f03cc4b1030fa996ac57a96e318acbecb1a9efdba17f28ce73e8585cb1612470aa7ede17b3e9e1771e59503f8a14339977d1490bb1c028c27ace85f6d59e41dd764efcebdd07668b59c74127a92d8f7935531220803dc769b4ac10243171ebf727035605caa804c7fd1783268c2c0e2f73ffb2b5aa9643de82ccb091191ec93c9b86de35e72392bfd290e96cc2701994b1590b550cbb58a29e6234e9d70d9b3f3202a124191240f2479140a8a53c7ce51cae4b06d489eb78c782590bd6401b6a517a838c0204c1bffcd0fff045aa7e31f45b1a0e43466e3bf77808e8845905221b188b81c3d600611bb6215a1421fad7cf6eed8cba986471448a2385d9ef9f7e6bdd4ced688635f0404c46180a8b0a633076c260fe587d131db30e606848045fff09558a6c5f68367f0ddb6ac05a769b49a682d4f784e2a00342d37da04e84bed81e0137f6f3ef7f499c6df5b5ebc1b2b878a5c4c4333dc57c1360d8a390b4bce5bf5b3683343aee70ae7ecb9e696afad77df080497e2880032af7ff3dbeef8d0873dfcb5f3e6cfbb5bc182fffee8ad74570cd0a41f2ad334049346bdc1cd0f78335e0c070f1e3efbef7ffefddd4f7afc63de0f041723c0f8f297bf3c7be1c245df5db850be429d38f09faf523bb20ed3ca25d96fb366a929f1c915079877f797a6823ac6c6dbb973e7ddc45ffc13d0d31d02e3339ff9ccbc952b57ee4a92bb9e475daa6b341d8ce23544dac269d5709da6d0c2711ab49373d7c7ee992bcfd68526c97be2b6f2c2dfa598b58031dd1ec8feec673fdb70bffbdd6fc1b9da48faf93520add8346d4c3bc7b9037fe3e8a6efe33b67b0ed3cc3f3ef4b75eebdc1b2d17188d6f1adcea9afb7873ffce10fe1ddee76b72ec09b8e80ee75ebd68d2c59b2444cc8e9d10ef8162b264252e418345a451d5472065a20d96986aa83ac5fbf8eb7bef56dd701871813f6231ef1083ac177bffb5de3ddef7ef74ab1e2a9058b22459a7f5c244e2915031d630aa374269705952ed9625058b66cd9bc57bdea5547c69a145b928e3aaf56ab6b1301a9ed56112332a67d3d3da831494c6db26bcf1e868786e8aa54c4fd1e1e25a0d56c33343c4cb9524e2ddb8c19331e08fc4150934d42bb542a2defefef97065ae947a53e524f7a6394fd9663418112525714b362c50a962f5f2e7b418ed7ac59239577e3b5db744b01f97c7e39909d6a25cc4af5cb054e9d394bac54cae12347a94895e57209cbb268b7da341a0dec6c8eb3e76af84198625a26ade45ebd91bae96a7520494c75a88a14b614c84c25c0ce66b3c3406a322ccba4bfaf174f8e1bcdc6a83f1c32395314506fd4d37b1dbf28490b527d05dbce10851100b95c2e0fd853fd0a06befded6f7fbfb7b7f78e69825b67fe6d8f1a13bda9c71fca308dfacfa8b46ec9ff8c59c0a9c90454846b8501c1e6f285166ac27e6164b2217085431d9506973702a1cd98f81f11b2640d65786ac70000000049454e44ae426082",
|
||||
expectedOutput: "89504e470d0a1a0a0000000d4948445200000020000000200806000000737a7af4000007ed494441547801c5c17b5c0d8602c0f15f9de3d16425a113999296348f3c0b75ea4e2b5be7a05bd46a32c99b5496477266d494ac97508a0e494848c2525e87bc95ccb31145915e3abacb38f7b6cfdde7d3a74faafff6fdaa59c81254fc8384b42179b40501455ee84476617b920eeee33e6742d7c994d685d15c9ac31ff85f5c4386b13ada4b0268a2597c8dc7fa72da23e423ccfca67221fa32f29dfe1c59b08ef4c4459c7a5acc1e130396d5aee2f8d8092c105ee7f9a91a6e6db6a6c4d3893e96b318aa1b41b7aa0822cd156c1aa5c39b2e0f698b7097d36b5af2caec499cc29dd409bd389b578ea66f10569394fc229b89f7fd2f890bbdcbbbeb83c8511b8acbc67b6cad39c7c691f7e81ceb829eb12deb6de740247f912e1c465b84d285c368c92150c68f338e31784e11c3924e522281d50a0156fdf84bf27a1fa2c4de7cb3d79dbdd3ab916f90a2b4ec45e3e6159cb54fc6c8741fa3b48a703e654e0f872ada2230f216cb348cebd030ae43c3b80e0de33aca2a2c30cc37a5d7c89714780a11de84dda24914ae28a5617b209f0f4e22bba03bfd973930a1df22ece73ea1dbe30d8c9ee48455e925a2d39dd861fa968e1088c41219ad1873b89e5137bf66a465029b46f461aaebf79cad7c4e68f0262aabba503ec09123e3b7a319e6cbdefe12385e485d5d0fe4d21e7c2bb047d1e94b3a429d8fb0d64de39cff1172f213581aea8f32eb2ebaf23bc85f6be2e1b5859af4a5680c9d4df046299551c9ec58ed49935d3f9bf04a2d8b8e1288c41219ad383ebe3f771475dc30f88490e1f7e82c8c62f34007be8e53e026b5c4c3a11b03ae6f657abf4944e8fe4efef3293c689c8d87961e11db9da91beb4847084462898c76e48499b243438fead0183e645660133886d3ffaa65acc0971b0113c9add4a3583b1c9f05b5a46c352447bb2f5a867de908753ac03f478bb26b9f52e4f88642e712b47cb7b122f4097ee5d5788cc8e2e8e20a4c94cf5962fa03e9257339635d4e47a9d30195dade841c9273d5408731bdcbf139b983d8de57393d2f908c992ed49b6c6474a101f1c11928dc8ef066ed753a4a483b740f34703fd38c82ada58c7c358f17c77ee2c98aa7acf9598df57ebfd0b93a8dfc3333c82aafc0e1e518968f49e7495e2e6a411fe8ba5e417bd469c79463eef8c54f63d76173a24f9f40b955c989dcb7f867bee7b33c29fd97b8e09c771de5ae5a9c4bd7d15747cae8ea30065ebc4d47086987b6cd34eef4aca56be65bfcc3c6312fab37bb2ec5303c64177d621c18eb25e24ef71ea41e0c216250000d9e525ef7d065d0d628ca3a4da73d02915822a30d1a29c398ebf12be1a5f3d1093a42df9709bc4a6e60d07721945c3d84a47b118a803c0483aff02e3a9eb74356b2283688ec05f6bcf94d8ff6a8d38ebb353ac4fe618ac53d57ee5cbd8874f26d2e9d8ec3eebc2b8ee163f1591bc3a0e25282b639d14bc305a7c652f20b37a06bb8878e50a71d8eff598d4cef2056dd8cd896da8537aebe6cd3b4e3c1706b2a53f5315d1b448d5a363a669fa2f2d442392198f8fe539816ad4e47084462898c36dc2cb4e2d6dc2f181b5241cf47f1147c178db67b19911e4fd1ba3c9e9f728e7241ef393766ca091a974145891ca5d88751920cf21555b44720124b64b44112f135a9053739693e0a3dd3f1684b5c392f4a24cefb027aef0663be3190c64867ba769acc90f43ed8c4a450239b43f5aa069e7656d11e753e62ffd52c94b646f49b7b1fcb3001d6dfbe6375d5778cebfd16cbc453b8669dc66e71144b8dc55cb7fb8a4b71fa1cb55d4279843e36cb2d18aa32e2135b7f027cbc688b402496c868c1cd620259ba4370b9aacec0a06c1cbfe8c2b08614a2b5df5353e14db0db441efa2e4623f92835c92bf18df56464919440d52c56b113b7ec4d686fd1e6b31d6b5813b6946335c51ce86b426b0422b144460be10633a9bff56ff236dee7878bc94c0e7d48a3d10d82baf664f45e3f7627a868541c47f9bb883d665ff15a56c5a36c2f54f16e6cb8a0497d4d29c2a365ecdf2ec2eb81132b0627a0fa7322ad11d28a5986a94c038cc2d7121da5e026ffa380a4862c0c0fc552231f87fcad90facf0229f23ac9dcc2482aee66919462c1a188857caf914813a3f0f1c03e9e8913c8ea398bd6a85d7bd85fc5fff9a4ace19c7e236689d964e858e26d9946c172335ab2d9ff827a83e1bc5fe8c78cf70dbc59684373f1ebeaf009fe940d3eb67cf54087dfb65c2379ea3cfc2ebfa725350b59828a66242bed51793b53f5a29ea84e3d89f2ddc4a4158598e9c969ce35ad8cf9f9fdb8bf3a86dcd35389720ce66fa22d2202a507099b338078fd18cc3ba961305f972901beb424108925329a99b5e021eb96e570f4543051b955ec769dca3c074b164b8d78f4e3532eb9f720b1fb5224a5d6ccd73d4892e609726a63095ee9c39e705b94cf26e3f3a18eb2ea7378561af0f3950f6cb1abe151cc455e5dba474b02915822a319ffd9c188cec8499a2a20c4269ebbb9ae7c1b684556c40786767bc6fdd05b4c1c6a49491739f2dc13d8efb62661531acbc6ebb1ece57ee6ab7499257067e7f2e92cb1d267709f517c73db8d068fde3cb1bc474beab4b0d376274df68d9b89dedd3b0ccc48648fc93374970e42651c878be1af8cd83986cd7602940557386babe0855a19b5ef42e86df788b3227b4e2c7362f3a248a47f1612e1349f26e71f3ca6356a16b20415cd445d7984225d4c695d1887334d386f664f9c7d3ff282dc68f2a7cf019a180d5cc4df7e2f8ee56fc278179a1cb00e67e26fa798e2f48034873f280ed1447cd98596d42c64092afe41eafcc3fe0b9c67148a38c1a5620000000049454e44ae426082",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "From Hex",
|
||||
args: ["None"]
|
||||
},
|
||||
{
|
||||
op: "Randomize Colour Palette",
|
||||
args: ["myseed"]
|
||||
},
|
||||
{
|
||||
op: "To Hex",
|
||||
args: ["None"]
|
||||
}
|
||||
]
|
||||
},
|
||||
/*{ This operation only works in a browser
|
||||
name: "Optical Character Recognition",
|
||||
input: "iVBORw0KGgoAAAANSUhEUgAAAUAAAAC0CAIAAABqhmJGAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAASuSURBVHhe7dftVdswAIbRzsVAzMM0XabDUCOUxLYsWW4Jp+/pvf9w9GH76CHw4x2IJWAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAI9p8G/PbyY8rL2686g8t+vnqHTyfgIYfvz/26veTXn/UKX8+f0EU9bHrtu/6KfAN/AwEXAj7lFf2TBFw4nae8on+SgIvJ01n/KLzpDK+L3bT/Ap4O+HC+V12mTH+M3gzcLbIY/EO6HfxYp13k09nb6r3UqcdnjoCL3ll72J26h+35Oxy2XvZ0wOLaXq9v2+F1UC+7RZtMZ/DnfX1lwDOPzwUCLo7O2trtDK8H3M/iqoc6bj1subT68XTA/F7bGJooyzKbhTvLPHY8eJLHlbNX1DqYUVfdXbqwJjsCLsans37aNNJM6w68OR0wv9f9ymKw3k67yn2ZZpHlg3a3zis60s6oV+ZvlzMCLoanc3Dsdt9TdWT/lM8OmNjr5KY72jmzq1zfrbvXtVtmRMDF8HTWcgaaqIrD1U4G/MFewxrW262s5jS/Fzpmdts6mnHy+Fwl4GJ0OjsNrG1P/y7CNo3+gEt7jW56MVprNed7A/5w+n6YJ+BieDpnj/jO6pweTz0acGWvmZveL9XOmd3x6wKuTt8PEwRczLRw4eje1XX7c/cDruw1uuneOu2c4aOvzI57mJhRh1xZlQ0BF+Oz9vcF96fuB1zYa7R2b5mD6/XSwdfg8snj4q21+W/L02dfzIxhQMDFyTm6Hd7m+JYP7rPKT5sRuzhOBywm91rUkYc3fV9ltchtr8VmzuGOdfDB9N1tFYefNfdXLmyGjNZkhoCLUQufVqd/7z7rUcLW/XieDvg0s9difNOdRV5ePibt5vTuazusWbF9rs2E5v4mH58LBFyMW7g5OID7s9cMuTygmt9rcNPb5MrAz0lHc3Z9Ht7XZsxqxO36ZtLR/c0+PpMEzLOc/4LhrwmYZ6lfywJ+JgHzJPr9DgLmi23/zdXvcwmYL7YKWL1PJ2AIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmCI9f7+G6yFxVg/GyYwAAAAAElFTkSuQmCC",
|
||||
expectedOutput: "Tesseract.js\n",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "From Base64",
|
||||
"args": ["A-Za-z0-9+/=", true]
|
||||
},
|
||||
{
|
||||
"op": "Optical Character Recognition",
|
||||
"args": [false]
|
||||
}
|
||||
]
|
||||
}*/
|
||||
]);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
const webpack = require("webpack");
|
||||
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
|
||||
const CopyWebpackPlugin = require("copy-webpack-plugin");
|
||||
const path = require("path");
|
||||
|
||||
/**
|
||||
@@ -50,6 +51,13 @@ module.exports = {
|
||||
new MiniCssExtractPlugin({
|
||||
filename: "assets/[name].css"
|
||||
}),
|
||||
new CopyWebpackPlugin([
|
||||
{
|
||||
context: "src/core/vendor/",
|
||||
from: "tesseract/**/*",
|
||||
to: "assets/"
|
||||
}
|
||||
])
|
||||
],
|
||||
resolve: {
|
||||
alias: {
|
||||
|
||||
Reference in New Issue
Block a user