mirror of
https://github.com/gchq/CyberChef
synced 2026-01-07 19:13:24 +00:00
Compare commits
226 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
68e8a221ff | ||
|
|
cce84c3782 | ||
|
|
d3473a7462 | ||
|
|
6bfe4ee238 | ||
|
|
e61b7d598e | ||
|
|
eb81b9217e | ||
|
|
4d9bfcad20 | ||
|
|
2387452a56 | ||
|
|
a4772941a7 | ||
|
|
6318f78e29 | ||
|
|
5e6f3cc5b4 | ||
|
|
04f1fa06ad | ||
|
|
8d660e53b2 | ||
|
|
f3864b00fe | ||
|
|
51cc94bf2a | ||
|
|
f63d1354ba | ||
|
|
80362cfa84 | ||
|
|
447a6d7524 | ||
|
|
f022440b4a | ||
|
|
4f5e0c007d | ||
|
|
b83f6591bb | ||
|
|
77a9481cf9 | ||
|
|
a8f029309d | ||
|
|
b0df8b7dca | ||
|
|
2cc05717e6 | ||
|
|
b96394131f | ||
|
|
875c1019b2 | ||
|
|
d1a0a39efa | ||
|
|
fdfbf7ddf8 | ||
|
|
414f8b5ba9 | ||
|
|
03a1c566fc | ||
|
|
0fc1c37e65 | ||
|
|
6b4efb420e | ||
|
|
9ed2b26933 | ||
|
|
70665534b8 | ||
|
|
7244d4d343 | ||
|
|
980c1e8681 | ||
|
|
e1378860d6 | ||
|
|
b9571db9f1 | ||
|
|
734962ac22 | ||
|
|
35103bf155 | ||
|
|
4c4d7b5d26 | ||
|
|
daad633195 | ||
|
|
d5cfe9f262 | ||
|
|
a2c46b3f66 | ||
|
|
6a1d11b9b5 | ||
|
|
0630c094e0 | ||
|
|
ace71f20b3 | ||
|
|
c0e02451a1 | ||
|
|
2d12a16771 | ||
|
|
9108b3923b | ||
|
|
726e117656 | ||
|
|
ab524fff15 | ||
|
|
55eae9910f | ||
|
|
d3138a7fdf | ||
|
|
05e65a74ce | ||
|
|
6d138f345f | ||
|
|
3c165dd7e8 | ||
|
|
04561d29b5 | ||
|
|
e5e6c1a2dd | ||
|
|
882efea314 | ||
|
|
89d979d92e | ||
|
|
383aab5f85 | ||
|
|
6659174f88 | ||
|
|
3ca29b8744 | ||
|
|
726bf3345e | ||
|
|
b2d61482d5 | ||
|
|
88d8e9a7f9 | ||
|
|
0b0ddd3140 | ||
|
|
3d4f74945c | ||
|
|
4387038351 | ||
|
|
49f444dfe9 | ||
|
|
061533bb57 | ||
|
|
6e2fb67d76 | ||
|
|
60f5093c6c | ||
|
|
665f91ec37 | ||
|
|
0805a011b9 | ||
|
|
3e3322e1f0 | ||
|
|
252b1b65c4 | ||
|
|
e8b4536ec2 | ||
|
|
61d40b5a0b | ||
|
|
d175aa958c | ||
|
|
ac3c220789 | ||
|
|
add65e121a | ||
|
|
de2e757691 | ||
|
|
eb34ab4f6a | ||
|
|
08e4232166 | ||
|
|
adf9772928 | ||
|
|
562171ec86 | ||
|
|
e9e162319f | ||
|
|
17c9ffe107 | ||
|
|
1831c84a29 | ||
|
|
7e27449204 | ||
|
|
282476d530 | ||
|
|
fce0728d5d | ||
|
|
0e9ac90607 | ||
|
|
5383f56b26 | ||
|
|
a02484c6cd | ||
|
|
be365f66ef | ||
|
|
011dc09d5e | ||
|
|
fc4d6d2d2e | ||
|
|
9d73127cae | ||
|
|
223743e3b5 | ||
|
|
44ed372f21 | ||
|
|
4d1f970105 | ||
|
|
b28a891a40 | ||
|
|
834ff95702 | ||
|
|
3e93580aa4 | ||
|
|
7a3ca027bb | ||
|
|
3c021919dd | ||
|
|
2106e8ddb0 | ||
|
|
3472484601 | ||
|
|
826a8c8a74 | ||
|
|
c66703f0ca | ||
|
|
874e7d8d54 | ||
|
|
4e2b85b8c8 | ||
|
|
5314a456cb | ||
|
|
ba2a5b195c | ||
|
|
f8115671ee | ||
|
|
494279edd8 | ||
|
|
bd6673afed | ||
|
|
210daf7324 | ||
|
|
d60d595254 | ||
|
|
06708949a1 | ||
|
|
da901e20d9 | ||
|
|
c28999ec6f | ||
|
|
9872578d51 | ||
|
|
3014696fcd | ||
|
|
6b70f77dcd | ||
|
|
7f6d8bffe3 | ||
|
|
458307f5ed | ||
|
|
294aa826f1 | ||
|
|
6810f38808 | ||
|
|
087cc6b8fd | ||
|
|
10c8101476 | ||
|
|
22028b074a | ||
|
|
3d086beed2 | ||
|
|
777d814e70 | ||
|
|
15c26a95c5 | ||
|
|
f87d3bd1cb | ||
|
|
b9ea1e8c71 | ||
|
|
db232f4ff2 | ||
|
|
70f705afbc | ||
|
|
912d63067c | ||
|
|
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 | ||
|
|
de762847e9 | ||
|
|
6248e32148 | ||
|
|
52f88ee32d | ||
|
|
f8d1cf2f60 | ||
|
|
e129425d8d | ||
|
|
ae20d82e1d | ||
|
|
463b2ce040 | ||
|
|
412b47abba | ||
|
|
ed216eee73 | ||
|
|
9dd5234962 | ||
|
|
018532016b | ||
|
|
7dfecc38f6 | ||
|
|
aa5afadcce | ||
|
|
d23a584b9e | ||
|
|
572f035877 | ||
|
|
b94eb6adb0 | ||
|
|
45fccb94e1 | ||
|
|
2628f17fae | ||
|
|
69fb6e77fc | ||
|
|
950a12360e | ||
|
|
48831225ac | ||
|
|
4e8a79d8f1 | ||
|
|
82b5e97a2b | ||
|
|
7f168d49a6 | ||
|
|
8ece8ebec2 | ||
|
|
4d39c3bbd2 | ||
|
|
23ddb87c9f | ||
|
|
db662a7662 | ||
|
|
39f3383709 | ||
|
|
4f8fc8d65e | ||
|
|
0397ba857f | ||
|
|
444fb4555b | ||
|
|
294f890a92 | ||
|
|
578502187d | ||
|
|
786082a9d0 | ||
|
|
b6eb851a13 | ||
|
|
93c41f044c | ||
|
|
a7f61397f7 | ||
|
|
0f5f20247a | ||
|
|
ad571e6019 | ||
|
|
14d924f6c7 | ||
|
|
282f02f4d5 | ||
|
|
d36cede0c7 | ||
|
|
a262d70b88 | ||
|
|
77b098c5fe | ||
|
|
b491b9d77d | ||
|
|
237f792fb4 |
@@ -1,2 +1 @@
|
|||||||
src/core/vendor/**
|
src/core/vendor/**
|
||||||
src/web/static/clippy_assets/**
|
|
||||||
@@ -7,19 +7,18 @@ assignees: ''
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<!-- Prefix the title above with 'Bug report:' -->
|
|
||||||
**Describe the bug**
|
**Describe the bug**
|
||||||
A clear and concise description of what the bug is.
|
A clear and concise description of what the bug is.
|
||||||
|
|
||||||
**To Reproduce**
|
**To Reproduce**
|
||||||
Steps to reproduce the behavior or a link to the recipe / input used to cause the bug:
|
Steps to reproduce the behaviour or a link to the recipe / input used to cause the bug:
|
||||||
|
|
||||||
1. Go to '...'
|
1. Go to '...'
|
||||||
2. Click on '....'
|
2. Click on '....'
|
||||||
3. Scroll down to '....'
|
3. Scroll down to '....'
|
||||||
4. See error
|
4. See error
|
||||||
|
|
||||||
**Expected behavior**
|
**Expected behaviour**
|
||||||
A clear and concise description of what you expected to happen.
|
A clear and concise description of what you expected to happen.
|
||||||
|
|
||||||
**Screenshots**
|
**Screenshots**
|
||||||
@@ -27,9 +26,8 @@ If applicable, add screenshots to help explain your problem.
|
|||||||
|
|
||||||
**Desktop (if relevant, please complete the following information):**
|
**Desktop (if relevant, please complete the following information):**
|
||||||
- OS: [e.g. Windows]
|
- OS: [e.g. Windows]
|
||||||
- Browser [e.g. chrome, safari]
|
- Browser: [e.g. chrome 72, firefox 60]
|
||||||
- Version [e.g. 22]
|
- CyberChef version: [e.g. 9.7.14]
|
||||||
|
|
||||||
**Additional context**
|
**Additional context**
|
||||||
Add any other context about the problem here.
|
Add any other context about the problem here.
|
||||||
|
|
||||||
@@ -6,9 +6,9 @@ labels: feature
|
|||||||
assignees: ''
|
assignees: ''
|
||||||
|
|
||||||
---
|
---
|
||||||
<!-- Prefix the title above with 'Feature request:' -->
|
|
||||||
**Is your feature request related to a problem? Please describe.**
|
**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**
|
**Describe the solution you'd like**
|
||||||
A clear and concise description of what you want to happen.
|
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
|
## Summary
|
||||||
|
|
||||||
### Example Input
|
### Example Input
|
||||||
|
|||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -4,7 +4,6 @@ travis.log
|
|||||||
build
|
build
|
||||||
.vscode
|
.vscode
|
||||||
.*.swp
|
.*.swp
|
||||||
.DS_Store
|
|
||||||
src/core/config/modules/*
|
src/core/config/modules/*
|
||||||
src/core/config/OperationConfig.json
|
src/core/config/OperationConfig.json
|
||||||
src/core/operations/index.mjs
|
src/core/operations/index.mjs
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
language: node_js
|
language: node_js
|
||||||
node_js:
|
node_js:
|
||||||
- lts/*
|
- lts/dubnium
|
||||||
cache: npm
|
cache: npm
|
||||||
addons:
|
addons:
|
||||||
chrome: stable
|
chrome: stable
|
||||||
|
|||||||
48
CHANGELOG.md
48
CHANGELOG.md
@@ -2,6 +2,33 @@
|
|||||||
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).
|
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.11.0] - 2019-11-06
|
||||||
|
- Implemented CFB, OFB, and CTR modes for Blowfish operations [@cbeuw] | [#653]
|
||||||
|
|
||||||
|
### [9.10.0] - 2019-11-06
|
||||||
|
- 'Lorenz' operation added [@VirtualColossus] | [#528]
|
||||||
|
|
||||||
|
### [9.9.0] - 2019-11-01
|
||||||
|
- Added support for 109 more character encodings [@n1474335]
|
||||||
|
|
||||||
|
### [9.8.0] - 2019-10-31
|
||||||
|
- 'Avro to JSON' operation added [@jarrodconnolly] | [#865]
|
||||||
|
|
||||||
|
### [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]
|
||||||
|
|
||||||
|
### [9.3.0] - 2019-08-30
|
||||||
|
- 'Show on map' operation added [@j433866] | [#477]
|
||||||
|
|
||||||
### [9.2.0] - 2019-08-23
|
### [9.2.0] - 2019-08-23
|
||||||
- 'Parse UDP' operation added [@h345983745] | [#614]
|
- 'Parse UDP' operation added [@h345983745] | [#614]
|
||||||
|
|
||||||
@@ -170,6 +197,15 @@ All major and minor version changes will be documented in this file. Details of
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[9.11.0]: https://github.com/gchq/CyberChef/releases/tag/v9.11.0
|
||||||
|
[9.10.0]: https://github.com/gchq/CyberChef/releases/tag/v9.10.0
|
||||||
|
[9.9.0]: https://github.com/gchq/CyberChef/releases/tag/v9.9.0
|
||||||
|
[9.8.0]: https://github.com/gchq/CyberChef/releases/tag/v9.8.0
|
||||||
|
[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
|
[9.2.0]: https://github.com/gchq/CyberChef/releases/tag/v9.2.0
|
||||||
[9.1.0]: https://github.com/gchq/CyberChef/releases/tag/v9.1.0
|
[9.1.0]: https://github.com/gchq/CyberChef/releases/tag/v9.1.0
|
||||||
[9.0.0]: https://github.com/gchq/CyberChef/releases/tag/v9.0.0
|
[9.0.0]: https://github.com/gchq/CyberChef/releases/tag/v9.0.0
|
||||||
@@ -241,6 +277,10 @@ All major and minor version changes will be documented in this file. Details of
|
|||||||
[@masq]: https://github.com/masq
|
[@masq]: https://github.com/masq
|
||||||
[@Ge0rg3]: https://github.com/Ge0rg3
|
[@Ge0rg3]: https://github.com/Ge0rg3
|
||||||
[@MShwed]: https://github.com/MShwed
|
[@MShwed]: https://github.com/MShwed
|
||||||
|
[@kassi]: https://github.com/kassi
|
||||||
|
[@jarrodconnolly]: https://github.com/jarrodconnolly
|
||||||
|
[@VirtualColossus]: https://github.com/VirtualColossus
|
||||||
|
[@cbeuw]: https://github.com/cbeuw
|
||||||
|
|
||||||
[#95]: https://github.com/gchq/CyberChef/pull/299
|
[#95]: https://github.com/gchq/CyberChef/pull/299
|
||||||
[#173]: https://github.com/gchq/CyberChef/pull/173
|
[#173]: https://github.com/gchq/CyberChef/pull/173
|
||||||
@@ -279,12 +319,15 @@ All major and minor version changes will be documented in this file. Details of
|
|||||||
[#467]: https://github.com/gchq/CyberChef/pull/467
|
[#467]: https://github.com/gchq/CyberChef/pull/467
|
||||||
[#468]: https://github.com/gchq/CyberChef/pull/468
|
[#468]: https://github.com/gchq/CyberChef/pull/468
|
||||||
[#476]: https://github.com/gchq/CyberChef/pull/476
|
[#476]: https://github.com/gchq/CyberChef/pull/476
|
||||||
|
[#477]: https://github.com/gchq/CyberChef/pull/477
|
||||||
[#489]: https://github.com/gchq/CyberChef/pull/489
|
[#489]: https://github.com/gchq/CyberChef/pull/489
|
||||||
[#496]: https://github.com/gchq/CyberChef/pull/496
|
[#496]: https://github.com/gchq/CyberChef/pull/496
|
||||||
|
[#500]: https://github.com/gchq/CyberChef/pull/500
|
||||||
[#506]: https://github.com/gchq/CyberChef/pull/506
|
[#506]: https://github.com/gchq/CyberChef/pull/506
|
||||||
[#515]: https://github.com/gchq/CyberChef/pull/515
|
[#515]: https://github.com/gchq/CyberChef/pull/515
|
||||||
[#516]: https://github.com/gchq/CyberChef/pull/516
|
[#516]: https://github.com/gchq/CyberChef/pull/516
|
||||||
[#525]: https://github.com/gchq/CyberChef/pull/525
|
[#525]: https://github.com/gchq/CyberChef/pull/525
|
||||||
|
[#528]: https://github.com/gchq/CyberChef/pull/528
|
||||||
[#530]: https://github.com/gchq/CyberChef/pull/530
|
[#530]: https://github.com/gchq/CyberChef/pull/530
|
||||||
[#531]: https://github.com/gchq/CyberChef/pull/531
|
[#531]: https://github.com/gchq/CyberChef/pull/531
|
||||||
[#533]: https://github.com/gchq/CyberChef/pull/533
|
[#533]: https://github.com/gchq/CyberChef/pull/533
|
||||||
@@ -296,3 +339,8 @@ All major and minor version changes will be documented in this file. Details of
|
|||||||
[#591]: https://github.com/gchq/CyberChef/pull/591
|
[#591]: https://github.com/gchq/CyberChef/pull/591
|
||||||
[#595]: https://github.com/gchq/CyberChef/pull/595
|
[#595]: https://github.com/gchq/CyberChef/pull/595
|
||||||
[#614]: https://github.com/gchq/CyberChef/pull/614
|
[#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
|
||||||
|
[#653]: https://github.com/gchq/CyberChef/pull/653
|
||||||
|
[#865]: https://github.com/gchq/CyberChef/pull/865
|
||||||
|
|||||||
61
Gruntfile.js
61
Gruntfile.js
@@ -14,7 +14,6 @@ const path = require("path");
|
|||||||
* @license Apache-2.0
|
* @license Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
module.exports = function (grunt) {
|
module.exports = function (grunt) {
|
||||||
grunt.file.defaultEncoding = "utf8";
|
grunt.file.defaultEncoding = "utf8";
|
||||||
grunt.file.preserveBOM = false;
|
grunt.file.preserveBOM = false;
|
||||||
@@ -102,6 +101,26 @@ module.exports = function (grunt) {
|
|||||||
return entryModules;
|
return entryModules;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detects the correct delimiter to use to chain shell commands together
|
||||||
|
* based on the current OS.
|
||||||
|
*
|
||||||
|
* @param {string[]} cmds
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
function chainCommands(cmds) {
|
||||||
|
const win = process.platform === "win32";
|
||||||
|
if (!win) {
|
||||||
|
return cmds.join(";");
|
||||||
|
}
|
||||||
|
return cmds
|
||||||
|
// && means that subsequent commands will not be executed if the
|
||||||
|
// previous one fails. & would coninue on a fail
|
||||||
|
.join("&&")
|
||||||
|
// Windows does not support \n properly
|
||||||
|
.replace("\n", "\\n");
|
||||||
|
}
|
||||||
|
|
||||||
grunt.initConfig({
|
grunt.initConfig({
|
||||||
clean: {
|
clean: {
|
||||||
dev: ["build/dev/*"],
|
dev: ["build/dev/*"],
|
||||||
@@ -140,8 +159,7 @@ module.exports = function (grunt) {
|
|||||||
mode: "production",
|
mode: "production",
|
||||||
target: "web",
|
target: "web",
|
||||||
entry: Object.assign({
|
entry: Object.assign({
|
||||||
main: "./src/web/index.js",
|
main: "./src/web/index.js"
|
||||||
sitemap: "./src/web/static/sitemap.js"
|
|
||||||
}, moduleEntryPoints),
|
}, moduleEntryPoints),
|
||||||
output: {
|
output: {
|
||||||
path: __dirname + "/build/prod",
|
path: __dirname + "/build/prod",
|
||||||
@@ -232,7 +250,6 @@ module.exports = function (grunt) {
|
|||||||
"build/prod/**/*",
|
"build/prod/**/*",
|
||||||
"!build/prod/index.html",
|
"!build/prod/index.html",
|
||||||
"!build/prod/BundleAnalyzerReport.html",
|
"!build/prod/BundleAnalyzerReport.html",
|
||||||
"!build/prod/sitemap.js"
|
|
||||||
],
|
],
|
||||||
dest: `build/prod/CyberChef_v${pkg.version}.zip`
|
dest: `build/prod/CyberChef_v${pkg.version}.zip`
|
||||||
}
|
}
|
||||||
@@ -318,33 +335,33 @@ module.exports = function (grunt) {
|
|||||||
},
|
},
|
||||||
exec: {
|
exec: {
|
||||||
repoSize: {
|
repoSize: {
|
||||||
command: [
|
command: chainCommands([
|
||||||
"git ls-files | wc -l | xargs printf '\n%b\ttracked files\n'",
|
"git ls-files | wc -l | xargs printf '\n%b\ttracked files\n'",
|
||||||
"du -hs | egrep -o '^[^\t]*' | xargs printf '%b\trepository size\n'"
|
"du -hs | egrep -o '^[^\t]*' | xargs printf '%b\trepository size\n'"
|
||||||
].join(";"),
|
]),
|
||||||
stderr: false
|
stderr: false
|
||||||
},
|
},
|
||||||
cleanGit: {
|
cleanGit: {
|
||||||
command: "git gc --prune=now --aggressive"
|
command: "git gc --prune=now --aggressive"
|
||||||
},
|
},
|
||||||
sitemap: {
|
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: {
|
generateConfig: {
|
||||||
command: [
|
command: chainCommands([
|
||||||
"echo '\n--- Regenerating config files. ---'",
|
"echo '\n--- Regenerating config files. ---'",
|
||||||
"echo [] > src/core/config/OperationConfig.json",
|
"echo [] > src/core/config/OperationConfig.json",
|
||||||
"node --experimental-modules --no-warnings --no-deprecation src/core/config/scripts/generateOpsIndex.mjs",
|
"node --experimental-modules --no-warnings --no-deprecation src/core/config/scripts/generateOpsIndex.mjs",
|
||||||
"node --experimental-modules --no-warnings --no-deprecation src/core/config/scripts/generateConfig.mjs",
|
"node --experimental-modules --no-warnings --no-deprecation src/core/config/scripts/generateConfig.mjs",
|
||||||
"echo '--- Config scripts finished. ---\n'"
|
"echo '--- Config scripts finished. ---\n'"
|
||||||
].join(";")
|
])
|
||||||
},
|
},
|
||||||
generateNodeIndex: {
|
generateNodeIndex: {
|
||||||
command: [
|
command: chainCommands([
|
||||||
"echo '\n--- Regenerating node index ---'",
|
"echo '\n--- Regenerating node index ---'",
|
||||||
"node --experimental-modules --no-warnings --no-deprecation src/node/config/scripts/generateNodeIndex.mjs",
|
"node --experimental-modules --no-warnings --no-deprecation src/node/config/scripts/generateNodeIndex.mjs",
|
||||||
"echo '--- Node index generated. ---\n'"
|
"echo '--- Node index generated. ---\n'"
|
||||||
].join(";"),
|
]),
|
||||||
},
|
},
|
||||||
opTests: {
|
opTests: {
|
||||||
command: "node --experimental-modules --no-warnings --no-deprecation tests/operations/index.mjs"
|
command: "node --experimental-modules --no-warnings --no-deprecation tests/operations/index.mjs"
|
||||||
@@ -356,40 +373,40 @@ module.exports = function (grunt) {
|
|||||||
command: "node --experimental-modules --no-warnings --no-deprecation tests/node/index.mjs"
|
command: "node --experimental-modules --no-warnings --no-deprecation tests/node/index.mjs"
|
||||||
},
|
},
|
||||||
setupNodeConsumers: {
|
setupNodeConsumers: {
|
||||||
command: [
|
command: chainCommands([
|
||||||
"echo '\n--- Testing node conumers ---'",
|
"echo '\n--- Testing node consumers ---'",
|
||||||
"npm link",
|
"npm link",
|
||||||
`mkdir ${nodeConsumerTestPath}`,
|
`mkdir ${nodeConsumerTestPath}`,
|
||||||
`cp tests/node/consumers/* ${nodeConsumerTestPath}`,
|
`cp tests/node/consumers/* ${nodeConsumerTestPath}`,
|
||||||
`cd ${nodeConsumerTestPath}`,
|
`cd ${nodeConsumerTestPath}`,
|
||||||
"npm link cyberchef"
|
"npm link cyberchef"
|
||||||
].join(";"),
|
]),
|
||||||
},
|
},
|
||||||
teardownNodeConsumers: {
|
teardownNodeConsumers: {
|
||||||
command: [
|
command: chainCommands([
|
||||||
`rm -rf ${nodeConsumerTestPath}`,
|
`rm -rf ${nodeConsumerTestPath}`,
|
||||||
"echo '\n--- Node consumer tests complete ---'"
|
"echo '\n--- Node consumer tests complete ---'"
|
||||||
].join(";"),
|
]),
|
||||||
},
|
},
|
||||||
testCJSNodeConsumer: {
|
testCJSNodeConsumer: {
|
||||||
command: [
|
command: chainCommands([
|
||||||
`cd ${nodeConsumerTestPath}`,
|
`cd ${nodeConsumerTestPath}`,
|
||||||
"node --no-warnings cjs-consumer.js",
|
"node --no-warnings cjs-consumer.js",
|
||||||
].join(";"),
|
]),
|
||||||
stdout: false,
|
stdout: false,
|
||||||
},
|
},
|
||||||
testESMNodeConsumer: {
|
testESMNodeConsumer: {
|
||||||
command: [
|
command: chainCommands([
|
||||||
`cd ${nodeConsumerTestPath}`,
|
`cd ${nodeConsumerTestPath}`,
|
||||||
"node --no-warnings --experimental-modules esm-consumer.mjs",
|
"node --no-warnings --experimental-modules esm-consumer.mjs",
|
||||||
].join(";"),
|
]),
|
||||||
stdout: false,
|
stdout: false,
|
||||||
},
|
},
|
||||||
testESMDeepImportNodeConsumer: {
|
testESMDeepImportNodeConsumer: {
|
||||||
command: [
|
command: chainCommands([
|
||||||
`cd ${nodeConsumerTestPath}`,
|
`cd ${nodeConsumerTestPath}`,
|
||||||
"node --no-warnings --experimental-modules esm-deep-import-consumer.mjs",
|
"node --no-warnings --experimental-modules esm-deep-import-consumer.mjs",
|
||||||
].join(";"),
|
]),
|
||||||
stdout: false,
|
stdout: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
10
README.md
10
README.md
@@ -69,7 +69,15 @@ You can use as many operations as you like in simple or complex ways. Some examp
|
|||||||
- You can save the output to a file at any time or load a file by dragging and dropping it into the input field. Files up to around 2GB are supported (depending on your browser), however some operations may take a very long time to run over this much data.
|
- You can save the output to a file at any time or load a file by dragging and dropping it into the input field. Files up to around 2GB are supported (depending on your browser), however some operations may take a very long time to run over this much data.
|
||||||
- CyberChef is entirely client-side
|
- CyberChef is entirely client-side
|
||||||
- It should be noted that none of your recipe configuration or input (either text or files) is ever sent to the CyberChef web server - all processing is carried out within your browser, on your own computer.
|
- It should be noted that none of your recipe configuration or input (either text or files) is ever sent to the CyberChef web server - all processing is carried out within your browser, on your own computer.
|
||||||
- Due to this feature, CyberChef can be compiled into a single HTML file. You can download this file and drop it into a virtual machine, share it with other people, or use it independently on your local machine.
|
- Due to this feature, CyberChef can be downloaded and run locally. You can use the link in the top left corner of the app to download a full copy of CyberChef and drop it into a virtual machine, share it with other people, or host it in a closed network.
|
||||||
|
|
||||||
|
|
||||||
|
## Deep linking
|
||||||
|
|
||||||
|
By manipulation of CyberChef's URL hash, you can change the initial settings with which the page opens.
|
||||||
|
The format is `https://gchq.github.io/CyberChef/#recipe=Operation()&input=...`
|
||||||
|
|
||||||
|
Supported arguments are `recipe`, `input` (encoded in Base64), and `theme`.
|
||||||
|
|
||||||
|
|
||||||
## Browser support
|
## Browser support
|
||||||
|
|||||||
2681
package-lock.json
generated
2681
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
71
package.json
71
package.json
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "cyberchef",
|
"name": "cyberchef",
|
||||||
"version": "9.2.3",
|
"version": "9.11.3",
|
||||||
"description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.",
|
"description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.",
|
||||||
"author": "n1474335 <n1474335@gmail.com>",
|
"author": "n1474335 <n1474335@gmail.com>",
|
||||||
"homepage": "https://gchq.github.io/CyberChef",
|
"homepage": "https://gchq.github.io/CyberChef",
|
||||||
@@ -36,19 +36,20 @@
|
|||||||
"node >= 10"
|
"node >= 10"
|
||||||
],
|
],
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.5.0",
|
"@babel/core": "^7.5.5",
|
||||||
"@babel/plugin-transform-runtime": "^7.5.0",
|
"@babel/plugin-transform-runtime": "^7.5.5",
|
||||||
"@babel/preset-env": "^7.5.0",
|
"@babel/preset-env": "^7.5.5",
|
||||||
"autoprefixer": "^9.6.0",
|
"autoprefixer": "^9.6.1",
|
||||||
"babel-eslint": "^10.0.2",
|
"babel-eslint": "^10.0.3",
|
||||||
"babel-loader": "^8.0.6",
|
"babel-loader": "^8.0.6",
|
||||||
"babel-plugin-dynamic-import-node": "^2.2.0",
|
"babel-plugin-dynamic-import-node": "^2.3.0",
|
||||||
"chromedriver": "^75.0.1",
|
"chromedriver": "^77.0.0",
|
||||||
"colors": "^1.3.3",
|
"colors": "^1.3.3",
|
||||||
"css-loader": "^3.0.0",
|
"copy-webpack-plugin": "^5.0.4",
|
||||||
"eslint": "^6.0.1",
|
"css-loader": "^3.2.0",
|
||||||
|
"eslint": "^6.2.2",
|
||||||
"exports-loader": "^0.7.0",
|
"exports-loader": "^0.7.0",
|
||||||
"file-loader": "^4.0.0",
|
"file-loader": "^4.2.0",
|
||||||
"grunt": "^1.0.4",
|
"grunt": "^1.0.4",
|
||||||
"grunt-accessibility": "~6.0.0",
|
"grunt-accessibility": "~6.0.0",
|
||||||
"grunt-chmod": "~1.1.1",
|
"grunt-chmod": "~1.1.1",
|
||||||
@@ -63,28 +64,29 @@
|
|||||||
"grunt-zip": "^0.18.2",
|
"grunt-zip": "^0.18.2",
|
||||||
"html-webpack-plugin": "^3.2.0",
|
"html-webpack-plugin": "^3.2.0",
|
||||||
"imports-loader": "^0.8.0",
|
"imports-loader": "^0.8.0",
|
||||||
"mini-css-extract-plugin": "^0.7.0",
|
"mini-css-extract-plugin": "^0.8.0",
|
||||||
"nightwatch": "^1.1.13",
|
"nightwatch": "^1.2.1",
|
||||||
"node-sass": "^4.12.0",
|
"node-sass": "^4.12.0",
|
||||||
"postcss-css-variables": "^0.13.0",
|
"postcss-css-variables": "^0.13.0",
|
||||||
"postcss-import": "^12.0.1",
|
"postcss-import": "^12.0.1",
|
||||||
"postcss-loader": "^3.0.0",
|
"postcss-loader": "^3.0.0",
|
||||||
"prompt": "^1.0.0",
|
"prompt": "^1.0.0",
|
||||||
"sass-loader": "^7.1.0",
|
"sass-loader": "^8.0.0",
|
||||||
"sitemap": "^3.2.0",
|
"sitemap": "^4.1.1",
|
||||||
"style-loader": "^0.23.1",
|
"style-loader": "^1.0.0",
|
||||||
"svg-url-loader": "^3.0.0",
|
"svg-url-loader": "^3.0.1",
|
||||||
"url-loader": "^2.0.1",
|
"url-loader": "^2.1.0",
|
||||||
"webpack": "^4.35.2",
|
"webpack": "^4.39.3",
|
||||||
"webpack-bundle-analyzer": "^3.3.2",
|
"webpack-bundle-analyzer": "^3.4.1",
|
||||||
"webpack-dev-server": "^3.7.2",
|
"webpack-dev-server": "^3.8.0",
|
||||||
"webpack-node-externals": "^1.7.2",
|
"webpack-node-externals": "^1.7.2",
|
||||||
"worker-loader": "^2.0.0"
|
"worker-loader": "^2.0.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/polyfill": "^7.4.4",
|
"@babel/polyfill": "^7.4.4",
|
||||||
"@babel/runtime": "^7.5.0",
|
"@babel/runtime": "^7.5.5",
|
||||||
"arrive": "^2.4.1",
|
"arrive": "^2.4.1",
|
||||||
|
"avsc": "^5.4.16",
|
||||||
"babel-plugin-transform-builtin-extend": "1.1.2",
|
"babel-plugin-transform-builtin-extend": "1.1.2",
|
||||||
"bcryptjs": "^2.4.3",
|
"bcryptjs": "^2.4.3",
|
||||||
"bignumber.js": "^9.0.0",
|
"bignumber.js": "^9.0.0",
|
||||||
@@ -94,23 +96,23 @@
|
|||||||
"bootstrap-material-design": "^4.1.2",
|
"bootstrap-material-design": "^4.1.2",
|
||||||
"bson": "^4.0.2",
|
"bson": "^4.0.2",
|
||||||
"chi-squared": "^1.1.0",
|
"chi-squared": "^1.1.0",
|
||||||
"clippyjs": "0.0.3",
|
"codepage": "^1.14.0",
|
||||||
"core-js": "^3.1.4",
|
"core-js": "^3.2.1",
|
||||||
"crypto-api": "^0.8.3",
|
"crypto-api": "^0.8.5",
|
||||||
"crypto-js": "^3.1.9-1",
|
"crypto-js": "^3.1.9-1",
|
||||||
"ctph.js": "0.0.5",
|
"ctph.js": "0.0.5",
|
||||||
"d3": "^5.9.7",
|
"d3": "^5.11.0",
|
||||||
"d3-hexbin": "^0.2.2",
|
"d3-hexbin": "^0.2.2",
|
||||||
"diff": "^4.0.1",
|
"diff": "^4.0.1",
|
||||||
"es6-promisify": "^6.0.1",
|
"es6-promisify": "^6.0.2",
|
||||||
"escodegen": "^1.11.1",
|
"escodegen": "^1.12.0",
|
||||||
"esm": "^3.2.25",
|
"esm": "^3.2.25",
|
||||||
"esmangle": "^1.0.1",
|
"esmangle": "^1.0.1",
|
||||||
"esprima": "^4.0.1",
|
"esprima": "^4.0.1",
|
||||||
"exif-parser": "^0.1.12",
|
"exif-parser": "^0.1.12",
|
||||||
"file-saver": "^2.0.2",
|
"file-saver": "^2.0.2",
|
||||||
"geodesy": "^1.1.3",
|
"geodesy": "^1.1.3",
|
||||||
"highlight.js": "^9.15.8",
|
"highlight.js": "^9.15.10",
|
||||||
"jimp": "^0.6.4",
|
"jimp": "^0.6.4",
|
||||||
"jquery": "3.4.1",
|
"jquery": "3.4.1",
|
||||||
"js-crc": "^0.2.0",
|
"js-crc": "^0.2.0",
|
||||||
@@ -120,16 +122,17 @@
|
|||||||
"jsonwebtoken": "^8.5.1",
|
"jsonwebtoken": "^8.5.1",
|
||||||
"jsqr": "^1.2.0",
|
"jsqr": "^1.2.0",
|
||||||
"jsrsasign": "8.0.12",
|
"jsrsasign": "8.0.12",
|
||||||
"kbpgp": "2.1.2",
|
"kbpgp": "2.1.3",
|
||||||
"libbzip2-wasm": "0.0.4",
|
"libbzip2-wasm": "0.0.4",
|
||||||
"libyara-wasm": "0.0.12",
|
"libyara-wasm": "^1.0.1",
|
||||||
"lodash": "^4.17.15",
|
"lodash": "^4.17.15",
|
||||||
"loglevel": "^1.6.3",
|
"loglevel": "^1.6.3",
|
||||||
"loglevel-message-prefix": "^3.0.0",
|
"loglevel-message-prefix": "^3.0.0",
|
||||||
|
"markdown-it": "^9.1.0",
|
||||||
"moment": "^2.24.0",
|
"moment": "^2.24.0",
|
||||||
"moment-timezone": "^0.5.25",
|
"moment-timezone": "^0.5.26",
|
||||||
"ngeohash": "^0.6.3",
|
"ngeohash": "^0.6.3",
|
||||||
"node-forge": "^0.8.5",
|
"node-forge": "^0.9.1",
|
||||||
"node-md6": "^0.1.0",
|
"node-md6": "^0.1.0",
|
||||||
"nodom": "^2.2.0",
|
"nodom": "^2.2.0",
|
||||||
"notepack.io": "^2.2.0",
|
"notepack.io": "^2.2.0",
|
||||||
@@ -142,6 +145,7 @@
|
|||||||
"sortablejs": "^1.9.0",
|
"sortablejs": "^1.9.0",
|
||||||
"split.js": "^1.5.11",
|
"split.js": "^1.5.11",
|
||||||
"ssdeep.js": "0.0.2",
|
"ssdeep.js": "0.0.2",
|
||||||
|
"tesseract.js": "^2.0.0-alpha.15",
|
||||||
"ua-parser-js": "^0.7.20",
|
"ua-parser-js": "^0.7.20",
|
||||||
"utf8": "^3.0.0",
|
"utf8": "^3.0.0",
|
||||||
"vkbeautify": "^0.99.3",
|
"vkbeautify": "^0.99.3",
|
||||||
@@ -157,6 +161,7 @@
|
|||||||
"test": "grunt test",
|
"test": "grunt test",
|
||||||
"test-node-consumer": "grunt testnodeconsumer",
|
"test-node-consumer": "grunt testnodeconsumer",
|
||||||
"testui": "grunt testui",
|
"testui": "grunt testui",
|
||||||
|
"testuidev": "npx nightwatch --env=dev",
|
||||||
"lint": "grunt lint",
|
"lint": "grunt lint",
|
||||||
"newop": "node --experimental-modules src/core/config/scripts/newOperation.mjs"
|
"newop": "node --experimental-modules src/core/config/scripts/newOperation.mjs"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -129,7 +129,7 @@ class Dish {
|
|||||||
*
|
*
|
||||||
* @param {number} type - The data type of value, see Dish enums.
|
* @param {number} type - The data type of value, see Dish enums.
|
||||||
* @param {boolean} [notUTF8=false] - Do not treat strings as UTF8.
|
* @param {boolean} [notUTF8=false] - Do not treat strings as UTF8.
|
||||||
* @returns {* | Promise} - (Broswer) A promise | (Node) value of dish in given type
|
* @returns {* | Promise} - (Browser) A promise | (Node) value of dish in given type
|
||||||
*/
|
*/
|
||||||
get(type, notUTF8=false) {
|
get(type, notUTF8=false) {
|
||||||
if (typeof type === "string") {
|
if (typeof type === "string") {
|
||||||
@@ -177,7 +177,7 @@ class Dish {
|
|||||||
this.type = type;
|
this.type = type;
|
||||||
|
|
||||||
if (!this.valid()) {
|
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}`);
|
throw new DishError(`Data is not a valid ${Dish.enumLookup(type)}: ${sample}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -191,7 +191,7 @@ class Dish {
|
|||||||
*
|
*
|
||||||
* @param {number} type - The data type of value, see Dish enums.
|
* @param {number} type - The data type of value, see Dish enums.
|
||||||
* @param {boolean} [notUTF8=false] - Do not treat strings as UTF8.
|
* @param {boolean} [notUTF8=false] - Do not treat strings as UTF8.
|
||||||
* @returns {Dish | Promise} - (Broswer) A promise | (Node) value of dish in given type
|
* @returns {Dish | Promise} - (Browser) A promise | (Node) value of dish in given type
|
||||||
*/
|
*/
|
||||||
presentAs(type, notUTF8=false) {
|
presentAs(type, notUTF8=false) {
|
||||||
const clone = this.clone();
|
const clone = this.clone();
|
||||||
|
|||||||
@@ -201,9 +201,8 @@ class Utils {
|
|||||||
* Utils.parseEscapedChars("\\n");
|
* Utils.parseEscapedChars("\\n");
|
||||||
*/
|
*/
|
||||||
static parseEscapedChars(str) {
|
static parseEscapedChars(str) {
|
||||||
return str.replace(/(\\)?\\([bfnrtv'"]|[0-3][0-7]{2}|[0-7]{1,2}|x[\da-fA-F]{2}|u[\da-fA-F]{4}|u\{[\da-fA-F]{1,6}\}|\\)/g, function(m, a, b) {
|
return str.replace(/\\([bfnrtv'"]|[0-3][0-7]{2}|[0-7]{1,2}|x[\da-fA-F]{2}|u[\da-fA-F]{4}|u\{[\da-fA-F]{1,6}\}|\\)/g, function(m, a) {
|
||||||
if (a === "\\") return "\\"+b;
|
switch (a[0]) {
|
||||||
switch (b[0]) {
|
|
||||||
case "\\":
|
case "\\":
|
||||||
return "\\";
|
return "\\";
|
||||||
case "0":
|
case "0":
|
||||||
@@ -214,7 +213,7 @@ class Utils {
|
|||||||
case "5":
|
case "5":
|
||||||
case "6":
|
case "6":
|
||||||
case "7":
|
case "7":
|
||||||
return String.fromCharCode(parseInt(b, 8));
|
return String.fromCharCode(parseInt(a, 8));
|
||||||
case "b":
|
case "b":
|
||||||
return "\b";
|
return "\b";
|
||||||
case "t":
|
case "t":
|
||||||
@@ -232,12 +231,12 @@ class Utils {
|
|||||||
case "'":
|
case "'":
|
||||||
return "'";
|
return "'";
|
||||||
case "x":
|
case "x":
|
||||||
return String.fromCharCode(parseInt(b.substr(1), 16));
|
return String.fromCharCode(parseInt(a.substr(1), 16));
|
||||||
case "u":
|
case "u":
|
||||||
if (b[1] === "{")
|
if (a[1] === "{")
|
||||||
return String.fromCodePoint(parseInt(b.slice(2, -1), 16));
|
return String.fromCodePoint(parseInt(a.slice(2, -1), 16));
|
||||||
else
|
else
|
||||||
return String.fromCharCode(parseInt(b.substr(1), 16));
|
return String.fromCharCode(parseInt(a.substr(1), 16));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -1303,6 +1302,30 @@ export function sendStatusMessage(msg) {
|
|||||||
console.debug(msg);
|
console.debug(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const debounceTimeouts = {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Debouncer to stop functions from being executed multiple times in a
|
||||||
|
* short space of time
|
||||||
|
* https://davidwalsh.name/javascript-debounce-function
|
||||||
|
*
|
||||||
|
* @param {function} func - The function to be executed after the debounce time
|
||||||
|
* @param {number} wait - The time (ms) to wait before executing the function
|
||||||
|
* @param {string} id - Unique ID to reference the timeout for the function
|
||||||
|
* @param {object} scope - The object to bind to the debounced function
|
||||||
|
* @param {array} args - Array of arguments to be passed to func
|
||||||
|
* @returns {function}
|
||||||
|
*/
|
||||||
|
export function debounce(func, wait, id, scope, args) {
|
||||||
|
return function() {
|
||||||
|
const later = function() {
|
||||||
|
func.apply(scope, args);
|
||||||
|
};
|
||||||
|
clearTimeout(debounceTimeouts[id]);
|
||||||
|
debounceTimeouts[id] = setTimeout(later, wait);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Polyfills
|
* Polyfills
|
||||||
|
|||||||
@@ -59,7 +59,8 @@
|
|||||||
"From Braille",
|
"From Braille",
|
||||||
"Parse TLV",
|
"Parse TLV",
|
||||||
"CSV to JSON",
|
"CSV to JSON",
|
||||||
"JSON to CSV"
|
"JSON to CSV",
|
||||||
|
"Avro to JSON"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -85,6 +86,8 @@
|
|||||||
"Vigenère Decode",
|
"Vigenère Decode",
|
||||||
"To Morse Code",
|
"To Morse Code",
|
||||||
"From Morse Code",
|
"From Morse Code",
|
||||||
|
"Bacon Cipher Encode",
|
||||||
|
"Bacon Cipher Decode",
|
||||||
"Bifid Cipher Encode",
|
"Bifid Cipher Encode",
|
||||||
"Bifid Cipher Decode",
|
"Bifid Cipher Decode",
|
||||||
"Affine Cipher Encode",
|
"Affine Cipher Encode",
|
||||||
@@ -106,7 +109,8 @@
|
|||||||
"Enigma",
|
"Enigma",
|
||||||
"Bombe",
|
"Bombe",
|
||||||
"Multiple Bombe",
|
"Multiple Bombe",
|
||||||
"Typex"
|
"Typex",
|
||||||
|
"Lorenz"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -121,6 +125,7 @@
|
|||||||
"Generate PGP Key Pair",
|
"Generate PGP Key Pair",
|
||||||
"PGP Encrypt",
|
"PGP Encrypt",
|
||||||
"PGP Decrypt",
|
"PGP Decrypt",
|
||||||
|
"PGP Verify",
|
||||||
"PGP Encrypt and Sign",
|
"PGP Encrypt and Sign",
|
||||||
"PGP Decrypt and Verify",
|
"PGP Decrypt and Verify",
|
||||||
"Parse SSH Host Key"
|
"Parse SSH Host Key"
|
||||||
@@ -228,6 +233,7 @@
|
|||||||
"Convert speed",
|
"Convert speed",
|
||||||
"Convert data units",
|
"Convert data units",
|
||||||
"Convert co-ordinate format",
|
"Convert co-ordinate format",
|
||||||
|
"Show on map",
|
||||||
"Parse UNIX file permissions",
|
"Parse UNIX file permissions",
|
||||||
"Swap endianness",
|
"Swap endianness",
|
||||||
"Parse colour code",
|
"Parse colour code",
|
||||||
@@ -281,6 +287,7 @@
|
|||||||
"Zip",
|
"Zip",
|
||||||
"Unzip",
|
"Unzip",
|
||||||
"Bzip2 Decompress",
|
"Bzip2 Decompress",
|
||||||
|
"Bzip2 Compress",
|
||||||
"Tar",
|
"Tar",
|
||||||
"Untar"
|
"Untar"
|
||||||
]
|
]
|
||||||
@@ -357,7 +364,8 @@
|
|||||||
"BSON serialise",
|
"BSON serialise",
|
||||||
"BSON deserialise",
|
"BSON deserialise",
|
||||||
"To MessagePack",
|
"To MessagePack",
|
||||||
"From MessagePack"
|
"From MessagePack",
|
||||||
|
"Render Markdown"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -366,8 +374,13 @@
|
|||||||
"Detect File Type",
|
"Detect File Type",
|
||||||
"Scan for Embedded Files",
|
"Scan for Embedded Files",
|
||||||
"Extract Files",
|
"Extract Files",
|
||||||
|
"YARA Rules",
|
||||||
"Remove EXIF",
|
"Remove EXIF",
|
||||||
"Extract EXIF"
|
"Extract EXIF",
|
||||||
|
"Extract RGBA",
|
||||||
|
"View Bit Plane",
|
||||||
|
"Randomize Colour Palette",
|
||||||
|
"Extract LSB"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -375,6 +388,7 @@
|
|||||||
"ops": [
|
"ops": [
|
||||||
"Render Image",
|
"Render Image",
|
||||||
"Play Media",
|
"Play Media",
|
||||||
|
"Optical Character Recognition",
|
||||||
"Remove EXIF",
|
"Remove EXIF",
|
||||||
"Extract EXIF",
|
"Extract EXIF",
|
||||||
"Split Colour Channels",
|
"Split Colour Channels",
|
||||||
@@ -392,6 +406,7 @@
|
|||||||
"Cover Image",
|
"Cover Image",
|
||||||
"Image Hue/Saturation/Lightness",
|
"Image Hue/Saturation/Lightness",
|
||||||
"Sharpen Image",
|
"Sharpen Image",
|
||||||
|
"Normalise Image",
|
||||||
"Convert Image Format",
|
"Convert Image Format",
|
||||||
"Add Text To Image",
|
"Add Text To Image",
|
||||||
"Hex Density chart",
|
"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,
|
||||||
|
};
|
||||||
@@ -22,7 +22,7 @@ export const ENCODING_SCHEME = [
|
|||||||
/**
|
/**
|
||||||
* Lookup table for the binary value of each digit representation.
|
* Lookup table for the binary value of each digit representation.
|
||||||
*
|
*
|
||||||
* I wrote a very nice algorithm to generate 8 4 2 1 encoding programatically,
|
* I wrote a very nice algorithm to generate 8 4 2 1 encoding programmatically,
|
||||||
* but unfortunately it's much easier (if less elegant) to use lookup tables
|
* but unfortunately it's much easier (if less elegant) to use lookup tables
|
||||||
* when supporting multiple encoding schemes.
|
* when supporting multiple encoding schemes.
|
||||||
*
|
*
|
||||||
|
|||||||
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 Utils from "../Utils.mjs";
|
||||||
|
import OperationError from "../errors/OperationError.mjs";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base64's the input byte array using the given alphabet, returning a string.
|
* 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+/="]
|
* @param {string} [alphabet="A-Za-z0-9+/="]
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
*
|
*
|
||||||
@@ -25,11 +25,17 @@ import Utils from "../Utils.mjs";
|
|||||||
*/
|
*/
|
||||||
export function toBase64(data, alphabet="A-Za-z0-9+/=") {
|
export function toBase64(data, alphabet="A-Za-z0-9+/=") {
|
||||||
if (!data) return "";
|
if (!data) return "";
|
||||||
|
if (data instanceof ArrayBuffer) {
|
||||||
|
data = new Uint8Array(data);
|
||||||
|
}
|
||||||
if (typeof data == "string") {
|
if (typeof data == "string") {
|
||||||
data = Utils.strToByteArray(data);
|
data = Utils.strToByteArray(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
alphabet = Utils.expandAlphRange(alphabet).join("");
|
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 = "",
|
let output = "",
|
||||||
chr1, chr2, chr3,
|
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 = alphabet || "A-Za-z0-9+/=";
|
||||||
alphabet = Utils.expandAlphRange(alphabet).join("");
|
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 = [];
|
const output = [];
|
||||||
let chr1, chr2, chr3,
|
let chr1, chr2, chr3,
|
||||||
|
|||||||
436
src/core/lib/Blowfish.mjs
Normal file
436
src/core/lib/Blowfish.mjs
Normal file
@@ -0,0 +1,436 @@
|
|||||||
|
/**
|
||||||
|
Blowfish.js from Dojo Toolkit 1.8.1 (https://github.com/dojo/dojox/tree/1.8/encoding)
|
||||||
|
Extracted by Sladex (xslade@gmail.com)
|
||||||
|
Shoehorned into working with mjs for CyberChef by Matt C (matt@artemisbot.uk)
|
||||||
|
Refactored and implemented modes support by cbeuw (cbeuw.andy@gmail.com)
|
||||||
|
|
||||||
|
@license BSD
|
||||||
|
========================================================================
|
||||||
|
The "New" BSD License:
|
||||||
|
**********************
|
||||||
|
|
||||||
|
Copyright (c) 2005-2016, The Dojo Foundation
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer in the documentation
|
||||||
|
and/or other materials provided with the distribution.
|
||||||
|
* Neither the name of the Dojo Foundation nor the names of its contributors
|
||||||
|
may be used to endorse or promote products derived from this software
|
||||||
|
without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||||
|
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const crypto = {};
|
||||||
|
|
||||||
|
import forge from "node-forge/dist/forge.min.js";
|
||||||
|
|
||||||
|
|
||||||
|
/* dojo-release-1.8.1/dojo/_base/lang.js.uncompressed.js */
|
||||||
|
|
||||||
|
const lang = {};
|
||||||
|
lang.isString = function(it) {
|
||||||
|
// summary:
|
||||||
|
// Return true if it is a String
|
||||||
|
// it: anything
|
||||||
|
// Item to test.
|
||||||
|
return (typeof it == "string" || it instanceof String); // Boolean
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* dojo-release-1.8.1/dojo/_base/array.js.uncompressed.js */
|
||||||
|
|
||||||
|
const arrayUtil = {};
|
||||||
|
arrayUtil.map = function(arr, callback, thisObject, Ctr) {
|
||||||
|
// summary:
|
||||||
|
// applies callback to each element of arr and returns
|
||||||
|
// an Array with the results
|
||||||
|
// arr: Array|String
|
||||||
|
// the array to iterate on. If a string, operates on
|
||||||
|
// individual characters.
|
||||||
|
// callback: Function
|
||||||
|
// a function is invoked with three arguments, (item, index,
|
||||||
|
// array), and returns a value
|
||||||
|
// thisObject: Object?
|
||||||
|
// may be used to scope the call to callback
|
||||||
|
// returns: Array
|
||||||
|
// description:
|
||||||
|
// This function corresponds to the JavaScript 1.6 Array.map() method, with one difference: when
|
||||||
|
// run over sparse arrays, this implementation passes the "holes" in the sparse array to
|
||||||
|
// the callback function with a value of undefined. JavaScript 1.6's map skips the holes in the sparse array.
|
||||||
|
// For more details, see:
|
||||||
|
// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map
|
||||||
|
// example:
|
||||||
|
// | // returns [2, 3, 4, 5]
|
||||||
|
// | array.map([1, 2, 3, 4], function(item){ return item+1 });
|
||||||
|
|
||||||
|
// TODO: why do we have a non-standard signature here? do we need "Ctr"?
|
||||||
|
let i = 0;
|
||||||
|
const l = arr && arr.length || 0, out = new (Ctr || Array)(l);
|
||||||
|
if (l && typeof arr == "string") arr = arr.split("");
|
||||||
|
if (thisObject) {
|
||||||
|
for (; i < l; ++i) {
|
||||||
|
out[i] = callback.call(thisObject, arr[i], i, arr);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (; i < l; ++i) {
|
||||||
|
out[i] = callback(arr[i], i, arr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out; // Array
|
||||||
|
};
|
||||||
|
|
||||||
|
/* dojo-release-1.8.1/dojox/encoding/crypto/Blowfish.js.uncompressed.js */
|
||||||
|
|
||||||
|
/* Blowfish
|
||||||
|
* Created based on the C# implementation by Marcus Hahn (http://www.hotpixel.net/)
|
||||||
|
* Unsigned math based on Paul Johnstone and Peter Wood patches.
|
||||||
|
* 2005-12-08
|
||||||
|
*/
|
||||||
|
const boxes={
|
||||||
|
p: [
|
||||||
|
0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
|
||||||
|
0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
|
||||||
|
0x9216d5d9, 0x8979fb1b
|
||||||
|
],
|
||||||
|
s0: [
|
||||||
|
0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
|
||||||
|
0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
|
||||||
|
0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
|
||||||
|
0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
|
||||||
|
0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
|
||||||
|
0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
|
||||||
|
0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
|
||||||
|
0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
|
||||||
|
0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
|
||||||
|
0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
|
||||||
|
0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
|
||||||
|
0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
|
||||||
|
0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
|
||||||
|
0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
|
||||||
|
0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
|
||||||
|
0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
|
||||||
|
0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
|
||||||
|
0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
|
||||||
|
0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
|
||||||
|
0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
|
||||||
|
0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
|
||||||
|
0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
|
||||||
|
0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
|
||||||
|
0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
|
||||||
|
0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
|
||||||
|
0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
|
||||||
|
0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
|
||||||
|
0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
|
||||||
|
0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
|
||||||
|
0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
|
||||||
|
0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
|
||||||
|
0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a
|
||||||
|
],
|
||||||
|
s1: [
|
||||||
|
0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
|
||||||
|
0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
|
||||||
|
0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
|
||||||
|
0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
|
||||||
|
0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
|
||||||
|
0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
|
||||||
|
0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
|
||||||
|
0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
|
||||||
|
0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
|
||||||
|
0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
|
||||||
|
0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
|
||||||
|
0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
|
||||||
|
0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
|
||||||
|
0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
|
||||||
|
0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
|
||||||
|
0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
|
||||||
|
0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
|
||||||
|
0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
|
||||||
|
0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
|
||||||
|
0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
|
||||||
|
0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
|
||||||
|
0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
|
||||||
|
0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
|
||||||
|
0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
|
||||||
|
0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
|
||||||
|
0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
|
||||||
|
0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
|
||||||
|
0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
|
||||||
|
0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
|
||||||
|
0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
|
||||||
|
0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
|
||||||
|
0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7
|
||||||
|
],
|
||||||
|
s2: [
|
||||||
|
0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
|
||||||
|
0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
|
||||||
|
0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
|
||||||
|
0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
|
||||||
|
0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
|
||||||
|
0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
|
||||||
|
0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
|
||||||
|
0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
|
||||||
|
0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
|
||||||
|
0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
|
||||||
|
0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
|
||||||
|
0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
|
||||||
|
0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
|
||||||
|
0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
|
||||||
|
0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
|
||||||
|
0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
|
||||||
|
0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
|
||||||
|
0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
|
||||||
|
0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
|
||||||
|
0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
|
||||||
|
0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
|
||||||
|
0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
|
||||||
|
0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
|
||||||
|
0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
|
||||||
|
0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
|
||||||
|
0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
|
||||||
|
0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
|
||||||
|
0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
|
||||||
|
0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
|
||||||
|
0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
|
||||||
|
0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
|
||||||
|
0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0
|
||||||
|
],
|
||||||
|
s3: [
|
||||||
|
0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
|
||||||
|
0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
|
||||||
|
0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
|
||||||
|
0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
|
||||||
|
0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
|
||||||
|
0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
|
||||||
|
0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
|
||||||
|
0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
|
||||||
|
0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
|
||||||
|
0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
|
||||||
|
0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
|
||||||
|
0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
|
||||||
|
0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
|
||||||
|
0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
|
||||||
|
0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
|
||||||
|
0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
|
||||||
|
0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
|
||||||
|
0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
|
||||||
|
0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
|
||||||
|
0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
|
||||||
|
0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
|
||||||
|
0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
|
||||||
|
0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
|
||||||
|
0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
|
||||||
|
0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
|
||||||
|
0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
|
||||||
|
0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
|
||||||
|
0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
|
||||||
|
0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
|
||||||
|
0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
|
||||||
|
0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
|
||||||
|
0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
// fixes based on patch submitted by Peter Wood (#5791)
|
||||||
|
const xor = function(x, y) {
|
||||||
|
return (((x>>0x10)^(y>>0x10))<<0x10)|(((x&0xffff)^(y&0xffff))&0xffff);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const f = function(v, box) {
|
||||||
|
const d=box.s3[v&0xff]; v>>=8;
|
||||||
|
const c=box.s2[v&0xff]; v>>=8;
|
||||||
|
const b=box.s1[v&0xff]; v>>=8;
|
||||||
|
const a=box.s0[v&0xff];
|
||||||
|
|
||||||
|
let r = (((a>>0x10)+(b>>0x10)+(((a&0xffff)+(b&0xffff))>>0x10))<<0x10)|(((a&0xffff)+(b&0xffff))&0xffff);
|
||||||
|
r = (((r>>0x10)^(c>>0x10))<<0x10)|(((r&0xffff)^(c&0xffff))&0xffff);
|
||||||
|
return (((r>>0x10)+(d>>0x10)+(((r&0xffff)+(d&0xffff))>>0x10))<<0x10)|(((r&0xffff)+(d&0xffff))&0xffff);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const eb = function(o, box) {
|
||||||
|
// TODO: see if this can't be made more efficient
|
||||||
|
let l=o.left;
|
||||||
|
let r=o.right;
|
||||||
|
l=xor(l, box.p[0]);
|
||||||
|
r=xor(r, xor(f(l, box), box.p[1]));
|
||||||
|
l=xor(l, xor(f(r, box), box.p[2]));
|
||||||
|
r=xor(r, xor(f(l, box), box.p[3]));
|
||||||
|
l=xor(l, xor(f(r, box), box.p[4]));
|
||||||
|
r=xor(r, xor(f(l, box), box.p[5]));
|
||||||
|
l=xor(l, xor(f(r, box), box.p[6]));
|
||||||
|
r=xor(r, xor(f(l, box), box.p[7]));
|
||||||
|
l=xor(l, xor(f(r, box), box.p[8]));
|
||||||
|
r=xor(r, xor(f(l, box), box.p[9]));
|
||||||
|
l=xor(l, xor(f(r, box), box.p[10]));
|
||||||
|
r=xor(r, xor(f(l, box), box.p[11]));
|
||||||
|
l=xor(l, xor(f(r, box), box.p[12]));
|
||||||
|
r=xor(r, xor(f(l, box), box.p[13]));
|
||||||
|
l=xor(l, xor(f(r, box), box.p[14]));
|
||||||
|
r=xor(r, xor(f(l, box), box.p[15]));
|
||||||
|
l=xor(l, xor(f(r, box), box.p[16]));
|
||||||
|
o.right=l;
|
||||||
|
o.left=xor(r, box.p[17]);
|
||||||
|
};
|
||||||
|
|
||||||
|
const db = function(o, box) {
|
||||||
|
let l=o.left;
|
||||||
|
let r=o.right;
|
||||||
|
l=xor(l, box.p[17]);
|
||||||
|
r=xor(r, xor(f(l, box), box.p[16]));
|
||||||
|
l=xor(l, xor(f(r, box), box.p[15]));
|
||||||
|
r=xor(r, xor(f(l, box), box.p[14]));
|
||||||
|
l=xor(l, xor(f(r, box), box.p[13]));
|
||||||
|
r=xor(r, xor(f(l, box), box.p[12]));
|
||||||
|
l=xor(l, xor(f(r, box), box.p[11]));
|
||||||
|
r=xor(r, xor(f(l, box), box.p[10]));
|
||||||
|
l=xor(l, xor(f(r, box), box.p[9]));
|
||||||
|
r=xor(r, xor(f(l, box), box.p[8]));
|
||||||
|
l=xor(l, xor(f(r, box), box.p[7]));
|
||||||
|
r=xor(r, xor(f(l, box), box.p[6]));
|
||||||
|
l=xor(l, xor(f(r, box), box.p[5]));
|
||||||
|
r=xor(r, xor(f(l, box), box.p[4]));
|
||||||
|
l=xor(l, xor(f(r, box), box.p[3]));
|
||||||
|
r=xor(r, xor(f(l, box), box.p[2]));
|
||||||
|
l=xor(l, xor(f(r, box), box.p[1]));
|
||||||
|
o.right=l;
|
||||||
|
o.left=xor(r, box.p[0]);
|
||||||
|
};
|
||||||
|
|
||||||
|
const encryptBlock=function(inblock, outblock, box) {
|
||||||
|
const o = {};
|
||||||
|
o.left=inblock[0];
|
||||||
|
o.right=inblock[1];
|
||||||
|
eb(o, box);
|
||||||
|
outblock[0] = o.left;
|
||||||
|
outblock[1] = o.right;
|
||||||
|
};
|
||||||
|
|
||||||
|
const decryptBlock=function(inblock, outblock, box) {
|
||||||
|
const o= {};
|
||||||
|
o.left=inblock[0];
|
||||||
|
o.right=inblock[1];
|
||||||
|
db(o, box);
|
||||||
|
outblock[0] = o.left;
|
||||||
|
outblock[1] = o.right;
|
||||||
|
};
|
||||||
|
|
||||||
|
crypto.Blowfish = new function() {
|
||||||
|
this.createCipher=function(key, modeName) {
|
||||||
|
return new forge.cipher.BlockCipher({
|
||||||
|
algorithm: new Blowfish.Algorithm(key, modeName),
|
||||||
|
key: key,
|
||||||
|
decrypt: false
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
this.createDecipher=function(key, modeName) {
|
||||||
|
return new forge.cipher.BlockCipher({
|
||||||
|
algorithm: new Blowfish.Algorithm(key, modeName),
|
||||||
|
key: key,
|
||||||
|
decrypt: true
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}();
|
||||||
|
|
||||||
|
|
||||||
|
crypto.Blowfish.Algorithm=function(key, modeName) {
|
||||||
|
this.initialize({key: key});
|
||||||
|
const _box = this.box;
|
||||||
|
const modeOption = {
|
||||||
|
blockSize: 8,
|
||||||
|
cipher: {
|
||||||
|
encrypt: function(inblock, outblock) {
|
||||||
|
encryptBlock(inblock, outblock, _box);
|
||||||
|
},
|
||||||
|
decrypt: function(inblock, outblock) {
|
||||||
|
decryptBlock(inblock, outblock, _box);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
switch (modeName.toLowerCase()) {
|
||||||
|
case "ecb":
|
||||||
|
this.mode=new forge.cipher.modes.ecb(modeOption);
|
||||||
|
break;
|
||||||
|
case "cbc":
|
||||||
|
this.mode=new forge.cipher.modes.cbc(modeOption);
|
||||||
|
break;
|
||||||
|
case "cfb":
|
||||||
|
this.mode=new forge.cipher.modes.cfb(modeOption);
|
||||||
|
break;
|
||||||
|
case "ofb":
|
||||||
|
this.mode=new forge.cipher.modes.ofb(modeOption);
|
||||||
|
break;
|
||||||
|
case "ctr":
|
||||||
|
this.mode=new forge.cipher.modes.ctr(modeOption);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
this.mode=new forge.cipher.modes.ecb(modeOption);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
crypto.Blowfish.Algorithm.prototype.initialize=function(options) {
|
||||||
|
const POW8=Math.pow(2, 8);
|
||||||
|
|
||||||
|
let k=options.key;
|
||||||
|
if (lang.isString(k)) {
|
||||||
|
k = arrayUtil.map(k.split(""), function(item) {
|
||||||
|
return item.charCodeAt(0) & 0xff;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// init the boxes
|
||||||
|
let pos=0, data=0;
|
||||||
|
const res={ left: 0, right: 0 };
|
||||||
|
const box = {
|
||||||
|
p: arrayUtil.map(boxes.p.slice(0), function(item) {
|
||||||
|
const l=k.length;
|
||||||
|
for (let j=0; j<4; j++) {
|
||||||
|
data=(data*POW8)|k[pos++ % l];
|
||||||
|
}
|
||||||
|
return (((item>>0x10)^(data>>0x10))<<0x10)|(((item&0xffff)^(data&0xffff))&0xffff);
|
||||||
|
}),
|
||||||
|
s0: boxes.s0.slice(0),
|
||||||
|
s1: boxes.s1.slice(0),
|
||||||
|
s2: boxes.s2.slice(0),
|
||||||
|
s3: boxes.s3.slice(0)
|
||||||
|
};
|
||||||
|
|
||||||
|
// encrypt p and the s boxes
|
||||||
|
for (let i=0, l=box.p.length; i<l;) {
|
||||||
|
eb(res, box);
|
||||||
|
box.p[i++]=res.left;
|
||||||
|
box.p[i++]=res.right;
|
||||||
|
}
|
||||||
|
for (let i=0; i<4; i++) {
|
||||||
|
for (let j=0, l=box["s"+i].length; j<l;) {
|
||||||
|
eb(res, box);
|
||||||
|
box["s"+i][j++]=res.left;
|
||||||
|
box["s"+i][j++]=res.right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.box = box;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Blowfish = crypto.Blowfish;
|
||||||
@@ -12,16 +12,65 @@
|
|||||||
export const IO_FORMAT = {
|
export const IO_FORMAT = {
|
||||||
"UTF-8 (65001)": 65001,
|
"UTF-8 (65001)": 65001,
|
||||||
"UTF-7 (65000)": 65000,
|
"UTF-7 (65000)": 65000,
|
||||||
"UTF16LE (1200)": 1200,
|
"UTF-16LE (1200)": 1200,
|
||||||
"UTF16BE (1201)": 1201,
|
"UTF-16BE (1201)": 1201,
|
||||||
"UTF16 (1201)": 1201,
|
"UTF-32LE (12000)": 12000,
|
||||||
|
"UTF-32BE (12001)": 12001,
|
||||||
"IBM EBCDIC International (500)": 500,
|
"IBM EBCDIC International (500)": 500,
|
||||||
"IBM EBCDIC US-Canada (37)": 37,
|
"IBM EBCDIC US-Canada (37)": 37,
|
||||||
|
"IBM EBCDIC Multilingual/ROECE (Latin 2) (870)": 870,
|
||||||
|
"IBM EBCDIC Greek Modern (875)": 875,
|
||||||
|
"IBM EBCDIC French (1010)": 1010,
|
||||||
|
"IBM EBCDIC Turkish (Latin 5) (1026)": 1026,
|
||||||
|
"IBM EBCDIC Latin 1/Open System (1047)": 1047,
|
||||||
|
"IBM EBCDIC Lao (1132/1133/1341)": 1132,
|
||||||
|
"IBM EBCDIC US-Canada (037 + Euro symbol) (1140)": 1140,
|
||||||
|
"IBM EBCDIC Germany (20273 + Euro symbol) (1141)": 1141,
|
||||||
|
"IBM EBCDIC Denmark-Norway (20277 + Euro symbol) (1142)": 1142,
|
||||||
|
"IBM EBCDIC Finland-Sweden (20278 + Euro symbol) (1143)": 1143,
|
||||||
|
"IBM EBCDIC Italy (20280 + Euro symbol) (1144)": 1144,
|
||||||
|
"IBM EBCDIC Latin America-Spain (20284 + Euro symbol) (1145)": 1145,
|
||||||
|
"IBM EBCDIC United Kingdom (20285 + Euro symbol) (1146)": 1146,
|
||||||
|
"IBM EBCDIC France (20297 + Euro symbol) (1147)": 1147,
|
||||||
|
"IBM EBCDIC International (500 + Euro symbol) (1148)": 1148,
|
||||||
|
"IBM EBCDIC Icelandic (20871 + Euro symbol) (1149)": 1149,
|
||||||
|
"IBM EBCDIC Germany (20273)": 20273,
|
||||||
|
"IBM EBCDIC Denmark-Norway (20277)": 20277,
|
||||||
|
"IBM EBCDIC Finland-Sweden (20278)": 20278,
|
||||||
|
"IBM EBCDIC Italy (20280)": 20280,
|
||||||
|
"IBM EBCDIC Latin America-Spain (20284)": 20284,
|
||||||
|
"IBM EBCDIC United Kingdom (20285)": 20285,
|
||||||
|
"IBM EBCDIC Japanese Katakana Extended (20290)": 20290,
|
||||||
|
"IBM EBCDIC France (20297)": 20297,
|
||||||
|
"IBM EBCDIC Arabic (20420)": 20420,
|
||||||
|
"IBM EBCDIC Greek (20423)": 20423,
|
||||||
|
"IBM EBCDIC Hebrew (20424)": 20424,
|
||||||
|
"IBM EBCDIC Korean Extended (20833)": 20833,
|
||||||
|
"IBM EBCDIC Thai (20838)": 20838,
|
||||||
|
"IBM EBCDIC Icelandic (20871)": 20871,
|
||||||
|
"IBM EBCDIC Cyrillic Russian (20880)": 20880,
|
||||||
|
"IBM EBCDIC Turkish (20905)": 20905,
|
||||||
|
"IBM EBCDIC Latin 1/Open System (1047 + Euro symbol) (20924)": 20924,
|
||||||
|
"IBM EBCDIC Cyrillic Serbian-Bulgarian (21025)": 21025,
|
||||||
|
"OEM United States (437)": 437,
|
||||||
|
"OEM Greek (formerly 437G); Greek (DOS) (737)": 737,
|
||||||
|
"OEM Baltic; Baltic (DOS) (775)": 775,
|
||||||
|
"OEM Russian; Cyrillic + Euro symbol (808)": 808,
|
||||||
|
"OEM Multilingual Latin 1; Western European (DOS) (850)": 850,
|
||||||
|
"OEM Latin 2; Central European (DOS) (852)": 852,
|
||||||
|
"OEM Cyrillic (primarily Russian) (855)": 855,
|
||||||
|
"OEM Turkish; Turkish (DOS) (857)": 857,
|
||||||
|
"OEM Multilingual Latin 1 + Euro symbol (858)": 858,
|
||||||
|
"OEM Portuguese; Portuguese (DOS) (860)": 860,
|
||||||
|
"OEM Icelandic; Icelandic (DOS) (861)": 861,
|
||||||
|
"OEM Hebrew; Hebrew (DOS) (862)": 862,
|
||||||
|
"OEM French Canadian; French Canadian (DOS) (863)": 863,
|
||||||
|
"OEM Arabic; Arabic (864) (864)": 864,
|
||||||
|
"OEM Nordic; Nordic (DOS) (865)": 865,
|
||||||
|
"OEM Russian; Cyrillic (DOS) (866)": 866,
|
||||||
|
"OEM Modern Greek; Greek, Modern (DOS) (869)": 869,
|
||||||
|
"OEM Cyrillic (primarily Russian) + Euro Symbol (872)": 872,
|
||||||
"Windows-874 Thai (874)": 874,
|
"Windows-874 Thai (874)": 874,
|
||||||
"Japanese Shift-JIS (932)": 932,
|
|
||||||
"Simplified Chinese GBK (936)": 936,
|
|
||||||
"Korean (949)": 949,
|
|
||||||
"Traditional Chinese Big5 (950)": 950,
|
|
||||||
"Windows-1250 Central European (1250)": 1250,
|
"Windows-1250 Central European (1250)": 1250,
|
||||||
"Windows-1251 Cyrillic (1251)": 1251,
|
"Windows-1251 Cyrillic (1251)": 1251,
|
||||||
"Windows-1252 Latin (1252)": 1252,
|
"Windows-1252 Latin (1252)": 1252,
|
||||||
@@ -31,10 +80,6 @@ export const IO_FORMAT = {
|
|||||||
"Windows-1256 Arabic (1256)": 1256,
|
"Windows-1256 Arabic (1256)": 1256,
|
||||||
"Windows-1257 Baltic (1257)": 1257,
|
"Windows-1257 Baltic (1257)": 1257,
|
||||||
"Windows-1258 Vietnam (1258)": 1258,
|
"Windows-1258 Vietnam (1258)": 1258,
|
||||||
"US-ASCII (20127)": 20127,
|
|
||||||
"Simplified Chinese GB2312 (20936)": 20936,
|
|
||||||
"KOI8-R Russian Cyrillic (20866)": 20866,
|
|
||||||
"KOI8-U Ukrainian Cyrillic (21866)": 21866,
|
|
||||||
"ISO-8859-1 Latin 1 Western European (28591)": 28591,
|
"ISO-8859-1 Latin 1 Western European (28591)": 28591,
|
||||||
"ISO-8859-2 Latin 2 Central European (28592)": 28592,
|
"ISO-8859-2 Latin 2 Central European (28592)": 28592,
|
||||||
"ISO-8859-3 Latin 3 South European (28593)": 28593,
|
"ISO-8859-3 Latin 3 South European (28593)": 28593,
|
||||||
@@ -43,6 +88,7 @@ export const IO_FORMAT = {
|
|||||||
"ISO-8859-6 Latin/Arabic (28596)": 28596,
|
"ISO-8859-6 Latin/Arabic (28596)": 28596,
|
||||||
"ISO-8859-7 Latin/Greek (28597)": 28597,
|
"ISO-8859-7 Latin/Greek (28597)": 28597,
|
||||||
"ISO-8859-8 Latin/Hebrew (28598)": 28598,
|
"ISO-8859-8 Latin/Hebrew (28598)": 28598,
|
||||||
|
"ISO 8859-8 Hebrew (ISO-Logical) (38598)": 38598,
|
||||||
"ISO-8859-9 Latin 5 Turkish (28599)": 28599,
|
"ISO-8859-9 Latin 5 Turkish (28599)": 28599,
|
||||||
"ISO-8859-10 Latin 6 Nordic (28600)": 28600,
|
"ISO-8859-10 Latin 6 Nordic (28600)": 28600,
|
||||||
"ISO-8859-11 Latin/Thai (28601)": 28601,
|
"ISO-8859-11 Latin/Thai (28601)": 28601,
|
||||||
@@ -50,9 +96,71 @@ export const IO_FORMAT = {
|
|||||||
"ISO-8859-14 Latin 8 Celtic (28604)": 28604,
|
"ISO-8859-14 Latin 8 Celtic (28604)": 28604,
|
||||||
"ISO-8859-15 Latin 9 (28605)": 28605,
|
"ISO-8859-15 Latin 9 (28605)": 28605,
|
||||||
"ISO-8859-16 Latin 10 (28606)": 28606,
|
"ISO-8859-16 Latin 10 (28606)": 28606,
|
||||||
"ISO-2022 JIS Japanese (50222)": 50222,
|
"ISO 2022 JIS Japanese with no halfwidth Katakana (50220)": 50220,
|
||||||
|
"ISO 2022 JIS Japanese with halfwidth Katakana (50221)": 50221,
|
||||||
|
"ISO 2022 Japanese JIS X 0201-1989 (1 byte Kana-SO/SI) (50222)": 50222,
|
||||||
|
"ISO 2022 Korean (50225)": 50225,
|
||||||
|
"ISO 2022 Simplified Chinese (50227)": 50227,
|
||||||
|
"ISO 6937 Non-Spacing Accent (20269)": 20269,
|
||||||
"EUC Japanese (51932)": 51932,
|
"EUC Japanese (51932)": 51932,
|
||||||
|
"EUC Simplified Chinese (51936)": 51936,
|
||||||
"EUC Korean (51949)": 51949,
|
"EUC Korean (51949)": 51949,
|
||||||
|
"ISCII Devanagari (57002)": 57002,
|
||||||
|
"ISCII Bengali (57003)": 57003,
|
||||||
|
"ISCII Tamil (57004)": 57004,
|
||||||
|
"ISCII Telugu (57005)": 57005,
|
||||||
|
"ISCII Assamese (57006)": 57006,
|
||||||
|
"ISCII Oriya (57007)": 57007,
|
||||||
|
"ISCII Kannada (57008)": 57008,
|
||||||
|
"ISCII Malayalam (57009)": 57009,
|
||||||
|
"ISCII Gujarati (57010)": 57010,
|
||||||
|
"ISCII Punjabi (57011)": 57011,
|
||||||
|
"Japanese Shift-JIS (932)": 932,
|
||||||
|
"Simplified Chinese GBK (936)": 936,
|
||||||
|
"Korean (949)": 949,
|
||||||
|
"Traditional Chinese Big5 (950)": 950,
|
||||||
|
"US-ASCII (7-bit) (20127)": 20127,
|
||||||
|
"Simplified Chinese GB2312 (20936)": 20936,
|
||||||
|
"KOI8-R Russian Cyrillic (20866)": 20866,
|
||||||
|
"KOI8-U Ukrainian Cyrillic (21866)": 21866,
|
||||||
|
"Mazovia (Polish) MS-DOS (620)": 620,
|
||||||
|
"Arabic (ASMO 708) (708)": 708,
|
||||||
|
"Arabic (Transparent ASMO); Arabic (DOS) (720)": 720,
|
||||||
|
"Kamenický (Czech) MS-DOS (895)": 895,
|
||||||
|
"Korean (Johab) (1361)": 1361,
|
||||||
|
"MAC Roman (10000)": 10000,
|
||||||
|
"Japanese (Mac) (10001)": 10001,
|
||||||
|
"MAC Traditional Chinese (Big5) (10002)": 10002,
|
||||||
|
"Korean (Mac) (10003)": 10003,
|
||||||
|
"Arabic (Mac) (10004)": 10004,
|
||||||
|
"Hebrew (Mac) (10005)": 10005,
|
||||||
|
"Greek (Mac) (10006)": 10006,
|
||||||
|
"Cyrillic (Mac) (10007)": 10007,
|
||||||
|
"MAC Simplified Chinese (GB 2312) (10008)": 10008,
|
||||||
|
"Romanian (Mac) (10010)": 10010,
|
||||||
|
"Ukrainian (Mac) (10017)": 10017,
|
||||||
|
"Thai (Mac) (10021)": 10021,
|
||||||
|
"MAC Latin 2 (Central European) (10029)": 10029,
|
||||||
|
"Icelandic (Mac) (10079)": 10079,
|
||||||
|
"Turkish (Mac) (10081)": 10081,
|
||||||
|
"Croatian (Mac) (10082)": 10082,
|
||||||
|
"CNS Taiwan (Chinese Traditional) (20000)": 20000,
|
||||||
|
"TCA Taiwan (20001)": 20001,
|
||||||
|
"ETEN Taiwan (Chinese Traditional) (20002)": 20002,
|
||||||
|
"IBM5550 Taiwan (20003)": 20003,
|
||||||
|
"TeleText Taiwan (20004)": 20004,
|
||||||
|
"Wang Taiwan (20005)": 20005,
|
||||||
|
"Western European IA5 (IRV International Alphabet 5) (20105)": 20105,
|
||||||
|
"IA5 German (7-bit) (20106)": 20106,
|
||||||
|
"IA5 Swedish (7-bit) (20107)": 20107,
|
||||||
|
"IA5 Norwegian (7-bit) (20108)": 20108,
|
||||||
|
"T.61 (20261)": 20261,
|
||||||
|
"Japanese (JIS 0208-1990 and 0212-1990) (20932)": 20932,
|
||||||
|
"Korean Wansung (20949)": 20949,
|
||||||
|
"Extended/Ext Alpha Lowercase (21027)": 21027,
|
||||||
|
"Europa 3 (29001)": 29001,
|
||||||
|
"Atari ST/TT (47451)": 47451,
|
||||||
|
"HZ-GB2312 Simplified Chinese (52936)": 52936,
|
||||||
"Simplified Chinese GB18030 (54936)": 54936,
|
"Simplified Chinese GB18030 (54936)": 54936,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -6,9 +6,22 @@
|
|||||||
* @license Apache-2.0
|
* @license Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import geohash from "ngeohash";
|
|
||||||
import geodesy from "geodesy";
|
|
||||||
import OperationError from "../errors/OperationError.mjs";
|
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
|
* Co-ordinate formats
|
||||||
@@ -116,22 +129,22 @@ export function convertCoordinates (input, inFormat, inDelim, outFormat, outDeli
|
|||||||
switch (inFormat) {
|
switch (inFormat) {
|
||||||
case "Geohash":
|
case "Geohash":
|
||||||
hash = geohash.decode(input.replace(/[^A-Za-z0-9]/g, ""));
|
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;
|
break;
|
||||||
case "Military Grid Reference System":
|
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();
|
latlon = utm.toLatLonE();
|
||||||
break;
|
break;
|
||||||
case "Ordnance Survey National Grid":
|
case "Ordnance Survey National Grid":
|
||||||
osng = geodesy.OsGridRef.parse(input.replace(/[^A-Za-z0-9]/g, ""));
|
osng = OsGridRef.parse(input.replace(/[^A-Za-z0-9]/g, ""));
|
||||||
latlon = geodesy.OsGridRef.osGridToLatLon(osng);
|
latlon = OsGridRef.osGridToLatLon(osng);
|
||||||
break;
|
break;
|
||||||
case "Universal Transverse Mercator":
|
case "Universal Transverse Mercator":
|
||||||
// Geodesy needs a space between the first 2 digits and the next letter
|
// Geodesy needs a space between the first 2 digits and the next letter
|
||||||
if (/^[\d]{2}[A-Za-z]/.test(input)) {
|
if (/^[\d]{2}[A-Za-z]/.test(input)) {
|
||||||
input = input.slice(0, 2) + " " + input.slice(2);
|
input = input.slice(0, 2) + " " + input.slice(2);
|
||||||
}
|
}
|
||||||
utm = geodesy.Utm.parse(input);
|
utm = Utm.parse(input);
|
||||||
latlon = utm.toLatLonE();
|
latlon = utm.toLatLonE();
|
||||||
break;
|
break;
|
||||||
case "Degrees Minutes Seconds":
|
case "Degrees Minutes Seconds":
|
||||||
@@ -143,7 +156,7 @@ export function convertCoordinates (input, inFormat, inDelim, outFormat, outDeli
|
|||||||
if (splitLat.length >= 3 && splitLong.length >= 3) {
|
if (splitLat.length >= 3 && splitLong.length >= 3) {
|
||||||
lat = convDMSToDD(splitLat[0], splitLat[1], splitLat[2], 10);
|
lat = convDMSToDD(splitLat[0], splitLat[1], splitLat[2], 10);
|
||||||
lon = convDMSToDD(splitLong[0], splitLong[1], splitLong[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 {
|
} else {
|
||||||
throw new OperationError("Invalid co-ordinate format for Degrees Minutes Seconds");
|
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]);
|
splitLat = splitInput(split[0]);
|
||||||
if (splitLat.length >= 3) {
|
if (splitLat.length >= 3) {
|
||||||
lat = convDMSToDD(splitLat[0], splitLat[1], splitLat[2]);
|
lat = convDMSToDD(splitLat[0], splitLat[1], splitLat[2]);
|
||||||
latlon = new geodesy.LatLonEllipsoidal(lat.degrees, lat.degrees);
|
latlon = new LatLonEllipsoidal(lat.degrees, lat.degrees);
|
||||||
} else {
|
} else {
|
||||||
throw new OperationError("Invalid co-ordinate format for Degrees Minutes Seconds");
|
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
|
// Convert to decimal degrees, and then convert to a geodesy object
|
||||||
lat = convDDMToDD(splitLat[0], splitLat[1], 10);
|
lat = convDDMToDD(splitLat[0], splitLat[1], 10);
|
||||||
lon = convDDMToDD(splitLong[0], splitLong[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 {
|
} else {
|
||||||
// Not a pair, so only try to convert one set of co-ordinates
|
// Not a pair, so only try to convert one set of co-ordinates
|
||||||
splitLat = splitInput(input);
|
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.");
|
throw new OperationError("Invalid co-ordinate format for Degrees Decimal Minutes.");
|
||||||
}
|
}
|
||||||
lat = convDDMToDD(splitLat[0], splitLat[1], 10);
|
lat = convDDMToDD(splitLat[0], splitLat[1], 10);
|
||||||
latlon = new geodesy.LatLonEllipsoidal(lat.degrees, lat.degrees);
|
latlon = new LatLonEllipsoidal(lat.degrees, lat.degrees);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "Decimal Degrees":
|
case "Decimal Degrees":
|
||||||
@@ -186,14 +199,14 @@ export function convertCoordinates (input, inFormat, inDelim, outFormat, outDeli
|
|||||||
if (splitLat.length !== 1 || splitLong.length !== 1) {
|
if (splitLat.length !== 1 || splitLong.length !== 1) {
|
||||||
throw new OperationError("Invalid co-ordinate format for Decimal Degrees.");
|
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 {
|
} else {
|
||||||
// Not a pair, so only try to convert one set of co-ordinates
|
// Not a pair, so only try to convert one set of co-ordinates
|
||||||
splitLat = splitInput(split[0]);
|
splitLat = splitInput(split[0]);
|
||||||
if (splitLat.length !== 1) {
|
if (splitLat.length !== 1) {
|
||||||
throw new OperationError("Invalid co-ordinate format for Decimal Degrees.");
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -260,7 +273,7 @@ export function convertCoordinates (input, inFormat, inDelim, outFormat, outDeli
|
|||||||
convLat = mgrs.toString(precision);
|
convLat = mgrs.toString(precision);
|
||||||
break;
|
break;
|
||||||
case "Ordnance Survey National Grid":
|
case "Ordnance Survey National Grid":
|
||||||
osng = geodesy.OsGridRef.latLonToOsGrid(latlon);
|
osng = OsGridRef.latLonToOsGrid(latlon);
|
||||||
if (osng.toString() === "") {
|
if (osng.toString() === "") {
|
||||||
throw new OperationError("Could not convert co-ordinates to OS National Grid. Are the co-ordinates in range?");
|
throw new OperationError("Could not convert co-ordinates to OS National Grid. Are the co-ordinates in range?");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ export const WORD_DELIM_OPTIONS = ["Line feed", "CRLF", "Forward slash", "Backsl
|
|||||||
export const INPUT_DELIM_OPTIONS = ["Line feed", "CRLF", "Space", "Comma", "Semi-colon", "Colon", "Nothing (separate chars)"];
|
export const INPUT_DELIM_OPTIONS = ["Line feed", "CRLF", "Space", "Comma", "Semi-colon", "Colon", "Nothing (separate chars)"];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Armithmetic sequence delimiters
|
* Arithmetic sequence delimiters
|
||||||
*/
|
*/
|
||||||
export const ARITHMETIC_DELIM_OPTIONS = ["Line feed", "Space", "Comma", "Semi-colon", "Colon", "CRLF"];
|
export const ARITHMETIC_DELIM_OPTIONS = ["Line feed", "Space", "Comma", "Semi-colon", "Colon", "CRLF"];
|
||||||
|
|
||||||
@@ -72,3 +72,12 @@ export const JOIN_DELIM_OPTIONS = [
|
|||||||
{name: "Nothing (join chars)", value: ""}
|
{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
|
* Given a buffer, detects magic byte sequences at specific positions and returns the
|
||||||
* extension and mime type.
|
* extension and mime type.
|
||||||
*
|
*
|
||||||
* @param {Uint8Array} buf
|
* @param {Uint8Array|ArrayBuffer} buf
|
||||||
* @param {string[]} [categories=All] - Which categories of file to look for
|
* @param {string[]} [categories=All] - Which categories of file to look for
|
||||||
* @returns {Object[]} types
|
* @returns {Object[]} types
|
||||||
* @returns {string} type.name - Name of file type
|
* @returns {string} type.name - Name of file type
|
||||||
@@ -84,6 +84,10 @@ function bytesMatch(sig, buf, offset=0) {
|
|||||||
* @returns {string} [type.desc] - Description
|
* @returns {string} [type.desc] - Description
|
||||||
*/
|
*/
|
||||||
export function detectFileType(buf, categories=Object.keys(FILE_SIGNATURES)) {
|
export function detectFileType(buf, categories=Object.keys(FILE_SIGNATURES)) {
|
||||||
|
if (buf instanceof ArrayBuffer) {
|
||||||
|
buf = new Uint8Array(buf);
|
||||||
|
}
|
||||||
|
|
||||||
if (!(buf && buf.length > 1)) {
|
if (!(buf && buf.length > 1)) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
@@ -174,7 +178,7 @@ export function scanForFileTypes(buf, categories=Object.keys(FILE_SIGNATURES)) {
|
|||||||
* @param {Uint8Array} buf - The buffer to search
|
* @param {Uint8Array} buf - The buffer to search
|
||||||
* @param {Object} sig - A single signature object (Not an array of signatures)
|
* @param {Object} sig - A single signature object (Not an array of signatures)
|
||||||
* @param {number} offset - Where to start search from
|
* @param {number} offset - Where to start search from
|
||||||
* @returs {number} The position of the match or -1 if one cannot be found.
|
* @returns {number} The position of the match or -1 if one cannot be found.
|
||||||
*/
|
*/
|
||||||
function locatePotentialSig(buf, sig, offset) {
|
function locatePotentialSig(buf, sig, offset) {
|
||||||
// Find values for first key and value in sig
|
// Find values for first key and value in sig
|
||||||
@@ -203,7 +207,7 @@ function locatePotentialSig(buf, sig, offset) {
|
|||||||
* Detects whether the given buffer is a file of the type specified.
|
* Detects whether the given buffer is a file of the type specified.
|
||||||
*
|
*
|
||||||
* @param {string|RegExp} type
|
* @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
|
* @returns {string|false} The mime type or false if the type does not match
|
||||||
*/
|
*/
|
||||||
export function isType(type, buf) {
|
export function isType(type, buf) {
|
||||||
@@ -230,7 +234,7 @@ export function isType(type, buf) {
|
|||||||
/**
|
/**
|
||||||
* Detects whether the given buffer contains an image file.
|
* 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
|
* @returns {string|false} The mime type or false if the type does not match
|
||||||
*/
|
*/
|
||||||
export function isImage(buf) {
|
export function isImage(buf) {
|
||||||
|
|||||||
@@ -97,6 +97,7 @@ class Magic {
|
|||||||
|
|
||||||
if (!fileType.length) return null;
|
if (!fileType.length) return null;
|
||||||
return {
|
return {
|
||||||
|
name: fileType[0].name,
|
||||||
ext: fileType[0].extension,
|
ext: fileType[0].extension,
|
||||||
mime: fileType[0].mime,
|
mime: fileType[0].mime,
|
||||||
desc: fileType[0].description
|
desc: fileType[0].description
|
||||||
@@ -354,17 +355,17 @@ class Magic {
|
|||||||
let aScore = a.languageScores[0].score,
|
let aScore = a.languageScores[0].score,
|
||||||
bScore = b.languageScores[0].score;
|
bScore = b.languageScores[0].score;
|
||||||
|
|
||||||
// If a recipe results in a file being detected, it receives a relatively good score
|
|
||||||
if (a.fileType) aScore = 500;
|
|
||||||
if (b.fileType) bScore = 500;
|
|
||||||
|
|
||||||
// If the result is valid UTF8, its score gets boosted (lower being better)
|
// If the result is valid UTF8, its score gets boosted (lower being better)
|
||||||
if (a.isUTF8) aScore -= 100;
|
if (a.isUTF8) aScore -= 100;
|
||||||
if (b.isUTF8) bScore -= 100;
|
if (b.isUTF8) bScore -= 100;
|
||||||
|
|
||||||
|
// If a recipe results in a file being detected, it receives a relatively good score
|
||||||
|
if (a.fileType && aScore > 500) aScore = 500;
|
||||||
|
if (b.fileType && bScore > 500) bScore = 500;
|
||||||
|
|
||||||
// If the option is marked useful, give it a good score
|
// If the option is marked useful, give it a good score
|
||||||
if (a.useful) aScore = 100;
|
if (a.useful && aScore > 100) aScore = 100;
|
||||||
if (b.useful) bScore = 100;
|
if (b.useful && bScore > 100) bScore = 100;
|
||||||
|
|
||||||
// Shorter recipes are better, so we add the length of the recipe to the score
|
// Shorter recipes are better, so we add the length of the recipe to the score
|
||||||
aScore += a.recipe.length;
|
aScore += a.recipe.length;
|
||||||
@@ -497,7 +498,7 @@ class Magic {
|
|||||||
* Taken from http://wikistats.wmflabs.org/display.php?t=wp
|
* Taken from http://wikistats.wmflabs.org/display.php?t=wp
|
||||||
*
|
*
|
||||||
* @param {string} code - ISO 639 code
|
* @param {string} code - ISO 639 code
|
||||||
* @returns {string} The full name of the languge
|
* @returns {string} The full name of the language
|
||||||
*/
|
*/
|
||||||
static codeToLanguage(code) {
|
static codeToLanguage(code) {
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ export async function parseQrCode(input, normalise) {
|
|||||||
image = await jimp.read(image);
|
image = await jimp.read(image);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
throw new OperationError(`Error normalising iamge. (${err})`);
|
throw new OperationError(`Error normalising image. (${err})`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const qrData = jsQR(image.bitmap.data, image.getWidth(), image.getHeight());
|
const qrData = jsQR(image.bitmap.data, image.getWidth(), image.getHeight());
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ class AddTextToImage extends Operation {
|
|||||||
let xPos = args[3],
|
let xPos = args[3],
|
||||||
yPos = args[4];
|
yPos = args[4];
|
||||||
|
|
||||||
if (!isImage(new Uint8Array(input))) {
|
if (!isImage(input)) {
|
||||||
throw new OperationError("Invalid file type.");
|
throw new OperationError("Invalid file type.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
76
src/core/operations/AvroToJSON.mjs
Normal file
76
src/core/operations/AvroToJSON.mjs
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
/**
|
||||||
|
* @author jarrodconnolly [jarrod@nestedquotes.ca]
|
||||||
|
* @copyright Crown Copyright 2019
|
||||||
|
* @license Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import Operation from "../Operation.mjs";
|
||||||
|
import OperationError from "../errors/OperationError.mjs";
|
||||||
|
import avro from "avsc";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Avro to JSON operation
|
||||||
|
*/
|
||||||
|
class AvroToJSON extends Operation {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AvroToJSON constructor
|
||||||
|
*/
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.name = "Avro to JSON";
|
||||||
|
this.module = "Serialise";
|
||||||
|
this.description = "Converts Avro encoded data into JSON.";
|
||||||
|
this.infoURL = "https://wikipedia.org/wiki/Apache_Avro";
|
||||||
|
this.inputType = "ArrayBuffer";
|
||||||
|
this.outputType = "string";
|
||||||
|
this.args = [
|
||||||
|
{
|
||||||
|
name: "Force Valid JSON",
|
||||||
|
type: "boolean",
|
||||||
|
value: true
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {ArrayBuffer} input
|
||||||
|
* @param {Object[]} args
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
run(input, args) {
|
||||||
|
if (input.byteLength <= 0) {
|
||||||
|
throw new OperationError("Please provide an input.");
|
||||||
|
}
|
||||||
|
|
||||||
|
const forceJSON = args[0];
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const result = [];
|
||||||
|
const inpArray = new Uint8Array(input);
|
||||||
|
const decoder = new avro.streams.BlockDecoder();
|
||||||
|
|
||||||
|
decoder
|
||||||
|
.on("data", function (obj) {
|
||||||
|
result.push(obj);
|
||||||
|
})
|
||||||
|
.on("error", function () {
|
||||||
|
reject(new OperationError("Error parsing Avro file."));
|
||||||
|
})
|
||||||
|
.on("end", function () {
|
||||||
|
if (forceJSON) {
|
||||||
|
resolve(result.length === 1 ? JSON.stringify(result[0], null, 4) : JSON.stringify(result, null, 4));
|
||||||
|
} else {
|
||||||
|
const data = result.reduce((result, current) => result + JSON.stringify(current) + "\n", "");
|
||||||
|
resolve(data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
decoder.write(inpArray);
|
||||||
|
decoder.end();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default AvroToJSON;
|
||||||
@@ -50,7 +50,7 @@ class BLAKE2b extends Operation {
|
|||||||
/**
|
/**
|
||||||
* @param {ArrayBuffer} input
|
* @param {ArrayBuffer} input
|
||||||
* @param {Object[]} args
|
* @param {Object[]} args
|
||||||
* @returns {string} The input having been hashed with BLAKE2b in the encoding format speicifed.
|
* @returns {string} The input having been hashed with BLAKE2b in the encoding format specified.
|
||||||
*/
|
*/
|
||||||
run(input, args) {
|
run(input, args) {
|
||||||
const [outSize, outFormat] = args;
|
const [outSize, outFormat] = args;
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ class BLAKE2s extends Operation {
|
|||||||
/**
|
/**
|
||||||
* @param {ArrayBuffer} input
|
* @param {ArrayBuffer} input
|
||||||
* @param {Object[]} args
|
* @param {Object[]} args
|
||||||
* @returns {string} The input having been hashed with BLAKE2s in the encoding format speicifed.
|
* @returns {string} The input having been hashed with BLAKE2s in the encoding format specified.
|
||||||
*/
|
*/
|
||||||
run(input, args) {
|
run(input, args) {
|
||||||
const [outSize, outFormat] = args;
|
const [outSize, outFormat] = args;
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ class BSONDeserialise extends Operation {
|
|||||||
super();
|
super();
|
||||||
|
|
||||||
this.name = "BSON deserialise";
|
this.name = "BSON deserialise";
|
||||||
this.module = "BSON";
|
this.module = "Serialise";
|
||||||
this.description = "BSON is a computer data interchange format used mainly as a data storage and network transfer format in the MongoDB database. It is a binary form for representing simple data structures, associative arrays (called objects or documents in MongoDB), and various data types of specific interest to MongoDB. The name 'BSON' is based on the term JSON and stands for 'Binary JSON'.<br><br>Input data should be in a raw bytes format.";
|
this.description = "BSON is a computer data interchange format used mainly as a data storage and network transfer format in the MongoDB database. It is a binary form for representing simple data structures, associative arrays (called objects or documents in MongoDB), and various data types of specific interest to MongoDB. The name 'BSON' is based on the term JSON and stands for 'Binary JSON'.<br><br>Input data should be in a raw bytes format.";
|
||||||
this.infoURL = "https://wikipedia.org/wiki/BSON";
|
this.infoURL = "https://wikipedia.org/wiki/BSON";
|
||||||
this.inputType = "ArrayBuffer";
|
this.inputType = "ArrayBuffer";
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ class BSONSerialise extends Operation {
|
|||||||
super();
|
super();
|
||||||
|
|
||||||
this.name = "BSON serialise";
|
this.name = "BSON serialise";
|
||||||
this.module = "BSON";
|
this.module = "Serialise";
|
||||||
this.description = "BSON is a computer data interchange format used mainly as a data storage and network transfer format in the MongoDB database. It is a binary form for representing simple data structures, associative arrays (called objects or documents in MongoDB), and various data types of specific interest to MongoDB. The name 'BSON' is based on the term JSON and stands for 'Binary JSON'.<br><br>Input data should be valid JSON.";
|
this.description = "BSON is a computer data interchange format used mainly as a data storage and network transfer format in the MongoDB database. It is a binary form for representing simple data structures, associative arrays (called objects or documents in MongoDB), and various data types of specific interest to MongoDB. The name 'BSON' is based on the term JSON and stands for 'Binary JSON'.<br><br>Input data should be valid JSON.";
|
||||||
this.infoURL = "https://wikipedia.org/wiki/BSON";
|
this.infoURL = "https://wikipedia.org/wiki/BSON";
|
||||||
this.inputType = "string";
|
this.inputType = "string";
|
||||||
|
|||||||
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.mjs";
|
||||||
|
import {
|
||||||
|
BACON_ALPHABETS,
|
||||||
|
BACON_TRANSLATION_CASE, BACON_TRANSLATION_AMNZ, BACON_TRANSLATIONS, BACON_CLEARER_MAP, BACON_NORMALIZE_MAP,
|
||||||
|
swapZeroAndOne
|
||||||
|
} from "../lib/Bacon.mjs";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.mjs";
|
||||||
|
import {
|
||||||
|
BACON_ALPHABETS,
|
||||||
|
BACON_TRANSLATIONS_FOR_ENCODING, BACON_TRANSLATION_AB,
|
||||||
|
swapZeroAndOne
|
||||||
|
} from "../lib/Bacon.mjs";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
@@ -6,23 +6,9 @@
|
|||||||
|
|
||||||
import Operation from "../Operation.mjs";
|
import Operation from "../Operation.mjs";
|
||||||
import Utils from "../Utils.mjs";
|
import Utils from "../Utils.mjs";
|
||||||
|
import forge from "node-forge/dist/forge.min.js";
|
||||||
import OperationError from "../errors/OperationError.mjs";
|
import OperationError from "../errors/OperationError.mjs";
|
||||||
import { Blowfish } from "../vendor/Blowfish.mjs";
|
import { Blowfish } from "../lib/Blowfish.mjs";
|
||||||
import { toBase64 } from "../lib/Base64.mjs";
|
|
||||||
import { toHexFast } from "../lib/Hex.mjs";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Lookup table for Blowfish output types.
|
|
||||||
*/
|
|
||||||
const BLOWFISH_OUTPUT_TYPE_LOOKUP = {
|
|
||||||
Base64: 0, Hex: 1, String: 2, Raw: 3
|
|
||||||
};
|
|
||||||
/**
|
|
||||||
* Lookup table for Blowfish modes.
|
|
||||||
*/
|
|
||||||
const BLOWFISH_MODE_LOOKUP = {
|
|
||||||
ECB: 0, CBC: 1, PCBC: 2, CFB: 3, OFB: 4, CTR: 5
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Blowfish Decrypt operation
|
* Blowfish Decrypt operation
|
||||||
@@ -57,12 +43,12 @@ class BlowfishDecrypt extends Operation {
|
|||||||
{
|
{
|
||||||
"name": "Mode",
|
"name": "Mode",
|
||||||
"type": "option",
|
"type": "option",
|
||||||
"value": ["CBC", "PCBC", "CFB", "OFB", "CTR", "ECB"]
|
"value": ["CBC", "CFB", "OFB", "CTR", "ECB"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Input",
|
"name": "Input",
|
||||||
"type": "option",
|
"type": "option",
|
||||||
"value": ["Hex", "Base64", "Raw"]
|
"value": ["Hex", "Raw"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Output",
|
"name": "Output",
|
||||||
@@ -79,21 +65,29 @@ class BlowfishDecrypt extends Operation {
|
|||||||
*/
|
*/
|
||||||
run(input, args) {
|
run(input, args) {
|
||||||
const key = Utils.convertToByteString(args[0].string, args[0].option),
|
const key = Utils.convertToByteString(args[0].string, args[0].option),
|
||||||
iv = Utils.convertToByteArray(args[1].string, args[1].option),
|
iv = Utils.convertToByteString(args[1].string, args[1].option),
|
||||||
[,, mode, inputType, outputType] = args;
|
mode = args[2],
|
||||||
|
inputType = args[3],
|
||||||
|
outputType = args[4];
|
||||||
|
|
||||||
if (key.length === 0) throw new OperationError("Enter a key");
|
if (key.length !== 8) {
|
||||||
|
throw new OperationError(`Invalid key length: ${key.length} bytes
|
||||||
|
|
||||||
input = inputType === "Raw" ? Utils.strToByteArray(input) : input;
|
Blowfish uses a key length of 8 bytes (64 bits).`);
|
||||||
|
}
|
||||||
|
|
||||||
Blowfish.setIV(toBase64(iv), 0);
|
input = Utils.convertToByteString(input, inputType);
|
||||||
|
|
||||||
const result = Blowfish.decrypt(input, key, {
|
const decipher = Blowfish.createDecipher(key, mode);
|
||||||
outputType: BLOWFISH_OUTPUT_TYPE_LOOKUP[inputType], // This actually means inputType. The library is weird.
|
decipher.start({iv: iv});
|
||||||
cipherMode: BLOWFISH_MODE_LOOKUP[mode]
|
decipher.update(forge.util.createBuffer(input));
|
||||||
});
|
const result = decipher.finish();
|
||||||
|
|
||||||
return outputType === "Hex" ? toHexFast(Utils.strToByteArray(result)) : result;
|
if (result) {
|
||||||
|
return outputType === "Hex" ? decipher.output.toHex() : decipher.output.getBytes();
|
||||||
|
} else {
|
||||||
|
throw new OperationError("Unable to decrypt input with these parameters.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,24 +6,9 @@
|
|||||||
|
|
||||||
import Operation from "../Operation.mjs";
|
import Operation from "../Operation.mjs";
|
||||||
import Utils from "../Utils.mjs";
|
import Utils from "../Utils.mjs";
|
||||||
|
import forge from "node-forge/dist/forge.min.js";
|
||||||
import OperationError from "../errors/OperationError.mjs";
|
import OperationError from "../errors/OperationError.mjs";
|
||||||
import { Blowfish } from "../vendor/Blowfish.mjs";
|
import { Blowfish } from "../lib/Blowfish.mjs";
|
||||||
import { toBase64 } from "../lib/Base64.mjs";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Lookup table for Blowfish output types.
|
|
||||||
*/
|
|
||||||
const BLOWFISH_OUTPUT_TYPE_LOOKUP = {
|
|
||||||
Base64: 0, Hex: 1, String: 2, Raw: 3
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Lookup table for Blowfish modes.
|
|
||||||
*/
|
|
||||||
const BLOWFISH_MODE_LOOKUP = {
|
|
||||||
ECB: 0, CBC: 1, PCBC: 2, CFB: 3, OFB: 4, CTR: 5
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Blowfish Encrypt operation
|
* Blowfish Encrypt operation
|
||||||
@@ -58,7 +43,7 @@ class BlowfishEncrypt extends Operation {
|
|||||||
{
|
{
|
||||||
"name": "Mode",
|
"name": "Mode",
|
||||||
"type": "option",
|
"type": "option",
|
||||||
"value": ["CBC", "PCBC", "CFB", "OFB", "CTR", "ECB"]
|
"value": ["CBC", "CFB", "OFB", "CTR", "ECB"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Input",
|
"name": "Input",
|
||||||
@@ -68,7 +53,7 @@ class BlowfishEncrypt extends Operation {
|
|||||||
{
|
{
|
||||||
"name": "Output",
|
"name": "Output",
|
||||||
"type": "option",
|
"type": "option",
|
||||||
"value": ["Hex", "Base64", "Raw"]
|
"value": ["Hex", "Raw"]
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@@ -80,21 +65,29 @@ class BlowfishEncrypt extends Operation {
|
|||||||
*/
|
*/
|
||||||
run(input, args) {
|
run(input, args) {
|
||||||
const key = Utils.convertToByteString(args[0].string, args[0].option),
|
const key = Utils.convertToByteString(args[0].string, args[0].option),
|
||||||
iv = Utils.convertToByteArray(args[1].string, args[1].option),
|
iv = Utils.convertToByteString(args[1].string, args[1].option),
|
||||||
[,, mode, inputType, outputType] = args;
|
mode = args[2],
|
||||||
|
inputType = args[3],
|
||||||
|
outputType = args[4];
|
||||||
|
|
||||||
if (key.length === 0) throw new OperationError("Enter a key");
|
if (key.length !== 8) {
|
||||||
|
throw new OperationError(`Invalid key length: ${key.length} bytes
|
||||||
|
|
||||||
|
Blowfish uses a key length of 8 bytes (64 bits).`);
|
||||||
|
}
|
||||||
|
|
||||||
input = Utils.convertToByteString(input, inputType);
|
input = Utils.convertToByteString(input, inputType);
|
||||||
|
|
||||||
Blowfish.setIV(toBase64(iv), 0);
|
const cipher = Blowfish.createCipher(key, mode);
|
||||||
|
cipher.start({iv: iv});
|
||||||
|
cipher.update(forge.util.createBuffer(input));
|
||||||
|
cipher.finish();
|
||||||
|
|
||||||
const enc = Blowfish.encrypt(input, key, {
|
if (outputType === "Hex") {
|
||||||
outputType: BLOWFISH_OUTPUT_TYPE_LOOKUP[outputType],
|
return cipher.output.toHex();
|
||||||
cipherMode: BLOWFISH_MODE_LOOKUP[mode]
|
} else {
|
||||||
});
|
return cipher.output.getBytes();
|
||||||
|
}
|
||||||
return outputType === "Raw" ? Utils.byteArrayToChars(enc) : enc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ class BlurImage extends Operation {
|
|||||||
async run(input, args) {
|
async run(input, args) {
|
||||||
const [blurAmount, blurType] = args;
|
const [blurAmount, blurType] = args;
|
||||||
|
|
||||||
if (!isImage(new Uint8Array(input))) {
|
if (!isImage(input)) {
|
||||||
throw new OperationError("Invalid file type.");
|
throw new OperationError("Invalid file type.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ class Bombe extends Operation {
|
|||||||
super();
|
super();
|
||||||
|
|
||||||
this.name = "Bombe";
|
this.name = "Bombe";
|
||||||
this.module = "Default";
|
this.module = "Bletchley";
|
||||||
this.description = "Emulation of the Bombe machine used at Bletchley Park to attack Enigma, based on work by Polish and British cryptanalysts.<br><br>To run this you need to have a 'crib', which is some known plaintext for a chunk of the target ciphertext, and know the rotors used. (See the 'Bombe (multiple runs)' operation if you don't know the rotors.) The machine will suggest possible configurations of the Enigma. Each suggestion has the rotor start positions (left to right) and known plugboard pairs.<br><br>Choosing a crib: First, note that Enigma cannot encrypt a letter to itself, which allows you to rule out some positions for possible cribs. Secondly, the Bombe does not simulate the Enigma's middle rotor stepping. The longer your crib, the more likely a step happened within it, which will prevent the attack working. However, other than that, longer cribs are generally better. The attack produces a 'menu' which maps ciphertext letters to plaintext, and the goal is to produce 'loops': for example, with ciphertext ABC and crib CAB, we have the mappings A<->C, B<->A, and C<->B, which produces a loop A-B-C-A. The more loops, the better the crib. The operation will output this: if your menu has too few loops or is too short, a large number of incorrect outputs will usually be produced. Try a different crib. If the menu seems good but the right answer isn't produced, your crib may be wrong, or you may have overlapped the middle rotor stepping - try a different crib.<br><br>Output is not sufficient to fully decrypt the data. You will have to recover the rest of the plugboard settings by inspection. And the ring position is not taken into account: this affects when the middle rotor steps. If your output is correct for a bit, and then goes wrong, adjust the ring and start position on the right-hand rotor together until the output improves. If necessary, repeat for the middle rotor.<br><br>By default this operation runs the checking machine, a manual process to verify the quality of Bombe stops, on each stop, discarding stops which fail. If you want to see how many times the hardware actually stops for a given input, disable the checking machine.<br><br>More detailed descriptions of the Enigma, Typex and Bombe operations <a href='https://github.com/gchq/CyberChef/wiki/Enigma,-the-Bombe,-and-Typex'>can be found here</a>.";
|
this.description = "Emulation of the Bombe machine used at Bletchley Park to attack Enigma, based on work by Polish and British cryptanalysts.<br><br>To run this you need to have a 'crib', which is some known plaintext for a chunk of the target ciphertext, and know the rotors used. (See the 'Bombe (multiple runs)' operation if you don't know the rotors.) The machine will suggest possible configurations of the Enigma. Each suggestion has the rotor start positions (left to right) and known plugboard pairs.<br><br>Choosing a crib: First, note that Enigma cannot encrypt a letter to itself, which allows you to rule out some positions for possible cribs. Secondly, the Bombe does not simulate the Enigma's middle rotor stepping. The longer your crib, the more likely a step happened within it, which will prevent the attack working. However, other than that, longer cribs are generally better. The attack produces a 'menu' which maps ciphertext letters to plaintext, and the goal is to produce 'loops': for example, with ciphertext ABC and crib CAB, we have the mappings A<->C, B<->A, and C<->B, which produces a loop A-B-C-A. The more loops, the better the crib. The operation will output this: if your menu has too few loops or is too short, a large number of incorrect outputs will usually be produced. Try a different crib. If the menu seems good but the right answer isn't produced, your crib may be wrong, or you may have overlapped the middle rotor stepping - try a different crib.<br><br>Output is not sufficient to fully decrypt the data. You will have to recover the rest of the plugboard settings by inspection. And the ring position is not taken into account: this affects when the middle rotor steps. If your output is correct for a bit, and then goes wrong, adjust the ring and start position on the right-hand rotor together until the output improves. If necessary, repeat for the middle rotor.<br><br>By default this operation runs the checking machine, a manual process to verify the quality of Bombe stops, on each stop, discarding stops which fail. If you want to see how many times the hardware actually stops for a given input, disable the checking machine.<br><br>More detailed descriptions of the Enigma, Typex and Bombe operations <a href='https://github.com/gchq/CyberChef/wiki/Enigma,-the-Bombe,-and-Typex'>can be found here</a>.";
|
||||||
this.infoURL = "https://wikipedia.org/wiki/Bombe";
|
this.infoURL = "https://wikipedia.org/wiki/Bombe";
|
||||||
this.inputType = "string";
|
this.inputType = "string";
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ class Bzip2Decompress extends Operation {
|
|||||||
* @param {Object[]} args
|
* @param {Object[]} args
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
run(input, args) {
|
async run(input, args) {
|
||||||
const [small] = args;
|
const [small] = args;
|
||||||
if (input.byteLength <= 0) {
|
if (input.byteLength <= 0) {
|
||||||
throw new OperationError("Please provide an input.");
|
throw new OperationError("Please provide an input.");
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
import Operation from "../Operation.mjs";
|
import Operation from "../Operation.mjs";
|
||||||
import OperationError from "../errors/OperationError.mjs";
|
import OperationError from "../errors/OperationError.mjs";
|
||||||
import cptable from "../vendor/js-codepage/cptable.js";
|
import cptable from "codepage";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Citrix CTX1 Decode operation
|
* Citrix CTX1 Decode operation
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import Operation from "../Operation.mjs";
|
import Operation from "../Operation.mjs";
|
||||||
import cptable from "../vendor/js-codepage/cptable.js";
|
import cptable from "codepage";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Citrix CTX1 Encode operation
|
* Citrix CTX1 Encode operation
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ class ContainImage extends Operation {
|
|||||||
"Bottom": jimp.VERTICAL_ALIGN_BOTTOM
|
"Bottom": jimp.VERTICAL_ALIGN_BOTTOM
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!isImage(new Uint8Array(input))) {
|
if (!isImage(input)) {
|
||||||
throw new OperationError("Invalid file type.");
|
throw new OperationError("Invalid file type.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ class ConvertDataUnits extends Operation {
|
|||||||
const DATA_UNITS = [
|
const DATA_UNITS = [
|
||||||
"Bits (b)", "Nibbles", "Octets", "Bytes (B)",
|
"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)]",
|
"[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)]",
|
"[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)]"
|
"[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];
|
const mime = formatMap[format];
|
||||||
|
|
||||||
if (!isImage(new Uint8Array(input))) {
|
if (!isImage(input)) {
|
||||||
throw new OperationError("Invalid file format.");
|
throw new OperationError("Invalid file format.");
|
||||||
}
|
}
|
||||||
let image;
|
let image;
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ class CoverImage extends Operation {
|
|||||||
"Bottom": jimp.VERTICAL_ALIGN_BOTTOM
|
"Bottom": jimp.VERTICAL_ALIGN_BOTTOM
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!isImage(new Uint8Array(input))) {
|
if (!isImage(input)) {
|
||||||
throw new OperationError("Invalid file type.");
|
throw new OperationError("Invalid file type.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ class CropImage extends Operation {
|
|||||||
*/
|
*/
|
||||||
async run(input, args) {
|
async run(input, args) {
|
||||||
const [xPos, yPos, width, height, autocrop, autoTolerance, autoFrames, autoSymmetric, autoBorder] = 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.");
|
throw new OperationError("Invalid file type.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -73,6 +73,12 @@ class DESDecrypt extends Operation {
|
|||||||
DES uses a key length of 8 bytes (64 bits).
|
DES uses a key length of 8 bytes (64 bits).
|
||||||
Triple DES uses a key length of 24 bytes (192 bits).`);
|
Triple DES uses a key length of 24 bytes (192 bits).`);
|
||||||
}
|
}
|
||||||
|
if (iv.length !== 8 && mode !== "ECB") {
|
||||||
|
throw new OperationError(`Invalid IV length: ${iv.length} bytes
|
||||||
|
|
||||||
|
DES uses an IV length of 8 bytes (64 bits).
|
||||||
|
Make sure you have specified the type correctly (e.g. Hex vs UTF8).`);
|
||||||
|
}
|
||||||
|
|
||||||
input = Utils.convertToByteString(input, inputType);
|
input = Utils.convertToByteString(input, inputType);
|
||||||
|
|
||||||
|
|||||||
@@ -73,6 +73,12 @@ class DESEncrypt extends Operation {
|
|||||||
DES uses a key length of 8 bytes (64 bits).
|
DES uses a key length of 8 bytes (64 bits).
|
||||||
Triple DES uses a key length of 24 bytes (192 bits).`);
|
Triple DES uses a key length of 24 bytes (192 bits).`);
|
||||||
}
|
}
|
||||||
|
if (iv.length !== 8 && mode !== "ECB") {
|
||||||
|
throw new OperationError(`Invalid IV length: ${iv.length} bytes
|
||||||
|
|
||||||
|
DES uses an IV length of 8 bytes (64 bits).
|
||||||
|
Make sure you have specified the type correctly (e.g. Hex vs UTF8).`);
|
||||||
|
}
|
||||||
|
|
||||||
input = Utils.convertToByteString(input, inputType);
|
input = Utils.convertToByteString(input, inputType);
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import Operation from "../Operation.mjs";
|
import Operation from "../Operation.mjs";
|
||||||
import cptable from "../vendor/js-codepage/cptable.js";
|
import cptable from "codepage";
|
||||||
import {IO_FORMAT} from "../lib/ChrEnc.mjs";
|
import {IO_FORMAT} from "../lib/ChrEnc.mjs";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
* @license Apache-2.0
|
* @license Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import Operation from "../Operation";
|
import Operation from "../Operation.mjs";
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -8,6 +8,13 @@ import Operation from "../Operation.mjs";
|
|||||||
import {detectFileType} from "../lib/FileType.mjs";
|
import {detectFileType} from "../lib/FileType.mjs";
|
||||||
import {FILE_SIGNATURES} from "../lib/FileSignatures.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
|
* Detect File Type operation
|
||||||
*/
|
*/
|
||||||
@@ -22,11 +29,7 @@ class DetectFileType extends Operation {
|
|||||||
this.name = "Detect File Type";
|
this.name = "Detect File Type";
|
||||||
this.module = "Default";
|
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: " +
|
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 =>
|
exts + ".";
|
||||||
FILE_SIGNATURES[cat].map(sig =>
|
|
||||||
sig.extension.split(",")[0]
|
|
||||||
).join(", ")
|
|
||||||
).join(", ") + ".";
|
|
||||||
this.infoURL = "https://wikipedia.org/wiki/List_of_file_signatures";
|
this.infoURL = "https://wikipedia.org/wiki/List_of_file_signatures";
|
||||||
this.inputType = "ArrayBuffer";
|
this.inputType = "ArrayBuffer";
|
||||||
this.outputType = "string";
|
this.outputType = "string";
|
||||||
|
|||||||
@@ -47,6 +47,11 @@ class Diff extends Operation {
|
|||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"value": true
|
"value": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "Show subtraction",
|
||||||
|
"type": "boolean",
|
||||||
|
"value": false
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "Ignore whitespace",
|
"name": "Ignore whitespace",
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
@@ -67,6 +72,7 @@ class Diff extends Operation {
|
|||||||
diffBy,
|
diffBy,
|
||||||
showAdded,
|
showAdded,
|
||||||
showRemoved,
|
showRemoved,
|
||||||
|
showSubtraction,
|
||||||
ignoreWhitespace
|
ignoreWhitespace
|
||||||
] = args,
|
] = args,
|
||||||
samples = input.split(sampleDelim);
|
samples = input.split(sampleDelim);
|
||||||
@@ -116,7 +122,7 @@ class Diff extends Operation {
|
|||||||
if (showAdded) output += "<span class='hl5'>" + Utils.escapeHtml(diff[i].value) + "</span>";
|
if (showAdded) output += "<span class='hl5'>" + Utils.escapeHtml(diff[i].value) + "</span>";
|
||||||
} else if (diff[i].removed) {
|
} else if (diff[i].removed) {
|
||||||
if (showRemoved) output += "<span class='hl3'>" + Utils.escapeHtml(diff[i].value) + "</span>";
|
if (showRemoved) output += "<span class='hl3'>" + Utils.escapeHtml(diff[i].value) + "</span>";
|
||||||
} else {
|
} else if (!showSubtraction) {
|
||||||
output += Utils.escapeHtml(diff[i].value);
|
output += Utils.escapeHtml(diff[i].value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ class DitherImage extends Operation {
|
|||||||
* @returns {byteArray}
|
* @returns {byteArray}
|
||||||
*/
|
*/
|
||||||
async run(input, args) {
|
async run(input, args) {
|
||||||
if (!isImage(new Uint8Array(input))) {
|
if (!isImage(input)) {
|
||||||
throw new OperationError("Invalid file type.");
|
throw new OperationError("Invalid file type.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import Operation from "../Operation.mjs";
|
import Operation from "../Operation.mjs";
|
||||||
import cptable from "../vendor/js-codepage/cptable.js";
|
import cptable from "codepage";
|
||||||
import {IO_FORMAT} from "../lib/ChrEnc.mjs";
|
import {IO_FORMAT} from "../lib/ChrEnc.mjs";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ class Enigma extends Operation {
|
|||||||
super();
|
super();
|
||||||
|
|
||||||
this.name = "Enigma";
|
this.name = "Enigma";
|
||||||
this.module = "Default";
|
this.module = "Bletchley";
|
||||||
this.description = "Encipher/decipher with the WW2 Enigma machine.<br><br>Enigma was used by the German military, among others, around the WW2 era as a portable cipher machine to protect sensitive military, diplomatic and commercial communications.<br><br>The standard set of German military rotors and reflectors are provided. To configure the plugboard, enter a string of connected pairs of letters, e.g. <code>AB CD EF</code> connects A to B, C to D, and E to F. This is also used to create your own reflectors. To create your own rotor, enter the letters that the rotor maps A to Z to, in order, optionally followed by <code><</code> then a list of stepping points.<br>This is deliberately fairly permissive with rotor placements etc compared to a real Enigma (on which, for example, a four-rotor Enigma uses only the thin reflectors and the beta or gamma rotor in the 4th slot).<br><br>More detailed descriptions of the Enigma, Typex and Bombe operations <a href='https://github.com/gchq/CyberChef/wiki/Enigma,-the-Bombe,-and-Typex'>can be found here</a>.";
|
this.description = "Encipher/decipher with the WW2 Enigma machine.<br><br>Enigma was used by the German military, among others, around the WW2 era as a portable cipher machine to protect sensitive military, diplomatic and commercial communications.<br><br>The standard set of German military rotors and reflectors are provided. To configure the plugboard, enter a string of connected pairs of letters, e.g. <code>AB CD EF</code> connects A to B, C to D, and E to F. This is also used to create your own reflectors. To create your own rotor, enter the letters that the rotor maps A to Z to, in order, optionally followed by <code><</code> then a list of stepping points.<br>This is deliberately fairly permissive with rotor placements etc compared to a real Enigma (on which, for example, a four-rotor Enigma uses only the thin reflectors and the beta or gamma rotor in the 4th slot).<br><br>More detailed descriptions of the Enigma, Typex and Bombe operations <a href='https://github.com/gchq/CyberChef/wiki/Enigma,-the-Bombe,-and-Typex'>can be found here</a>.";
|
||||||
this.infoURL = "https://wikipedia.org/wiki/Enigma_machine";
|
this.infoURL = "https://wikipedia.org/wiki/Enigma_machine";
|
||||||
this.inputType = "string";
|
this.inputType = "string";
|
||||||
|
|||||||
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) {
|
async run(input, args) {
|
||||||
const [flipAxis] = args;
|
const [flipAxis] = args;
|
||||||
if (!isImage(new Uint8Array(input))) {
|
if (!isImage(input)) {
|
||||||
throw new OperationError("Invalid input file type.");
|
throw new OperationError("Invalid input file type.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -76,8 +76,8 @@ class Fork extends Operation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const recipe = new Recipe();
|
const recipe = new Recipe();
|
||||||
let output = "",
|
const outputs = [];
|
||||||
progress = 0;
|
let progress = 0;
|
||||||
|
|
||||||
state.forkOffset += state.progress + 1;
|
state.forkOffset += state.progress + 1;
|
||||||
|
|
||||||
@@ -104,10 +104,10 @@ class Fork extends Operation {
|
|||||||
}
|
}
|
||||||
progress = err.progress + 1;
|
progress = err.progress + 1;
|
||||||
}
|
}
|
||||||
output += await dish.get(outputType) + mergeDelim;
|
outputs.push(await dish.get(outputType));
|
||||||
}
|
}
|
||||||
|
|
||||||
state.dish.set(output, outputType);
|
state.dish.set(outputs.join(mergeDelim), outputType);
|
||||||
state.progress += progress;
|
state.progress += progress;
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,15 +42,22 @@ class FromBase62 extends Operation {
|
|||||||
*/
|
*/
|
||||||
run(input, args) {
|
run(input, args) {
|
||||||
if (input.length < 1) return [];
|
if (input.length < 1) return [];
|
||||||
const ALPHABET = Utils.expandAlphRange(args[0]).join("");
|
const alphabet = Utils.expandAlphRange(args[0]).join("");
|
||||||
const BN = BigNumber.clone({ ALPHABET });
|
const BN62 = BigNumber.clone({ ALPHABET: alphabet });
|
||||||
|
|
||||||
const re = new RegExp("[^" + ALPHABET.replace(/[[\]\\\-^$]/g, "\\$&") + "]", "g");
|
const re = new RegExp("[^" + alphabet.replace(/[[\]\\\-^$]/g, "\\$&") + "]", "g");
|
||||||
input = input.replace(re, "");
|
input = input.replace(re, "");
|
||||||
|
|
||||||
const number = new BN(input, 62);
|
// Read number in using Base62 alphabet
|
||||||
|
const number = new BN62(input, 62);
|
||||||
|
// Copy to new BigNumber object that uses the default alphabet
|
||||||
|
const normalized = new BigNumber(number);
|
||||||
|
|
||||||
return Utils.convertToByteArray(number.toString(16), "Hex");
|
// Convert to hex and add leading 0 if required
|
||||||
|
let hex = normalized.toString(16);
|
||||||
|
if (hex.length % 2 !== 0) hex = "0" + hex;
|
||||||
|
|
||||||
|
return Utils.convertToByteArray(hex, "Hex");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ class FromQuotedPrintable extends Operation {
|
|||||||
|
|
||||||
this.name = "From Quoted Printable";
|
this.name = "From Quoted Printable";
|
||||||
this.module = "Default";
|
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.infoURL = "https://wikipedia.org/wiki/Quoted-printable";
|
||||||
this.inputType = "string";
|
this.inputType = "string";
|
||||||
this.outputType = "byteArray";
|
this.outputType = "byteArray";
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ class GeneratePGPKeyPair extends Operation {
|
|||||||
* @param {Object[]} args
|
* @param {Object[]} args
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
run(input, args) {
|
async run(input, args) {
|
||||||
const [keyType, keySize] = args[0].split("-"),
|
const [keyType, keySize] = args[0].split("-"),
|
||||||
password = args[1],
|
password = args[1],
|
||||||
name = args[2],
|
name = args[2],
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ class HammingDistance extends Operation {
|
|||||||
samples = input.split(delim);
|
samples = input.split(delim);
|
||||||
|
|
||||||
if (samples.length !== 2) {
|
if (samples.length !== 2) {
|
||||||
throw new OperationError("Error: You can only calculae the edit distance between 2 strings. Please ensure exactly two inputs are provided, separated by the specified delimiter.");
|
throw new OperationError("Error: You can only calculate the edit distance between 2 strings. Please ensure exactly two inputs are provided, separated by the specified delimiter.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (samples[0].length !== samples[1].length) {
|
if (samples[0].length !== samples[1].length) {
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ class ImageBrightnessContrast extends Operation {
|
|||||||
*/
|
*/
|
||||||
async run(input, args) {
|
async run(input, args) {
|
||||||
const [brightness, contrast] = args;
|
const [brightness, contrast] = args;
|
||||||
if (!isImage(new Uint8Array(input))) {
|
if (!isImage(input)) {
|
||||||
throw new OperationError("Invalid file type.");
|
throw new OperationError("Invalid file type.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ class ImageFilter extends Operation {
|
|||||||
*/
|
*/
|
||||||
async run(input, args) {
|
async run(input, args) {
|
||||||
const [filterType] = args;
|
const [filterType] = args;
|
||||||
if (!isImage(new Uint8Array(input))) {
|
if (!isImage(input)) {
|
||||||
throw new OperationError("Invalid file type.");
|
throw new OperationError("Invalid file type.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ class ImageHueSaturationLightness extends Operation {
|
|||||||
async run(input, args) {
|
async run(input, args) {
|
||||||
const [hue, saturation, lightness] = args;
|
const [hue, saturation, lightness] = args;
|
||||||
|
|
||||||
if (!isImage(new Uint8Array(input))) {
|
if (!isImage(input)) {
|
||||||
throw new OperationError("Invalid file type.");
|
throw new OperationError("Invalid file type.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ class ImageOpacity extends Operation {
|
|||||||
*/
|
*/
|
||||||
async run(input, args) {
|
async run(input, args) {
|
||||||
const [opacity] = args;
|
const [opacity] = args;
|
||||||
if (!isImage(new Uint8Array(input))) {
|
if (!isImage(input)) {
|
||||||
throw new OperationError("Invalid file type.");
|
throw new OperationError("Invalid file type.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ class InvertImage extends Operation {
|
|||||||
* @returns {byteArray}
|
* @returns {byteArray}
|
||||||
*/
|
*/
|
||||||
async run(input, args) {
|
async run(input, args) {
|
||||||
if (!isImage(new Uint8Array(input))) {
|
if (!isImage(input)) {
|
||||||
throw new OperationError("Invalid input file format.");
|
throw new OperationError("Invalid input file format.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
759
src/core/operations/Lorenz.mjs
Normal file
759
src/core/operations/Lorenz.mjs
Normal file
@@ -0,0 +1,759 @@
|
|||||||
|
/**
|
||||||
|
* Emulation of the Lorenz SZ40/42a/42b cipher attachment.
|
||||||
|
*
|
||||||
|
* @author VirtualColossus [martin@virtualcolossus.co.uk]
|
||||||
|
* @copyright Crown Copyright 2019
|
||||||
|
* @license Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import Operation from "../Operation";
|
||||||
|
import OperationError from "../errors/OperationError";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lorenz operation
|
||||||
|
*/
|
||||||
|
class Lorenz extends Operation {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lorenz constructor
|
||||||
|
*/
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.name = "Lorenz";
|
||||||
|
this.module = "Bletchley";
|
||||||
|
this.description = "The Lorenz SZ40/42 cipher attachment was a WW2 German rotor cipher machine with twelve rotors which attached in-line between remote teleprinters.<br><br>It used the Vernam cipher with two groups of five rotors (named the psi(ψ) wheels and chi(χ) wheels at Bletchley Park) to create two pseudorandom streams of five bits, encoded in ITA2, which were XOR added to the plaintext. Two other rotors, dubbed the mu(μ) or motor wheels, could hold up the stepping of the psi wheels meaning they stepped intermittently.<br><br>Each rotor has a different number of cams/lugs around their circumference which could be set active or inactive changing the key stream.<br><br>Three models of the Lorenz are emulated, SZ40, SZ42a and SZ42b and three example wheel patterns (the lug settings) are included (KH, ZMUG & BREAM) with the option to set a custom set using the letter 'x' for active or '.' for an inactive lug.<br><br>The input can either be plaintext or ITA2 when sending and ITA2 when receiving.<br><br>To learn more, Virtual Lorenz, an online, browser based simulation of the Lorenz SZ40/42 is available at <a href='https://lorenz.virtualcolossus.co.uk' target='_blank'>https://lorenz.virtualcolossus.co.uk</a>.<br><br>A more detailed description of this operation can be found <a href='https://github.com/gchq/CyberChef/wiki/Lorenz-SZ' target='_blank'>here</a>.";
|
||||||
|
this.infoURL = "https://wikipedia.org/wiki/Lorenz_cipher";
|
||||||
|
this.inputType = "string";
|
||||||
|
this.outputType = "string";
|
||||||
|
this.args = [
|
||||||
|
{
|
||||||
|
name: "Model",
|
||||||
|
type: "option",
|
||||||
|
value: ["SZ40", "SZ42a", "SZ42b"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Wheel Pattern",
|
||||||
|
type: "argSelector",
|
||||||
|
value: [
|
||||||
|
{
|
||||||
|
name: "KH Pattern",
|
||||||
|
off: [19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ZMUG Pattern",
|
||||||
|
off: [19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "BREAM Pattern",
|
||||||
|
off: [19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "No Pattern",
|
||||||
|
off: [19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Custom",
|
||||||
|
on: [19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "KT-Schalter",
|
||||||
|
type: "boolean"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Mode",
|
||||||
|
type: "argSelector",
|
||||||
|
value: [
|
||||||
|
{
|
||||||
|
name: "Send",
|
||||||
|
on: [4],
|
||||||
|
off: [5]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Receive",
|
||||||
|
off: [4],
|
||||||
|
on: [5]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Input Type",
|
||||||
|
type: "option",
|
||||||
|
value: ["Plaintext", "ITA2"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Output Type",
|
||||||
|
type: "option",
|
||||||
|
value: ["Plaintext", "ITA2"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ITA2 Format",
|
||||||
|
type: "option",
|
||||||
|
value: ["5/8/9", "+/-/."]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Ψ1 start (1-43)",
|
||||||
|
type: "number",
|
||||||
|
value: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Ψ2 start (1-47)",
|
||||||
|
type: "number",
|
||||||
|
value: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Ψ3 start (1-51)",
|
||||||
|
type: "number",
|
||||||
|
value: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Ψ4 start (1-53)",
|
||||||
|
type: "number",
|
||||||
|
value: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Ψ5 start (1-59)",
|
||||||
|
type: "number",
|
||||||
|
value: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Μ37 start (1-37)",
|
||||||
|
type: "number",
|
||||||
|
value: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Μ61 start (1-61)",
|
||||||
|
type: "number",
|
||||||
|
value: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Χ1 start (1-41)",
|
||||||
|
type: "number",
|
||||||
|
value: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Χ2 start (1-31)",
|
||||||
|
type: "number",
|
||||||
|
value: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Χ3 start (1-29)",
|
||||||
|
type: "number",
|
||||||
|
value: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Χ4 start (1-26)",
|
||||||
|
type: "number",
|
||||||
|
value: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Χ5 start (1-23)",
|
||||||
|
type: "number",
|
||||||
|
value: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Ψ1 lugs (43)",
|
||||||
|
type: "string",
|
||||||
|
value: ".x...xx.x.x..xxx.x.x.xxxx.x.x.x.x.x..x.xx.x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Ψ2 lugs (47)",
|
||||||
|
type: "string",
|
||||||
|
value: ".xx.x.xxx..x.x.x..x.xx.x.xxx.x....x.xx.x.x.x..x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Ψ3 lugs (51)",
|
||||||
|
type: "string",
|
||||||
|
value: ".x.x.x..xxx....x.x.xx.x.x.x..xxx.x.x..x.x.xx..x.x.x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Ψ4 lugs (53)",
|
||||||
|
type: "string",
|
||||||
|
value: ".xx...xxxxx.x.x.xx...x.xx.x.x..x.x.xx.x..x.x.x.x.x.x."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Ψ5 lugs (59)",
|
||||||
|
type: "string",
|
||||||
|
value: "xx...xx.x..x.xx.x...x.x.x.x.x.x.x.x.xx..xxxx.x.x...xx.x..x."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Μ37 lugs (37)",
|
||||||
|
type: "string",
|
||||||
|
value: "x.x.x.x.x.x...x.x.x...x.x.x...x.x...."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Μ61 lugs (61)",
|
||||||
|
type: "string",
|
||||||
|
value: ".xxxx.xxxx.xxx.xxxx.xx....xxx.xxxx.xxxx.xxxx.xxxx.xxx.xxxx..."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Χ1 lugs (41)",
|
||||||
|
type: "string",
|
||||||
|
value: ".x...xxx.x.xxxx.x...x.x..xxx....xx.xxxx.."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Χ2 lugs (31)",
|
||||||
|
type: "string",
|
||||||
|
value: "x..xxx...x.xxxx..xx..x..xx.xx.."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Χ3 lugs (29)",
|
||||||
|
type: "string",
|
||||||
|
value: "..xx..x.xxx...xx...xx..xx.xx."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Χ4 lugs (26)",
|
||||||
|
type: "string",
|
||||||
|
value: "xx..x..xxxx..xx.xxx....x.."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Χ5 lugs (23)",
|
||||||
|
type: "string",
|
||||||
|
value: "xx..xx....xxxx.x..x.x.."
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} input
|
||||||
|
* @param {Object[]} args
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
run(input, args) {
|
||||||
|
|
||||||
|
const model = args[0],
|
||||||
|
pattern = args[1],
|
||||||
|
kt = args[2],
|
||||||
|
mode = args[3],
|
||||||
|
intype = args[4],
|
||||||
|
outtype = args[5],
|
||||||
|
format = args[6],
|
||||||
|
lugs1 = args[19],
|
||||||
|
lugs2 = args[20],
|
||||||
|
lugs3 = args[21],
|
||||||
|
lugs4 = args[22],
|
||||||
|
lugs5 = args[23],
|
||||||
|
lugm37 = args[24],
|
||||||
|
lugm61 = args[25],
|
||||||
|
lugx1 = args[26],
|
||||||
|
lugx2 = args[27],
|
||||||
|
lugx3 = args[28],
|
||||||
|
lugx4 = args[29],
|
||||||
|
lugx5 = args[30];
|
||||||
|
|
||||||
|
let s1 = args[7],
|
||||||
|
s2 = args[8],
|
||||||
|
s3 = args[9],
|
||||||
|
s4 = args[10],
|
||||||
|
s5 = args[11],
|
||||||
|
m37 = args[12],
|
||||||
|
m61 = args[13],
|
||||||
|
x1 = args[14],
|
||||||
|
x2 = args[15],
|
||||||
|
x3 = args[16],
|
||||||
|
x4 = args[17],
|
||||||
|
x5 = args[18];
|
||||||
|
|
||||||
|
this.reverseTable();
|
||||||
|
|
||||||
|
if (s1<1 || s1>43) throw new OperationError("Ψ1 start must be between 1 and 43");
|
||||||
|
if (s2<1 || s2>47) throw new OperationError("Ψ2 start must be between 1 and 47");
|
||||||
|
if (s3<1 || s3>51) throw new OperationError("Ψ3 start must be between 1 and 51");
|
||||||
|
if (s4<1 || s4>53) throw new OperationError("Ψ4 start must be between 1 and 53");
|
||||||
|
if (s5<1 || s5>59) throw new OperationError("Ψ5 start must be between 1 and 59");
|
||||||
|
if (m37<1 || m37>37) throw new OperationError("Μ37 start must be between 1 and 37");
|
||||||
|
if (m61<1 || m61>61) throw new OperationError("Μ61 start must be between 1 and 61");
|
||||||
|
if (x1<1 || x1>41) throw new OperationError("Χ1 start must be between 1 and 41");
|
||||||
|
if (x2<1 || x2>31) throw new OperationError("Χ2 start must be between 1 and 31");
|
||||||
|
if (x3<1 || x3>29) throw new OperationError("Χ3 start must be between 1 and 29");
|
||||||
|
if (x4<1 || x4>26) throw new OperationError("Χ4 start must be between 1 and 26");
|
||||||
|
if (x5<1 || x5>23) throw new OperationError("Χ5 start must be between 1 and 23");
|
||||||
|
|
||||||
|
// Initialise chosen wheel pattern
|
||||||
|
let chosenSetting = "";
|
||||||
|
if (pattern === "Custom") {
|
||||||
|
const re = new RegExp("^[.xX]*$");
|
||||||
|
if (lugs1.length !== 43 || !re.test(lugs1)) throw new OperationError("Ψ1 custom lugs must be 43 long and can only include . or x ");
|
||||||
|
if (lugs2.length !== 47 || !re.test(lugs2)) throw new OperationError("Ψ2 custom lugs must be 47 long and can only include . or x");
|
||||||
|
if (lugs3.length !== 51 || !re.test(lugs3)) throw new OperationError("Ψ3 custom lugs must be 51 long and can only include . or x");
|
||||||
|
if (lugs4.length !== 53 || !re.test(lugs4)) throw new OperationError("Ψ4 custom lugs must be 53 long and can only include . or x");
|
||||||
|
if (lugs5.length !== 59 || !re.test(lugs5)) throw new OperationError("Ψ5 custom lugs must be 59 long and can only include . or x");
|
||||||
|
if (lugm37.length !== 37 || !re.test(lugm37)) throw new OperationError("M37 custom lugs must be 37 long and can only include . or x");
|
||||||
|
if (lugm61.length !== 61 || !re.test(lugm61)) throw new OperationError("M61 custom lugs must be 61 long and can only include . or x");
|
||||||
|
if (lugx1.length !== 41 || !re.test(lugx1)) throw new OperationError("Χ1 custom lugs must be 41 long and can only include . or x");
|
||||||
|
if (lugx2.length !== 31 || !re.test(lugx2)) throw new OperationError("Χ2 custom lugs must be 31 long and can only include . or x");
|
||||||
|
if (lugx3.length !== 29 || !re.test(lugx3)) throw new OperationError("Χ3 custom lugs must be 29 long and can only include . or x");
|
||||||
|
if (lugx4.length !== 26 || !re.test(lugx4)) throw new OperationError("Χ4 custom lugs must be 26 long and can only include . or x");
|
||||||
|
if (lugx5.length !== 23 || !re.test(lugx5)) throw new OperationError("Χ5 custom lugs must be 23 long and can only include . or x");
|
||||||
|
chosenSetting = INIT_PATTERNS["No Pattern"];
|
||||||
|
chosenSetting.S[1] = this.readLugs(lugs1);
|
||||||
|
chosenSetting.S[2] = this.readLugs(lugs2);
|
||||||
|
chosenSetting.S[3] = this.readLugs(lugs3);
|
||||||
|
chosenSetting.S[4] = this.readLugs(lugs4);
|
||||||
|
chosenSetting.S[5] = this.readLugs(lugs5);
|
||||||
|
chosenSetting.M[1] = this.readLugs(lugm37);
|
||||||
|
chosenSetting.M[2] = this.readLugs(lugm61);
|
||||||
|
chosenSetting.X[1] = this.readLugs(lugx1);
|
||||||
|
chosenSetting.X[2] = this.readLugs(lugx2);
|
||||||
|
chosenSetting.X[3] = this.readLugs(lugx3);
|
||||||
|
chosenSetting.X[4] = this.readLugs(lugx4);
|
||||||
|
chosenSetting.X[5] = this.readLugs(lugx5);
|
||||||
|
} else {
|
||||||
|
chosenSetting = INIT_PATTERNS[pattern];
|
||||||
|
}
|
||||||
|
const chiSettings = chosenSetting.X; // Pin settings for Chi links (X)
|
||||||
|
const psiSettings = chosenSetting.S; // Pin settings for Psi links (S)
|
||||||
|
const muSettings = chosenSetting.M; // Pin settings for Motor links (M)
|
||||||
|
|
||||||
|
// Convert input text to ITA2 (including figure/letter shifts)
|
||||||
|
const ita2Input = this.convertToITA2(input, intype, mode);
|
||||||
|
|
||||||
|
let thisPsi = [];
|
||||||
|
let thisChi = [];
|
||||||
|
let m61lug = muSettings[1][m61-1];
|
||||||
|
let m37lug = muSettings[2][m37-1];
|
||||||
|
const p5 = [0, 0, 0];
|
||||||
|
|
||||||
|
const self = this;
|
||||||
|
const letters = Array.prototype.map.call(ita2Input, function(character) {
|
||||||
|
const letter = character.toUpperCase();
|
||||||
|
|
||||||
|
// Store lugs used in limitations, need these later
|
||||||
|
let x2bptr = x2+1;
|
||||||
|
if (x2bptr===32) x2bptr=1;
|
||||||
|
let s1bptr = s1+1;
|
||||||
|
if (s1bptr===44) s1bptr=1;
|
||||||
|
|
||||||
|
thisChi = [
|
||||||
|
chiSettings[1][x1-1],
|
||||||
|
chiSettings[2][x2-1],
|
||||||
|
chiSettings[3][x3-1],
|
||||||
|
chiSettings[4][x4-1],
|
||||||
|
chiSettings[5][x5-1]
|
||||||
|
];
|
||||||
|
|
||||||
|
thisPsi = [
|
||||||
|
psiSettings[1][s1-1],
|
||||||
|
psiSettings[2][s2-1],
|
||||||
|
psiSettings[3][s3-1],
|
||||||
|
psiSettings[4][s4-1],
|
||||||
|
psiSettings[5][s5-1]
|
||||||
|
];
|
||||||
|
|
||||||
|
if (typeof ITA2_TABLE[letter] == "undefined") {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
// The encipher calculation
|
||||||
|
|
||||||
|
// We calculate Bitwise XOR for each of the 5 bits across our input ( K XOR Psi XOR Chi )
|
||||||
|
const xorSum = [];
|
||||||
|
for (let i=0;i<=4;i++) {
|
||||||
|
xorSum[i] = ITA2_TABLE[letter][i] ^ thisPsi[i] ^ thisChi[i];
|
||||||
|
}
|
||||||
|
const resultStr = xorSum.join("");
|
||||||
|
|
||||||
|
// Wheel movement
|
||||||
|
|
||||||
|
// Chi wheels always move one back after each letter
|
||||||
|
if (--x1 < 1) x1 = 41;
|
||||||
|
if (--x2 < 1) x2 = 31;
|
||||||
|
if (--x3 < 1) x3 = 29;
|
||||||
|
if (--x4 < 1) x4 = 26;
|
||||||
|
if (--x5 < 1) x5 = 23;
|
||||||
|
|
||||||
|
// Motor wheel (61 pin) also moves one each letter
|
||||||
|
if (--m61 < 1) m61 = 61;
|
||||||
|
|
||||||
|
// If M61 is set, we also move M37
|
||||||
|
if (m61lug === 1) {
|
||||||
|
if (--m37 < 1) m37 = 37;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Psi wheels only move sometimes, dependent on M37 current setting and limitations
|
||||||
|
|
||||||
|
const basicmotor = m37lug;
|
||||||
|
let totalmotor = basicmotor;
|
||||||
|
let lim = 0;
|
||||||
|
|
||||||
|
p5[2] = p5[1];
|
||||||
|
p5[1] = p5[0];
|
||||||
|
if (mode==="Send") {
|
||||||
|
p5[0] = parseInt(ITA2_TABLE[letter][4], 10);
|
||||||
|
} else {
|
||||||
|
p5[0] = parseInt(xorSum[4], 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Limitations here
|
||||||
|
if (model==="SZ42a") {
|
||||||
|
// Chi 2 one back lim - The active character of Chi 2 (2nd Chi wheel) in the previous position
|
||||||
|
lim = parseInt(chiSettings[2][x2bptr-1], 10);
|
||||||
|
if (kt) {
|
||||||
|
//p5 back 2
|
||||||
|
if (lim===p5[2]) {
|
||||||
|
lim = 0;
|
||||||
|
} else {
|
||||||
|
lim=1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If basic motor = 0 and limitation = 1, Total motor = 0 [no move], otherwise, total motor = 1 [move]
|
||||||
|
if (basicmotor===0 && lim===1) {
|
||||||
|
totalmotor = 0;
|
||||||
|
} else {
|
||||||
|
totalmotor = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (model==="SZ42b") {
|
||||||
|
// Chi 2 one back + Psi 1 one back.
|
||||||
|
const x2b1lug = parseInt(chiSettings[2][x2bptr-1], 10);
|
||||||
|
const s1b1lug = parseInt(psiSettings[1][s1bptr-1], 10);
|
||||||
|
lim = 1;
|
||||||
|
if (x2b1lug===s1b1lug) lim=0;
|
||||||
|
if (kt) {
|
||||||
|
//p5 back 2
|
||||||
|
if (lim===p5[2]) {
|
||||||
|
lim=0;
|
||||||
|
} else {
|
||||||
|
lim=1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If basic motor = 0 and limitation = 1, Total motor = 0 [no move], otherwise, total motor = 1 [move]
|
||||||
|
if (basicmotor===0 && lim===1) {
|
||||||
|
totalmotor = 0;
|
||||||
|
} else {
|
||||||
|
totalmotor = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (model==="SZ40") {
|
||||||
|
// SZ40 - just move based on the M37 motor wheel
|
||||||
|
totalmotor = basicmotor;
|
||||||
|
} else {
|
||||||
|
throw new OperationError("Lorenz model type not recognised");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move the Psi wheels when current totalmotor active
|
||||||
|
if (totalmotor === 1) {
|
||||||
|
if (--s1 < 1) s1 = 43;
|
||||||
|
if (--s2 < 1) s2 = 47;
|
||||||
|
if (--s3 < 1) s3 = 51;
|
||||||
|
if (--s4 < 1) s4 = 53;
|
||||||
|
if (--s5 < 1) s5 = 59;
|
||||||
|
}
|
||||||
|
|
||||||
|
m61lug = muSettings[1][m61-1];
|
||||||
|
m37lug = muSettings[2][m37-1];
|
||||||
|
|
||||||
|
let rtnstr = self.REVERSE_ITA2_TABLE[resultStr];
|
||||||
|
if (format==="5/8/9") {
|
||||||
|
if (rtnstr==="+") rtnstr="5"; // + or 5 used to represent figure shift
|
||||||
|
if (rtnstr==="-") rtnstr="8"; // - or 8 used to represent letter shift
|
||||||
|
if (rtnstr===".") rtnstr="9"; // . or 9 used to represent space
|
||||||
|
}
|
||||||
|
return rtnstr;
|
||||||
|
});
|
||||||
|
|
||||||
|
const ita2output = letters.join("");
|
||||||
|
|
||||||
|
return this.convertFromITA2(ita2output, outtype, mode);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverses the ITA2 Code lookup table
|
||||||
|
*/
|
||||||
|
reverseTable() {
|
||||||
|
this.REVERSE_ITA2_TABLE = {};
|
||||||
|
this.REVERSE_FIGSHIFT_TABLE = {};
|
||||||
|
|
||||||
|
for (const letter in ITA2_TABLE) {
|
||||||
|
const code = ITA2_TABLE[letter];
|
||||||
|
this.REVERSE_ITA2_TABLE[code] = letter;
|
||||||
|
}
|
||||||
|
for (const letter in figShiftArr) {
|
||||||
|
const ltr = figShiftArr[letter];
|
||||||
|
this.REVERSE_FIGSHIFT_TABLE[ltr] = letter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read lugs settings - convert to 0|1
|
||||||
|
*/
|
||||||
|
readLugs(lugstr) {
|
||||||
|
const arr = Array.prototype.map.call(lugstr, function(lug) {
|
||||||
|
if (lug===".") {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return arr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert input plaintext to ITA2
|
||||||
|
*/
|
||||||
|
convertToITA2(input, intype, mode) {
|
||||||
|
let result = "";
|
||||||
|
let figShifted = false;
|
||||||
|
|
||||||
|
for (const character of input) {
|
||||||
|
const letter = character.toUpperCase();
|
||||||
|
|
||||||
|
// Convert input text to ITA2 (including figure/letter shifts)
|
||||||
|
if (intype === "ITA2" || mode === "Receive") {
|
||||||
|
if (validITA2.indexOf(letter) === -1) {
|
||||||
|
let errltr = letter;
|
||||||
|
if (errltr==="\n") errltr = "Carriage Return";
|
||||||
|
if (errltr===" ") errltr = "Space";
|
||||||
|
throw new OperationError("Invalid ITA2 character : "+errltr);
|
||||||
|
}
|
||||||
|
result += letter;
|
||||||
|
} else {
|
||||||
|
if (validChars.indexOf(letter) === -1) throw new OperationError("Invalid Plaintext character : "+letter);
|
||||||
|
|
||||||
|
if (!figShifted && figShiftedChars.indexOf(letter) !== -1) {
|
||||||
|
// in letters mode and next char needs to be figure shifted
|
||||||
|
figShifted = true;
|
||||||
|
result += "55" + figShiftArr[letter];
|
||||||
|
} else if (figShifted) {
|
||||||
|
// in figures mode and next char needs to be letter shifted
|
||||||
|
if (letter==="\n") {
|
||||||
|
result += "34";
|
||||||
|
} else if (letter==="\r") {
|
||||||
|
result += "4";
|
||||||
|
} else if (figShiftedChars.indexOf(letter) === -1) {
|
||||||
|
figShifted = false;
|
||||||
|
result += "88" + letter;
|
||||||
|
} else {
|
||||||
|
result += figShiftArr[letter];
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (letter==="\n") {
|
||||||
|
result += "34";
|
||||||
|
} else if (letter==="\r") {
|
||||||
|
result += "4";
|
||||||
|
} else {
|
||||||
|
result += letter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert final result ITA2 to plaintext
|
||||||
|
*/
|
||||||
|
convertFromITA2(input, outtype, mode) {
|
||||||
|
let result = "";
|
||||||
|
let figShifted = false;
|
||||||
|
for (const letter of input) {
|
||||||
|
if (mode === "Receive") {
|
||||||
|
|
||||||
|
// Convert output ITA2 to plaintext (including figure/letter shifts)
|
||||||
|
if (outtype === "Plaintext") {
|
||||||
|
|
||||||
|
if (letter === "5" || letter === "+") {
|
||||||
|
figShifted = true;
|
||||||
|
} else if (letter === "8" || letter === "-") {
|
||||||
|
figShifted = false;
|
||||||
|
} else if (letter === "9") {
|
||||||
|
result += " ";
|
||||||
|
} else if (letter === "3") {
|
||||||
|
result += "\n";
|
||||||
|
} else if (letter === "4") {
|
||||||
|
result += "";
|
||||||
|
} else if (letter === "/") {
|
||||||
|
result += "/";
|
||||||
|
} else {
|
||||||
|
|
||||||
|
if (figShifted) {
|
||||||
|
result += this.REVERSE_FIGSHIFT_TABLE[letter];
|
||||||
|
} else {
|
||||||
|
result += letter;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
result += letter;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
result += letter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const ITA2_TABLE = {
|
||||||
|
"A": "11000",
|
||||||
|
"B": "10011",
|
||||||
|
"C": "01110",
|
||||||
|
"D": "10010",
|
||||||
|
"E": "10000",
|
||||||
|
"F": "10110",
|
||||||
|
"G": "01011",
|
||||||
|
"H": "00101",
|
||||||
|
"I": "01100",
|
||||||
|
"J": "11010",
|
||||||
|
"K": "11110",
|
||||||
|
"L": "01001",
|
||||||
|
"M": "00111",
|
||||||
|
"N": "00110",
|
||||||
|
"O": "00011",
|
||||||
|
"P": "01101",
|
||||||
|
"Q": "11101",
|
||||||
|
"R": "01010",
|
||||||
|
"S": "10100",
|
||||||
|
"T": "00001",
|
||||||
|
"U": "11100",
|
||||||
|
"V": "01111",
|
||||||
|
"W": "11001",
|
||||||
|
"X": "10111",
|
||||||
|
"Y": "10101",
|
||||||
|
"Z": "10001",
|
||||||
|
"3": "00010",
|
||||||
|
"4": "01000",
|
||||||
|
"9": "00100",
|
||||||
|
"/": "00000",
|
||||||
|
" ": "00100",
|
||||||
|
".": "00100",
|
||||||
|
"8": "11111",
|
||||||
|
"5": "11011",
|
||||||
|
"-": "11111",
|
||||||
|
"+": "11011"
|
||||||
|
};
|
||||||
|
|
||||||
|
const validChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890+-'()/:=?,. \n\r";
|
||||||
|
const validITA2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ34589+-./";
|
||||||
|
const figShiftedChars = "1234567890+-'()/:=?,.";
|
||||||
|
|
||||||
|
const figShiftArr = {
|
||||||
|
"1": "Q",
|
||||||
|
"2": "W",
|
||||||
|
"3": "E",
|
||||||
|
"4": "R",
|
||||||
|
"5": "T",
|
||||||
|
"6": "Y",
|
||||||
|
"7": "U",
|
||||||
|
"8": "I",
|
||||||
|
"9": "O",
|
||||||
|
"0": "P",
|
||||||
|
" ": "9",
|
||||||
|
"-": "A",
|
||||||
|
"?": "B",
|
||||||
|
":": "C",
|
||||||
|
"#": "D",
|
||||||
|
"%": "F",
|
||||||
|
"@": "G",
|
||||||
|
"£": "H",
|
||||||
|
"": "J",
|
||||||
|
"(": "K",
|
||||||
|
")": "L",
|
||||||
|
".": "M",
|
||||||
|
",": "N",
|
||||||
|
"'": "S",
|
||||||
|
"=": "V",
|
||||||
|
"/": "X",
|
||||||
|
"+": "Z",
|
||||||
|
"\n": "3",
|
||||||
|
"\r": "4"
|
||||||
|
};
|
||||||
|
|
||||||
|
const INIT_PATTERNS = {
|
||||||
|
"No Pattern": {
|
||||||
|
"X": {
|
||||||
|
1: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||||
|
2: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||||
|
3: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||||
|
4: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||||
|
5: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
||||||
|
},
|
||||||
|
"S": {
|
||||||
|
1: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||||
|
2: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||||
|
3: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||||
|
4: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||||
|
5: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
||||||
|
},
|
||||||
|
"M": {
|
||||||
|
1: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||||
|
2: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
"KH Pattern": {
|
||||||
|
"X": {
|
||||||
|
1: [0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0],
|
||||||
|
2: [1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0],
|
||||||
|
3: [0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0],
|
||||||
|
4: [1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0],
|
||||||
|
5: [1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0]
|
||||||
|
},
|
||||||
|
"S": {
|
||||||
|
1: [0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1],
|
||||||
|
2: [0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1],
|
||||||
|
3: [0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1],
|
||||||
|
4: [0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0],
|
||||||
|
5: [1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0]
|
||||||
|
},
|
||||||
|
"M": {
|
||||||
|
1: [0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0],
|
||||||
|
2: [1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ZMUG Pattern": {
|
||||||
|
"X": {
|
||||||
|
1: [0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0],
|
||||||
|
2: [1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0],
|
||||||
|
3: [0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0],
|
||||||
|
4: [1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1],
|
||||||
|
5: [0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1]
|
||||||
|
},
|
||||||
|
"S": {
|
||||||
|
1: [1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0],
|
||||||
|
2: [0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1],
|
||||||
|
3: [0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1],
|
||||||
|
4: [0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1],
|
||||||
|
5: [1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0]
|
||||||
|
},
|
||||||
|
"M": {
|
||||||
|
1: [1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1],
|
||||||
|
2: [0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"BREAM Pattern": {
|
||||||
|
"X": {
|
||||||
|
1: [0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0],
|
||||||
|
2: [0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1],
|
||||||
|
3: [1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0],
|
||||||
|
4: [1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0],
|
||||||
|
5: [0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0]
|
||||||
|
},
|
||||||
|
"S": {
|
||||||
|
1: [0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0],
|
||||||
|
2: [1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0],
|
||||||
|
3: [1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
|
||||||
|
4: [0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1],
|
||||||
|
5: [1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0]
|
||||||
|
},
|
||||||
|
"M": {
|
||||||
|
1: [1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1],
|
||||||
|
2: [0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Lorenz;
|
||||||
@@ -54,7 +54,7 @@ class MultipleBombe extends Operation {
|
|||||||
super();
|
super();
|
||||||
|
|
||||||
this.name = "Multiple Bombe";
|
this.name = "Multiple Bombe";
|
||||||
this.module = "Default";
|
this.module = "Bletchley";
|
||||||
this.description = "Emulation of the Bombe machine used to attack Enigma. This version carries out multiple Bombe runs to handle unknown rotor configurations.<br><br>You should test your menu on the single Bombe operation before running it here. See the description of the Bombe operation for instructions on choosing a crib.<br><br>More detailed descriptions of the Enigma, Typex and Bombe operations <a href='https://github.com/gchq/CyberChef/wiki/Enigma,-the-Bombe,-and-Typex'>can be found here</a>.";
|
this.description = "Emulation of the Bombe machine used to attack Enigma. This version carries out multiple Bombe runs to handle unknown rotor configurations.<br><br>You should test your menu on the single Bombe operation before running it here. See the description of the Bombe operation for instructions on choosing a crib.<br><br>More detailed descriptions of the Enigma, Typex and Bombe operations <a href='https://github.com/gchq/CyberChef/wiki/Enigma,-the-Bombe,-and-Typex'>can be found here</a>.";
|
||||||
this.infoURL = "https://wikipedia.org/wiki/Bombe";
|
this.infoURL = "https://wikipedia.org/wiki/Bombe";
|
||||||
this.inputType = "string";
|
this.inputType = "string";
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ class NormaliseImage extends Operation {
|
|||||||
* @returns {byteArray}
|
* @returns {byteArray}
|
||||||
*/
|
*/
|
||||||
async run(input, args) {
|
async run(input, args) {
|
||||||
if (!isImage(new Uint8Array(input))) {
|
if (!isImage(input)) {
|
||||||
throw new OperationError("Invalid file type.");
|
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;
|
||||||
@@ -128,8 +128,7 @@ class PHPDeserialize extends Operation {
|
|||||||
switch (kind) {
|
switch (kind) {
|
||||||
case "n":
|
case "n":
|
||||||
expect(";");
|
expect(";");
|
||||||
return "";
|
return "null";
|
||||||
|
|
||||||
case "i":
|
case "i":
|
||||||
case "d":
|
case "d":
|
||||||
case "b": {
|
case "b": {
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ class ParseQRCode extends Operation {
|
|||||||
async run(input, args) {
|
async run(input, args) {
|
||||||
const [normalise] = args;
|
const [normalise] = args;
|
||||||
|
|
||||||
if (!isImage(new Uint8Array(input))) {
|
if (!isImage(input)) {
|
||||||
throw new OperationError("Invalid file type.");
|
throw new OperationError("Invalid file type.");
|
||||||
}
|
}
|
||||||
return await parseQrCode(input, normalise);
|
return await parseQrCode(input, normalise);
|
||||||
|
|||||||
@@ -4,11 +4,11 @@
|
|||||||
* @license Apache-2.0
|
* @license Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import Operation from "../Operation";
|
import Operation from "../Operation.mjs";
|
||||||
import OperationError from "../errors/OperationError";
|
import OperationError from "../errors/OperationError.mjs";
|
||||||
import Utils from "../Utils";
|
import Utils from "../Utils.mjs";
|
||||||
import { fromBase64 } from "../lib/Base64";
|
import { fromBase64 } from "../lib/Base64.mjs";
|
||||||
import { fromHex, toHexFast } from "../lib/Hex";
|
import { fromHex, toHexFast } from "../lib/Hex.mjs";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse SSH Host Key operation
|
* Parse SSH Host Key operation
|
||||||
|
|||||||
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;
|
||||||
@@ -77,7 +77,7 @@ class RawInflate extends Operation {
|
|||||||
}),
|
}),
|
||||||
result = new Uint8Array(inflate.decompress());
|
result = new Uint8Array(inflate.decompress());
|
||||||
|
|
||||||
// Raw Inflate somethimes messes up and returns nonsense like this:
|
// Raw Inflate sometimes messes up and returns nonsense like this:
|
||||||
// ]....]....]....]....]....]....]....]....]....]....]....]....]....]...
|
// ]....]....]....]....]....]....]....]....]....]....]....]....]....]...
|
||||||
// e.g. Input data of [8b, 1d, dc, 44]
|
// e.g. Input data of [8b, 1d, dc, 44]
|
||||||
// Look for the first two square brackets:
|
// Look for the first two square brackets:
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ class RemoveWhitespace extends Operation {
|
|||||||
run(input, args) {
|
run(input, args) {
|
||||||
const [
|
const [
|
||||||
removeSpaces,
|
removeSpaces,
|
||||||
removeCariageReturns,
|
removeCarriageReturns,
|
||||||
removeLineFeeds,
|
removeLineFeeds,
|
||||||
removeTabs,
|
removeTabs,
|
||||||
removeFormFeeds,
|
removeFormFeeds,
|
||||||
@@ -73,7 +73,7 @@ class RemoveWhitespace extends Operation {
|
|||||||
let data = input;
|
let data = input;
|
||||||
|
|
||||||
if (removeSpaces) data = data.replace(/ /g, "");
|
if (removeSpaces) data = data.replace(/ /g, "");
|
||||||
if (removeCariageReturns) data = data.replace(/\r/g, "");
|
if (removeCarriageReturns) data = data.replace(/\r/g, "");
|
||||||
if (removeLineFeeds) data = data.replace(/\n/g, "");
|
if (removeLineFeeds) data = data.replace(/\n/g, "");
|
||||||
if (removeTabs) data = data.replace(/\t/g, "");
|
if (removeTabs) data = data.replace(/\t/g, "");
|
||||||
if (removeFormFeeds) data = data.replace(/\f/g, "");
|
if (removeFormFeeds) data = data.replace(/\f/g, "");
|
||||||
|
|||||||
69
src/core/operations/RenderMarkdown.mjs
Normal file
69
src/core/operations/RenderMarkdown.mjs
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
/**
|
||||||
|
* @author j433866 [j433866@gmail.com]
|
||||||
|
* @copyright Crown Copyright 2019
|
||||||
|
* @license Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import Operation from "../Operation.mjs";
|
||||||
|
import MarkdownIt from "markdown-it";
|
||||||
|
import hljs from "highlight.js";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render Markdown operation
|
||||||
|
*/
|
||||||
|
class RenderMarkdown extends Operation {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RenderMarkdown constructor
|
||||||
|
*/
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.name = "Render Markdown";
|
||||||
|
this.module = "Code";
|
||||||
|
this.description = "Renders input Markdown as HTML. HTML rendering is disabled to avoid XSS.";
|
||||||
|
this.infoURL = "https://wikipedia.org/wiki/Markdown";
|
||||||
|
this.inputType = "string";
|
||||||
|
this.outputType = "html";
|
||||||
|
this.args = [
|
||||||
|
{
|
||||||
|
name: "Autoconvert URLs to links",
|
||||||
|
type: "boolean",
|
||||||
|
value: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Enable syntax highlighting",
|
||||||
|
type: "boolean",
|
||||||
|
value: true
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} input
|
||||||
|
* @param {Object[]} args
|
||||||
|
* @returns {html}
|
||||||
|
*/
|
||||||
|
run(input, args) {
|
||||||
|
const [convertLinks, enableHighlighting] = args,
|
||||||
|
md = new MarkdownIt({
|
||||||
|
linkify: convertLinks,
|
||||||
|
html: false, // Explicitly disable HTML rendering
|
||||||
|
highlight: function(str, lang) {
|
||||||
|
if (lang && hljs.getLanguage(lang) && enableHighlighting) {
|
||||||
|
try {
|
||||||
|
return hljs.highlight(lang, str).value;
|
||||||
|
} catch (__) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
rendered = md.render(input);
|
||||||
|
|
||||||
|
return `<div style="font-family: var(--primary-font-family)">${rendered}</div>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default RenderMarkdown;
|
||||||
@@ -87,7 +87,7 @@ class ResizeImage extends Operation {
|
|||||||
"Bezier": jimp.RESIZE_BEZIER
|
"Bezier": jimp.RESIZE_BEZIER
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!isImage(new Uint8Array(input))) {
|
if (!isImage(input)) {
|
||||||
throw new OperationError("Invalid file type.");
|
throw new OperationError("Invalid file type.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ class RotateImage extends Operation {
|
|||||||
async run(input, args) {
|
async run(input, args) {
|
||||||
const [degrees] = args;
|
const [degrees] = args;
|
||||||
|
|
||||||
if (!isImage(new Uint8Array(input))) {
|
if (!isImage(input)) {
|
||||||
throw new OperationError("Invalid file type.");
|
throw new OperationError("Invalid file type.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ class SharpenImage extends Operation {
|
|||||||
async run(input, args) {
|
async run(input, args) {
|
||||||
const [radius, amount, threshold] = args;
|
const [radius, amount, threshold] = args;
|
||||||
|
|
||||||
if (!isImage(new Uint8Array(input))) {
|
if (!isImage(input)) {
|
||||||
throw new OperationError("Invalid file type.");
|
throw new OperationError("Invalid file type.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
113
src/core/operations/ShowOnMap.mjs
Normal file
113
src/core/operations/ShowOnMap.mjs
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
/**
|
||||||
|
* @author j433866 [j433866@gmail.com]
|
||||||
|
* @copyright Crown Copyright 2019
|
||||||
|
* @license Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import Operation from "../Operation.mjs";
|
||||||
|
import {FORMATS, convertCoordinates} from "../lib/ConvertCoordinates.mjs";
|
||||||
|
import OperationError from "../errors/OperationError.mjs";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show on map operation
|
||||||
|
*/
|
||||||
|
class ShowOnMap extends Operation {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ShowOnMap constructor
|
||||||
|
*/
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.name = "Show on map";
|
||||||
|
this.module = "Hashing";
|
||||||
|
this.description = "Displays co-ordinates on a slippy map.<br><br>Co-ordinates will be converted to decimal degrees before being shown on the map.<br><br>Supported formats:<ul><li>Degrees Minutes Seconds (DMS)</li><li>Degrees Decimal Minutes (DDM)</li><li>Decimal Degrees (DD)</li><li>Geohash</li><li>Military Grid Reference System (MGRS)</li><li>Ordnance Survey National Grid (OSNG)</li><li>Universal Transverse Mercator (UTM)</li></ul><br>This operation will not work offline.";
|
||||||
|
this.infoURL = "https://foundation.wikimedia.org/wiki/Maps_Terms_of_Use";
|
||||||
|
this.inputType = "string";
|
||||||
|
this.outputType = "string";
|
||||||
|
this.presentType = "html";
|
||||||
|
this.args = [
|
||||||
|
{
|
||||||
|
name: "Zoom Level",
|
||||||
|
type: "number",
|
||||||
|
value: 13
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Input Format",
|
||||||
|
type: "option",
|
||||||
|
value: ["Auto"].concat(FORMATS)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Input Delimiter",
|
||||||
|
type: "option",
|
||||||
|
value: [
|
||||||
|
"Auto",
|
||||||
|
"Direction Preceding",
|
||||||
|
"Direction Following",
|
||||||
|
"\\n",
|
||||||
|
"Comma",
|
||||||
|
"Semi-colon",
|
||||||
|
"Colon"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} input
|
||||||
|
* @param {Object[]} args
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
run(input, args) {
|
||||||
|
if (input.replace(/\s+/g, "") !== "") {
|
||||||
|
const inFormat = args[1],
|
||||||
|
inDelim = args[2];
|
||||||
|
let latLong;
|
||||||
|
try {
|
||||||
|
latLong = convertCoordinates(input, inFormat, inDelim, "Decimal Degrees", "Comma", "None", 5);
|
||||||
|
} catch (error) {
|
||||||
|
throw new OperationError(error);
|
||||||
|
}
|
||||||
|
latLong = latLong.replace(/[,]$/, "");
|
||||||
|
latLong = latLong.replace(/°/g, "");
|
||||||
|
return latLong;
|
||||||
|
}
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} data
|
||||||
|
* @param {Object[]} args
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
async present(data, args) {
|
||||||
|
if (data.replace(/\s+/g, "") === "") {
|
||||||
|
data = "0, 0";
|
||||||
|
}
|
||||||
|
const zoomLevel = args[0];
|
||||||
|
const tileUrl = "https://maps.wikimedia.org/osm-intl/{z}/{x}/{y}.png",
|
||||||
|
tileAttribution = "<a href=\"https://wikimediafoundation.org/wiki/Maps_Terms_of_Use\">Wikimedia maps</a> | © <a href=\"https://www.openstreetmap.org/copyright\">OpenStreetMap</a> contributors",
|
||||||
|
leafletUrl = "https://unpkg.com/leaflet@1.5.0/dist/leaflet.js",
|
||||||
|
leafletCssUrl = "https://unpkg.com/leaflet@1.5.0/dist/leaflet.css";
|
||||||
|
return `<link rel="stylesheet" href="${leafletCssUrl}" crossorigin=""/>
|
||||||
|
<style>#output-html { white-space: normal; padding: 0; }</style>
|
||||||
|
<div id="presentedMap" style="width: 100%; height: 100%;"></div>
|
||||||
|
<script type="text/javascript">
|
||||||
|
var mapscript = document.createElement('script');
|
||||||
|
document.body.appendChild(mapscript);
|
||||||
|
mapscript.onload = function() {
|
||||||
|
var presentMap = L.map('presentedMap').setView([${data}], ${zoomLevel});
|
||||||
|
L.tileLayer('${tileUrl}', {
|
||||||
|
attribution: '${tileAttribution}'
|
||||||
|
}).addTo(presentMap);
|
||||||
|
|
||||||
|
L.marker([${data}]).addTo(presentMap)
|
||||||
|
.bindPopup('${data}')
|
||||||
|
.openPopup();
|
||||||
|
};
|
||||||
|
mapscript.src = "${leafletUrl}";
|
||||||
|
</script>`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ShowOnMap;
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
import Operation from "../Operation.mjs";
|
import Operation from "../Operation.mjs";
|
||||||
import Utils from "../Utils.mjs";
|
import Utils from "../Utils.mjs";
|
||||||
import cptable from "../vendor/js-codepage/cptable.js";
|
import cptable from "codepage";
|
||||||
import {IO_FORMAT} from "../lib/ChrEnc.mjs";
|
import {IO_FORMAT} from "../lib/ChrEnc.mjs";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -44,12 +44,15 @@ class ToBase62 extends Operation {
|
|||||||
input = new Uint8Array(input);
|
input = new Uint8Array(input);
|
||||||
if (input.length < 1) return "";
|
if (input.length < 1) return "";
|
||||||
|
|
||||||
const ALPHABET = Utils.expandAlphRange(args[0]).join("");
|
const alphabet = Utils.expandAlphRange(args[0]).join("");
|
||||||
const BN = BigNumber.clone({ ALPHABET });
|
const BN62 = BigNumber.clone({ ALPHABET: alphabet });
|
||||||
|
|
||||||
input = toHexFast(input).toUpperCase();
|
input = toHexFast(input).toUpperCase();
|
||||||
|
|
||||||
const number = new BN(input, 16);
|
// Read number in as hex using normal alphabet
|
||||||
|
const normalized = new BigNumber(input, 16);
|
||||||
|
// Copy to BigNumber clone that uses the specified Base62 alphabet
|
||||||
|
const number = new BN62(normalized);
|
||||||
|
|
||||||
return number.toString(62);
|
return number.toString(62);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ class ToBase64 extends Operation {
|
|||||||
*/
|
*/
|
||||||
run(input, args) {
|
run(input, args) {
|
||||||
const alphabet = args[0];
|
const alphabet = args[0];
|
||||||
return toBase64(new Uint8Array(input), alphabet);
|
return toBase64(input, alphabet);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ class ToQuotedPrintable extends Operation {
|
|||||||
* @private
|
* @private
|
||||||
* @param {number} nr
|
* @param {number} nr
|
||||||
* @param {byteArray[]} ranges
|
* @param {byteArray[]} ranges
|
||||||
* @returns {bolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
_checkRanges(nr, ranges) {
|
_checkRanges(nr, ranges) {
|
||||||
for (let i = ranges.length - 1; i >= 0; i--) {
|
for (let i = ranges.length - 1; i >= 0; i--) {
|
||||||
|
|||||||
@@ -75,6 +75,12 @@ class TripleDESDecrypt extends Operation {
|
|||||||
Triple DES uses a key length of 24 bytes (192 bits).
|
Triple DES uses a key length of 24 bytes (192 bits).
|
||||||
DES uses a key length of 8 bytes (64 bits).`);
|
DES uses a key length of 8 bytes (64 bits).`);
|
||||||
}
|
}
|
||||||
|
if (iv.length !== 8 && mode !== "ECB") {
|
||||||
|
throw new OperationError(`Invalid IV length: ${iv.length} bytes
|
||||||
|
|
||||||
|
Triple DES uses an IV length of 8 bytes (64 bits).
|
||||||
|
Make sure you have specified the type correctly (e.g. Hex vs UTF8).`);
|
||||||
|
}
|
||||||
|
|
||||||
input = Utils.convertToByteString(input, inputType);
|
input = Utils.convertToByteString(input, inputType);
|
||||||
|
|
||||||
|
|||||||
@@ -75,6 +75,12 @@ class TripleDESEncrypt extends Operation {
|
|||||||
Triple DES uses a key length of 24 bytes (192 bits).
|
Triple DES uses a key length of 24 bytes (192 bits).
|
||||||
DES uses a key length of 8 bytes (64 bits).`);
|
DES uses a key length of 8 bytes (64 bits).`);
|
||||||
}
|
}
|
||||||
|
if (iv.length !== 8 && mode !== "ECB") {
|
||||||
|
throw new OperationError(`Invalid IV length: ${iv.length} bytes
|
||||||
|
|
||||||
|
Triple DES uses an IV length of 8 bytes (64 bits).
|
||||||
|
Make sure you have specified the type correctly (e.g. Hex vs UTF8).`);
|
||||||
|
}
|
||||||
|
|
||||||
input = Utils.convertToByteString(input, inputType);
|
input = Utils.convertToByteString(input, inputType);
|
||||||
|
|
||||||
|
|||||||
@@ -22,8 +22,8 @@ class Typex extends Operation {
|
|||||||
super();
|
super();
|
||||||
|
|
||||||
this.name = "Typex";
|
this.name = "Typex";
|
||||||
this.module = "Default";
|
this.module = "Bletchley";
|
||||||
this.description = "Encipher/decipher with the WW2 Typex machine.<br><br>Typex was originally built by the British Royal Air Force prior to WW2, and is based on the Enigma machine with some improvements made, including using five rotors with more stepping points and interchangeable wiring cores. It was used across the British and Commonewealth militaries. A number of later variants were produced; here we simulate a WW2 era Mark 22 Typex with plugboards for the reflector and input. Typex rotors were changed regularly and none are public: a random example set are provided.<br><br>To configure the reflector plugboard, enter a string of connected pairs of letters in the reflector box, e.g. <code>AB CD EF</code> connects A to B, C to D, and E to F (you'll need to connect every letter). There is also an input plugboard: unlike Enigma's plugboard, it's not restricted to pairs, so it's entered like a rotor (without stepping). To create your own rotor, enter the letters that the rotor maps A to Z to, in order, optionally followed by <code><</code> then a list of stepping points.<br><br>More detailed descriptions of the Enigma, Typex and Bombe operations <a href='https://github.com/gchq/CyberChef/wiki/Enigma,-the-Bombe,-and-Typex'>can be found here</a>.";
|
this.description = "Encipher/decipher with the WW2 Typex machine.<br><br>Typex was originally built by the British Royal Air Force prior to WW2, and is based on the Enigma machine with some improvements made, including using five rotors with more stepping points and interchangeable wiring cores. It was used across the British and Commonwealth militaries. A number of later variants were produced; here we simulate a WW2 era Mark 22 Typex with plugboards for the reflector and input. Typex rotors were changed regularly and none are public: a random example set are provided.<br><br>To configure the reflector plugboard, enter a string of connected pairs of letters in the reflector box, e.g. <code>AB CD EF</code> connects A to B, C to D, and E to F (you'll need to connect every letter). There is also an input plugboard: unlike Enigma's plugboard, it's not restricted to pairs, so it's entered like a rotor (without stepping). To create your own rotor, enter the letters that the rotor maps A to Z to, in order, optionally followed by <code><</code> then a list of stepping points.<br><br>More detailed descriptions of the Enigma, Typex and Bombe operations <a href='https://github.com/gchq/CyberChef/wiki/Enigma,-the-Bombe,-and-Typex'>can be found here</a>.";
|
||||||
this.infoURL = "https://wikipedia.org/wiki/Typex";
|
this.infoURL = "https://wikipedia.org/wiki/Typex";
|
||||||
this.inputType = "string";
|
this.inputType = "string";
|
||||||
this.outputType = "string";
|
this.outputType = "string";
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ class UNIXTimestampToWindowsFiletime extends Operation {
|
|||||||
} else if (units === "Milliseconds (ms)") {
|
} else if (units === "Milliseconds (ms)") {
|
||||||
input = input.multipliedBy(new BigNumber("10000"));
|
input = input.multipliedBy(new BigNumber("10000"));
|
||||||
} else if (units === "Microseconds (μs)") {
|
} else if (units === "Microseconds (μs)") {
|
||||||
input = input.multiplyiedBy(new BigNumber("10"));
|
input = input.multipliedBy(new BigNumber("10"));
|
||||||
} else if (units === "Nanoseconds (ns)") {
|
} else if (units === "Nanoseconds (ns)") {
|
||||||
input = input.dividedBy(new BigNumber("100"));
|
input = input.dividedBy(new BigNumber("100"));
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ class URLEncode extends Operation {
|
|||||||
* @returns {string}
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
encodeAllChars (str) {
|
encodeAllChars (str) {
|
||||||
// TODO Do this programatically
|
// TODO Do this programmatically
|
||||||
return encodeURIComponent(str)
|
return encodeURIComponent(str)
|
||||||
.replace(/!/g, "%21")
|
.replace(/!/g, "%21")
|
||||||
.replace(/#/g, "%23")
|
.replace(/#/g, "%23")
|
||||||
|
|||||||
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;
|
||||||
@@ -55,7 +55,7 @@ class VigenèreDecode extends Operation {
|
|||||||
keyIndex = alphabet.indexOf(chr);
|
keyIndex = alphabet.indexOf(chr);
|
||||||
msgIndex = alphabet.indexOf(input[i]);
|
msgIndex = alphabet.indexOf(input[i]);
|
||||||
// Subtract indexes from each other, add 26 just in case the value is negative,
|
// Subtract indexes from each other, add 26 just in case the value is negative,
|
||||||
// modulo to remove if neccessary
|
// modulo to remove if necessary
|
||||||
output += alphabet[(msgIndex - keyIndex + alphabet.length) % 26];
|
output += alphabet[(msgIndex - keyIndex + alphabet.length) % 26];
|
||||||
} else if (alphabet.indexOf(input[i].toLowerCase()) >= 0) {
|
} else if (alphabet.indexOf(input[i].toLowerCase()) >= 0) {
|
||||||
chr = key[(i - fail) % key.length].toLowerCase();
|
chr = key[(i - fail) % key.length].toLowerCase();
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ class Whirlpool extends Operation {
|
|||||||
|
|
||||||
this.name = "Whirlpool";
|
this.name = "Whirlpool";
|
||||||
this.module = "Crypto";
|
this.module = "Crypto";
|
||||||
this.description = "Whirlpool is a cryptographic hash function designed by Vincent Rijmen (co-creator of AES) and Paulo S. L. M. Barreto, who first described it in 2000.<br><br>Several variants exist:<ul><li>Whirlpool-0 is the original version released in 2000.</li><li>Whirlpool-T is the first revision, released in 2001, improving the generation of the s-box.</li><li>Whirlpool is the latest revision, released in 2003, fixing a flaw in the difusion matrix.</li></ul>";
|
this.description = "Whirlpool is a cryptographic hash function designed by Vincent Rijmen (co-creator of AES) and Paulo S. L. M. Barreto, who first described it in 2000.<br><br>Several variants exist:<ul><li>Whirlpool-0 is the original version released in 2000.</li><li>Whirlpool-T is the first revision, released in 2001, improving the generation of the s-box.</li><li>Whirlpool is the latest revision, released in 2003, fixing a flaw in the diffusion matrix.</li></ul>";
|
||||||
this.infoURL = "https://wikipedia.org/wiki/Whirlpool_(cryptography)";
|
this.infoURL = "https://wikipedia.org/wiki/Whirlpool_(cryptography)";
|
||||||
this.inputType = "ArrayBuffer";
|
this.inputType = "ArrayBuffer";
|
||||||
this.outputType = "string";
|
this.outputType = "string";
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ class YARARules extends Operation {
|
|||||||
* @param {Object[]} args
|
* @param {Object[]} args
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
run(input, args) {
|
async run(input, args) {
|
||||||
if (isWorkerEnvironment())
|
if (isWorkerEnvironment())
|
||||||
self.sendStatusMessage("Instantiating YARA...");
|
self.sendStatusMessage("Instantiating YARA...");
|
||||||
const [rules, showStrings, showLengths, showMeta, showCounts] = args;
|
const [rules, showStrings, showLengths, showMeta, showCounts] = args;
|
||||||
|
|||||||
652
src/core/vendor/Blowfish.mjs
vendored
652
src/core/vendor/Blowfish.mjs
vendored
@@ -1,652 +0,0 @@
|
|||||||
/**
|
|
||||||
Blowfish.js from Dojo Toolkit 1.8.1 (https://github.com/dojo/dojox/tree/1.8/encoding)
|
|
||||||
Extracted by Sladex (xslade@gmail.com)
|
|
||||||
Shoehorned into working with mjs for CyberChef by Matt C (matt@artemisbot.uk)
|
|
||||||
|
|
||||||
@license BSD
|
|
||||||
========================================================================
|
|
||||||
The "New" BSD License:
|
|
||||||
**********************
|
|
||||||
|
|
||||||
Copyright (c) 2005-2016, The Dojo Foundation
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are met:
|
|
||||||
|
|
||||||
* Redistributions of source code must retain the above copyright notice, this
|
|
||||||
list of conditions and the following disclaimer.
|
|
||||||
* Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
this list of conditions and the following disclaimer in the documentation
|
|
||||||
and/or other materials provided with the distribution.
|
|
||||||
* Neither the name of the Dojo Foundation nor the names of its contributors
|
|
||||||
may be used to endorse or promote products derived from this software
|
|
||||||
without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
||||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
|
||||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
||||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
||||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
||||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
let crypto = {};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* dojo-release-1.8.1/dojox/encoding/crypto/_base.js.uncompressed.js */
|
|
||||||
|
|
||||||
crypto.cipherModes = {
|
|
||||||
// summary:
|
|
||||||
// Enumeration for various cipher modes.
|
|
||||||
ECB:0, CBC:1, PCBC:2, CFB:3, OFB:4, CTR:5
|
|
||||||
};
|
|
||||||
crypto.outputTypes = {
|
|
||||||
// summary:
|
|
||||||
// Enumeration for input and output encodings.
|
|
||||||
Base64:0, Hex:1, String:2, Raw:3
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* dojo-release-1.8.1/dojox/encoding/base64.js.uncompressed.js */
|
|
||||||
|
|
||||||
var base64 = {};
|
|
||||||
var p="=";
|
|
||||||
var tab="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
||||||
|
|
||||||
base64.encode=function(/* byte[] */ba){
|
|
||||||
// summary:
|
|
||||||
// Encode an array of bytes as a base64-encoded string
|
|
||||||
var s=[], l=ba.length;
|
|
||||||
var rm=l%3;
|
|
||||||
var x=l-rm;
|
|
||||||
for (var i=0; i<x;){
|
|
||||||
var t=ba[i++]<<16|ba[i++]<<8|ba[i++];
|
|
||||||
s.push(tab.charAt((t>>>18)&0x3f));
|
|
||||||
s.push(tab.charAt((t>>>12)&0x3f));
|
|
||||||
s.push(tab.charAt((t>>>6)&0x3f));
|
|
||||||
s.push(tab.charAt(t&0x3f));
|
|
||||||
}
|
|
||||||
// deal with trailers, based on patch from Peter Wood.
|
|
||||||
switch(rm){
|
|
||||||
case 2:{
|
|
||||||
var t=ba[i++]<<16|ba[i++]<<8;
|
|
||||||
s.push(tab.charAt((t>>>18)&0x3f));
|
|
||||||
s.push(tab.charAt((t>>>12)&0x3f));
|
|
||||||
s.push(tab.charAt((t>>>6)&0x3f));
|
|
||||||
s.push(p);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 1:{
|
|
||||||
var t=ba[i++]<<16;
|
|
||||||
s.push(tab.charAt((t>>>18)&0x3f));
|
|
||||||
s.push(tab.charAt((t>>>12)&0x3f));
|
|
||||||
s.push(p);
|
|
||||||
s.push(p);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return s.join(""); // string
|
|
||||||
};
|
|
||||||
|
|
||||||
base64.decode=function(/* string */str){
|
|
||||||
// summary:
|
|
||||||
// Convert a base64-encoded string to an array of bytes
|
|
||||||
var s=str.split(""), out=[];
|
|
||||||
var l=s.length;
|
|
||||||
while(s[--l]==p){ } // strip off trailing padding
|
|
||||||
for (var i=0; i<l;){
|
|
||||||
var t=tab.indexOf(s[i++])<<18;
|
|
||||||
if(i<=l){ t|=tab.indexOf(s[i++])<<12 };
|
|
||||||
if(i<=l){ t|=tab.indexOf(s[i++])<<6 };
|
|
||||||
if(i<=l){ t|=tab.indexOf(s[i++]) };
|
|
||||||
out.push((t>>>16)&0xff);
|
|
||||||
out.push((t>>>8)&0xff);
|
|
||||||
out.push(t&0xff);
|
|
||||||
}
|
|
||||||
// strip off any null bytes
|
|
||||||
while(out[out.length-1]==0){ out.pop(); }
|
|
||||||
return out; // byte[]
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* dojo-release-1.8.1/dojo/_base/lang.js.uncompressed.js */
|
|
||||||
|
|
||||||
var lang = {};
|
|
||||||
lang.isString = function(it){
|
|
||||||
// summary:
|
|
||||||
// Return true if it is a String
|
|
||||||
// it: anything
|
|
||||||
// Item to test.
|
|
||||||
return (typeof it == "string" || it instanceof String); // Boolean
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* dojo-release-1.8.1/dojo/_base/array.js.uncompressed.js */
|
|
||||||
|
|
||||||
var arrayUtil = {};
|
|
||||||
arrayUtil.map = function(arr, callback, thisObject, Ctr){
|
|
||||||
// summary:
|
|
||||||
// applies callback to each element of arr and returns
|
|
||||||
// an Array with the results
|
|
||||||
// arr: Array|String
|
|
||||||
// the array to iterate on. If a string, operates on
|
|
||||||
// individual characters.
|
|
||||||
// callback: Function|String
|
|
||||||
// a function is invoked with three arguments, (item, index,
|
|
||||||
// array), and returns a value
|
|
||||||
// thisObject: Object?
|
|
||||||
// may be used to scope the call to callback
|
|
||||||
// returns: Array
|
|
||||||
// description:
|
|
||||||
// This function corresponds to the JavaScript 1.6 Array.map() method, with one difference: when
|
|
||||||
// run over sparse arrays, this implementation passes the "holes" in the sparse array to
|
|
||||||
// the callback function with a value of undefined. JavaScript 1.6's map skips the holes in the sparse array.
|
|
||||||
// For more details, see:
|
|
||||||
// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map
|
|
||||||
// example:
|
|
||||||
// | // returns [2, 3, 4, 5]
|
|
||||||
// | array.map([1, 2, 3, 4], function(item){ return item+1 });
|
|
||||||
|
|
||||||
// TODO: why do we have a non-standard signature here? do we need "Ctr"?
|
|
||||||
var i = 0, l = arr && arr.length || 0, out = new (Ctr || Array)(l);
|
|
||||||
if(l && typeof arr == "string") arr = arr.split("");
|
|
||||||
if(typeof callback == "string") callback = cache[callback] || buildFn(callback);
|
|
||||||
if(thisObject){
|
|
||||||
for(; i < l; ++i){
|
|
||||||
out[i] = callback.call(thisObject, arr[i], i, arr);
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
for(; i < l; ++i){
|
|
||||||
out[i] = callback(arr[i], i, arr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return out; // Array
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* dojo-release-1.8.1/dojox/encoding/crypto/Blowfish.js.uncompressed.js */
|
|
||||||
|
|
||||||
/* Blowfish
|
|
||||||
* Created based on the C# implementation by Marcus Hahn (http://www.hotpixel.net/)
|
|
||||||
* Unsigned math based on Paul Johnstone and Peter Wood patches.
|
|
||||||
* 2005-12-08
|
|
||||||
*/
|
|
||||||
crypto.Blowfish = new function(){
|
|
||||||
// summary:
|
|
||||||
// Object for doing Blowfish encryption/decryption.
|
|
||||||
var POW2=Math.pow(2,2);
|
|
||||||
var POW3=Math.pow(2,3);
|
|
||||||
var POW4=Math.pow(2,4);
|
|
||||||
var POW8=Math.pow(2,8);
|
|
||||||
var POW16=Math.pow(2,16);
|
|
||||||
var POW24=Math.pow(2,24);
|
|
||||||
var iv=null; // CBC mode initialization vector
|
|
||||||
var boxes={
|
|
||||||
p:[
|
|
||||||
0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
|
|
||||||
0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
|
|
||||||
0x9216d5d9, 0x8979fb1b
|
|
||||||
],
|
|
||||||
s0:[
|
|
||||||
0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
|
|
||||||
0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
|
|
||||||
0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
|
|
||||||
0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
|
|
||||||
0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
|
|
||||||
0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
|
|
||||||
0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
|
|
||||||
0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
|
|
||||||
0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
|
|
||||||
0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
|
|
||||||
0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
|
|
||||||
0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
|
|
||||||
0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
|
|
||||||
0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
|
|
||||||
0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
|
|
||||||
0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
|
|
||||||
0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
|
|
||||||
0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
|
|
||||||
0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
|
|
||||||
0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
|
|
||||||
0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
|
|
||||||
0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
|
|
||||||
0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
|
|
||||||
0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
|
|
||||||
0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
|
|
||||||
0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
|
|
||||||
0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
|
|
||||||
0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
|
|
||||||
0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
|
|
||||||
0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
|
|
||||||
0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
|
|
||||||
0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a
|
|
||||||
],
|
|
||||||
s1:[
|
|
||||||
0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
|
|
||||||
0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
|
|
||||||
0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
|
|
||||||
0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
|
|
||||||
0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
|
|
||||||
0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
|
|
||||||
0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
|
|
||||||
0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
|
|
||||||
0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
|
|
||||||
0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
|
|
||||||
0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
|
|
||||||
0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
|
|
||||||
0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
|
|
||||||
0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
|
|
||||||
0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
|
|
||||||
0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
|
|
||||||
0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
|
|
||||||
0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
|
|
||||||
0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
|
|
||||||
0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
|
|
||||||
0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
|
|
||||||
0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
|
|
||||||
0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
|
|
||||||
0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
|
|
||||||
0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
|
|
||||||
0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
|
|
||||||
0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
|
|
||||||
0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
|
|
||||||
0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
|
|
||||||
0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
|
|
||||||
0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
|
|
||||||
0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7
|
|
||||||
],
|
|
||||||
s2:[
|
|
||||||
0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
|
|
||||||
0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
|
|
||||||
0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
|
|
||||||
0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
|
|
||||||
0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
|
|
||||||
0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
|
|
||||||
0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
|
|
||||||
0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
|
|
||||||
0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
|
|
||||||
0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
|
|
||||||
0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
|
|
||||||
0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
|
|
||||||
0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
|
|
||||||
0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
|
|
||||||
0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
|
|
||||||
0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
|
|
||||||
0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
|
|
||||||
0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
|
|
||||||
0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
|
|
||||||
0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
|
|
||||||
0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
|
|
||||||
0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
|
|
||||||
0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
|
|
||||||
0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
|
|
||||||
0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
|
|
||||||
0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
|
|
||||||
0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
|
|
||||||
0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
|
|
||||||
0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
|
|
||||||
0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
|
|
||||||
0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
|
|
||||||
0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0
|
|
||||||
],
|
|
||||||
s3:[
|
|
||||||
0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
|
|
||||||
0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
|
|
||||||
0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
|
|
||||||
0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
|
|
||||||
0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
|
|
||||||
0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
|
|
||||||
0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
|
|
||||||
0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
|
|
||||||
0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
|
|
||||||
0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
|
|
||||||
0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
|
|
||||||
0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
|
|
||||||
0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
|
|
||||||
0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
|
|
||||||
0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
|
|
||||||
0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
|
|
||||||
0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
|
|
||||||
0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
|
|
||||||
0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
|
|
||||||
0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
|
|
||||||
0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
|
|
||||||
0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
|
|
||||||
0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
|
|
||||||
0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
|
|
||||||
0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
|
|
||||||
0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
|
|
||||||
0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
|
|
||||||
0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
|
|
||||||
0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
|
|
||||||
0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
|
|
||||||
0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
|
|
||||||
0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6
|
|
||||||
]
|
|
||||||
}
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
// fixes based on patch submitted by Peter Wood (#5791)
|
|
||||||
function add(x,y){
|
|
||||||
return (((x>>0x10)+(y>>0x10)+(((x&0xffff)+(y&0xffff))>>0x10))<<0x10)|(((x&0xffff)+(y&0xffff))&0xffff);
|
|
||||||
}
|
|
||||||
function xor(x,y){
|
|
||||||
return (((x>>0x10)^(y>>0x10))<<0x10)|(((x&0xffff)^(y&0xffff))&0xffff);
|
|
||||||
}
|
|
||||||
|
|
||||||
function $(v, box){
|
|
||||||
var d=box.s3[v&0xff]; v>>=8;
|
|
||||||
var c=box.s2[v&0xff]; v>>=8;
|
|
||||||
var b=box.s1[v&0xff]; v>>=8;
|
|
||||||
var a=box.s0[v&0xff];
|
|
||||||
|
|
||||||
var r = (((a>>0x10)+(b>>0x10)+(((a&0xffff)+(b&0xffff))>>0x10))<<0x10)|(((a&0xffff)+(b&0xffff))&0xffff);
|
|
||||||
r = (((r>>0x10)^(c>>0x10))<<0x10)|(((r&0xffff)^(c&0xffff))&0xffff);
|
|
||||||
return (((r>>0x10)+(d>>0x10)+(((r&0xffff)+(d&0xffff))>>0x10))<<0x10)|(((r&0xffff)+(d&0xffff))&0xffff);
|
|
||||||
}
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
function eb(o, box){
|
|
||||||
// TODO: see if this can't be made more efficient
|
|
||||||
var l=o.left;
|
|
||||||
var r=o.right;
|
|
||||||
l=xor(l,box.p[0]);
|
|
||||||
r=xor(r,xor($(l,box),box.p[1]));
|
|
||||||
l=xor(l,xor($(r,box),box.p[2]));
|
|
||||||
r=xor(r,xor($(l,box),box.p[3]));
|
|
||||||
l=xor(l,xor($(r,box),box.p[4]));
|
|
||||||
r=xor(r,xor($(l,box),box.p[5]));
|
|
||||||
l=xor(l,xor($(r,box),box.p[6]));
|
|
||||||
r=xor(r,xor($(l,box),box.p[7]));
|
|
||||||
l=xor(l,xor($(r,box),box.p[8]));
|
|
||||||
r=xor(r,xor($(l,box),box.p[9]));
|
|
||||||
l=xor(l,xor($(r,box),box.p[10]));
|
|
||||||
r=xor(r,xor($(l,box),box.p[11]));
|
|
||||||
l=xor(l,xor($(r,box),box.p[12]));
|
|
||||||
r=xor(r,xor($(l,box),box.p[13]));
|
|
||||||
l=xor(l,xor($(r,box),box.p[14]));
|
|
||||||
r=xor(r,xor($(l,box),box.p[15]));
|
|
||||||
l=xor(l,xor($(r,box),box.p[16]));
|
|
||||||
o.right=l;
|
|
||||||
o.left=xor(r,box.p[17]);
|
|
||||||
}
|
|
||||||
|
|
||||||
function db(o, box){
|
|
||||||
var l=o.left;
|
|
||||||
var r=o.right;
|
|
||||||
l=xor(l,box.p[17]);
|
|
||||||
r=xor(r,xor($(l,box),box.p[16]));
|
|
||||||
l=xor(l,xor($(r,box),box.p[15]));
|
|
||||||
r=xor(r,xor($(l,box),box.p[14]));
|
|
||||||
l=xor(l,xor($(r,box),box.p[13]));
|
|
||||||
r=xor(r,xor($(l,box),box.p[12]));
|
|
||||||
l=xor(l,xor($(r,box),box.p[11]));
|
|
||||||
r=xor(r,xor($(l,box),box.p[10]));
|
|
||||||
l=xor(l,xor($(r,box),box.p[9]));
|
|
||||||
r=xor(r,xor($(l,box),box.p[8]));
|
|
||||||
l=xor(l,xor($(r,box),box.p[7]));
|
|
||||||
r=xor(r,xor($(l,box),box.p[6]));
|
|
||||||
l=xor(l,xor($(r,box),box.p[5]));
|
|
||||||
r=xor(r,xor($(l,box),box.p[4]));
|
|
||||||
l=xor(l,xor($(r,box),box.p[3]));
|
|
||||||
r=xor(r,xor($(l,box),box.p[2]));
|
|
||||||
l=xor(l,xor($(r,box),box.p[1]));
|
|
||||||
o.right=l;
|
|
||||||
o.left=xor(r,box.p[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note that we aren't caching contexts here; it might take a little longer
|
|
||||||
// but we should be more secure this way.
|
|
||||||
function init(key){
|
|
||||||
var k=key;
|
|
||||||
if(lang.isString(k)){
|
|
||||||
k = arrayUtil.map(k.split(""), function(item){
|
|
||||||
return item.charCodeAt(0) & 0xff;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// init the boxes
|
|
||||||
var pos=0, data=0, res={ left:0, right:0 }, i, j, l;
|
|
||||||
var box = {
|
|
||||||
p: arrayUtil.map(boxes.p.slice(0), function(item){
|
|
||||||
var l=k.length, j;
|
|
||||||
for(j=0; j<4; j++){ data=(data*POW8)|k[pos++ % l]; }
|
|
||||||
return (((item>>0x10)^(data>>0x10))<<0x10)|(((item&0xffff)^(data&0xffff))&0xffff);
|
|
||||||
}),
|
|
||||||
s0:boxes.s0.slice(0),
|
|
||||||
s1:boxes.s1.slice(0),
|
|
||||||
s2:boxes.s2.slice(0),
|
|
||||||
s3:boxes.s3.slice(0)
|
|
||||||
};
|
|
||||||
|
|
||||||
// encrypt p and the s boxes
|
|
||||||
for(i=0, l=box.p.length; i<l;){
|
|
||||||
eb(res, box);
|
|
||||||
box.p[i++]=res.left, box.p[i++]=res.right;
|
|
||||||
}
|
|
||||||
for(i=0; i<4; i++){
|
|
||||||
for(j=0, l=box["s"+i].length; j<l;){
|
|
||||||
eb(res, box);
|
|
||||||
box["s"+i][j++]=res.left, box["s"+i][j++]=res.right;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return box;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
// PUBLIC FUNCTIONS
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
this.getIV=function(/* dojox.encoding.crypto.outputTypes? */ outputType){
|
|
||||||
// summary:
|
|
||||||
// returns the initialization vector in the output format specified by outputType
|
|
||||||
var out=outputType||crypto.outputTypes.Base64;
|
|
||||||
switch(out){
|
|
||||||
case crypto.outputTypes.Hex:{
|
|
||||||
return arrayUtil.map(iv, function(item){
|
|
||||||
return (item<=0xf?'0':'')+item.toString(16);
|
|
||||||
}).join(""); // string
|
|
||||||
}
|
|
||||||
case crypto.outputTypes.String:{
|
|
||||||
return iv.join(""); // string
|
|
||||||
}
|
|
||||||
case crypto.outputTypes.Raw:{
|
|
||||||
return iv; // array
|
|
||||||
}
|
|
||||||
default:{
|
|
||||||
return base64.encode(iv); // string
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
this.setIV=function(/* string */data, /* dojox.encoding.crypto.outputTypes? */inputType){
|
|
||||||
// summary:
|
|
||||||
// sets the initialization vector to data (as interpreted as inputType)
|
|
||||||
var ip=inputType||crypto.outputTypes.Base64;
|
|
||||||
var ba=null;
|
|
||||||
switch(ip){
|
|
||||||
case crypto.outputTypes.String:{
|
|
||||||
ba = arrayUtil.map(data.split(""), function(item){
|
|
||||||
return item.charCodeAt(0);
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case crypto.outputTypes.Hex:{
|
|
||||||
ba=[];
|
|
||||||
for(var i=0, l=data.length-1; i<l; i+=2){
|
|
||||||
ba.push(parseInt(data.substr(i,2), 16));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case crypto.outputTypes.Raw:{
|
|
||||||
ba=data;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:{
|
|
||||||
ba=base64.decode(data);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// make it a pair of words now
|
|
||||||
iv={};
|
|
||||||
iv.left=ba[0]*POW24|ba[1]*POW16|ba[2]*POW8|ba[3];
|
|
||||||
iv.right=ba[4]*POW24|ba[5]*POW16|ba[6]*POW8|ba[7];
|
|
||||||
};
|
|
||||||
|
|
||||||
this.encrypt = function(/* string */plaintext, /* string */key, /* object? */ao){
|
|
||||||
// summary:
|
|
||||||
// encrypts plaintext using key; allows user to specify output type and cipher mode via keyword object "ao"
|
|
||||||
var out=crypto.outputTypes.Base64;
|
|
||||||
var mode=crypto.cipherModes.ECB;
|
|
||||||
if (ao){
|
|
||||||
if (ao.outputType) out=ao.outputType;
|
|
||||||
if (ao.cipherMode) mode=ao.cipherMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
var bx = init(key), padding = 8-(plaintext.length&7);
|
|
||||||
for (var i=0; i<padding; i++){ plaintext+=String.fromCharCode(padding); }
|
|
||||||
|
|
||||||
var cipher=[], count=plaintext.length >> 3, pos=0, o={}, isCBC=(mode==crypto.cipherModes.CBC);
|
|
||||||
var vector={left:iv.left||null, right:iv.right||null};
|
|
||||||
for(var i=0; i<count; i++){
|
|
||||||
o.left=plaintext.charCodeAt(pos)*POW24
|
|
||||||
|plaintext.charCodeAt(pos+1)*POW16
|
|
||||||
|plaintext.charCodeAt(pos+2)*POW8
|
|
||||||
|plaintext.charCodeAt(pos+3);
|
|
||||||
o.right=plaintext.charCodeAt(pos+4)*POW24
|
|
||||||
|plaintext.charCodeAt(pos+5)*POW16
|
|
||||||
|plaintext.charCodeAt(pos+6)*POW8
|
|
||||||
|plaintext.charCodeAt(pos+7);
|
|
||||||
|
|
||||||
if(isCBC){
|
|
||||||
o.left=(((o.left>>0x10)^(vector.left>>0x10))<<0x10)|(((o.left&0xffff)^(vector.left&0xffff))&0xffff);
|
|
||||||
o.right=(((o.right>>0x10)^(vector.right>>0x10))<<0x10)|(((o.right&0xffff)^(vector.right&0xffff))&0xffff);
|
|
||||||
}
|
|
||||||
|
|
||||||
eb(o, bx); // encrypt the block
|
|
||||||
|
|
||||||
if(isCBC){
|
|
||||||
vector.left=o.left;
|
|
||||||
vector.right=o.right;
|
|
||||||
}
|
|
||||||
|
|
||||||
cipher.push((o.left>>24)&0xff);
|
|
||||||
cipher.push((o.left>>16)&0xff);
|
|
||||||
cipher.push((o.left>>8)&0xff);
|
|
||||||
cipher.push(o.left&0xff);
|
|
||||||
cipher.push((o.right>>24)&0xff);
|
|
||||||
cipher.push((o.right>>16)&0xff);
|
|
||||||
cipher.push((o.right>>8)&0xff);
|
|
||||||
cipher.push(o.right&0xff);
|
|
||||||
pos+=8;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(out){
|
|
||||||
case crypto.outputTypes.Hex:{
|
|
||||||
return arrayUtil.map(cipher, function(item){
|
|
||||||
return (item<=0xf?'0':'')+item.toString(16);
|
|
||||||
}).join(""); // string
|
|
||||||
}
|
|
||||||
case crypto.outputTypes.String:{
|
|
||||||
return cipher.join(""); // string
|
|
||||||
}
|
|
||||||
case crypto.outputTypes.Raw:{
|
|
||||||
return cipher; // array
|
|
||||||
}
|
|
||||||
default:{
|
|
||||||
return base64.encode(cipher); // string
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
this.decrypt = function(/* string */ciphertext, /* string */key, /* object? */ao){
|
|
||||||
// summary:
|
|
||||||
// decrypts ciphertext using key; allows specification of how ciphertext is encoded via ao.
|
|
||||||
var ip=crypto.outputTypes.Base64;
|
|
||||||
var mode=crypto.cipherModes.ECB;
|
|
||||||
if (ao){
|
|
||||||
if (ao.outputType) ip=ao.outputType;
|
|
||||||
if (ao.cipherMode) mode=ao.cipherMode;
|
|
||||||
}
|
|
||||||
var bx = init(key);
|
|
||||||
var pt=[];
|
|
||||||
|
|
||||||
var c=null;
|
|
||||||
switch(ip){
|
|
||||||
case crypto.outputTypes.Hex:{
|
|
||||||
c = [];
|
|
||||||
for(var i=0, l=ciphertext.length-1; i<l; i+=2){
|
|
||||||
c.push(parseInt(ciphertext.substr(i,2), 16));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case crypto.outputTypes.String:{
|
|
||||||
c = arrayUtil.map(ciphertext.split(""), function(item){
|
|
||||||
return item.charCodeAt(0);
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case crypto.outputTypes.Raw:{
|
|
||||||
c=ciphertext; // should be a byte array
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:{
|
|
||||||
c=base64.decode(ciphertext);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var count=c.length >> 3, pos=0, o={}, isCBC=(mode==crypto.cipherModes.CBC);
|
|
||||||
var vector={left:iv.left||null, right:iv.right||null};
|
|
||||||
for(var i=0; i<count; i++){
|
|
||||||
o.left=c[pos]*POW24|c[pos+1]*POW16|c[pos+2]*POW8|c[pos+3];
|
|
||||||
o.right=c[pos+4]*POW24|c[pos+5]*POW16|c[pos+6]*POW8|c[pos+7];
|
|
||||||
|
|
||||||
if(isCBC){
|
|
||||||
var left=o.left;
|
|
||||||
var right=o.right;
|
|
||||||
}
|
|
||||||
|
|
||||||
db(o, bx); // decrypt the block
|
|
||||||
|
|
||||||
if(isCBC){
|
|
||||||
o.left=(((o.left>>0x10)^(vector.left>>0x10))<<0x10)|(((o.left&0xffff)^(vector.left&0xffff))&0xffff);
|
|
||||||
o.right=(((o.right>>0x10)^(vector.right>>0x10))<<0x10)|(((o.right&0xffff)^(vector.right&0xffff))&0xffff);
|
|
||||||
vector.left=left;
|
|
||||||
vector.right=right;
|
|
||||||
}
|
|
||||||
|
|
||||||
pt.push((o.left>>24)&0xff);
|
|
||||||
pt.push((o.left>>16)&0xff);
|
|
||||||
pt.push((o.left>>8)&0xff);
|
|
||||||
pt.push(o.left&0xff);
|
|
||||||
pt.push((o.right>>24)&0xff);
|
|
||||||
pt.push((o.right>>16)&0xff);
|
|
||||||
pt.push((o.right>>8)&0xff);
|
|
||||||
pt.push(o.right&0xff);
|
|
||||||
pos+=8;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check for padding, and remove.
|
|
||||||
if(pt[pt.length-1]==pt[pt.length-2]||pt[pt.length-1]==0x01){
|
|
||||||
var n=pt[pt.length-1];
|
|
||||||
pt.splice(pt.length-n, n);
|
|
||||||
}
|
|
||||||
|
|
||||||
// convert to string
|
|
||||||
return arrayUtil.map(pt, function(item){
|
|
||||||
return String.fromCharCode(item);
|
|
||||||
}).join(""); // string
|
|
||||||
};
|
|
||||||
|
|
||||||
this.setIV("0000000000000000", crypto.outputTypes.Hex);
|
|
||||||
}();
|
|
||||||
|
|
||||||
export const Blowfish = crypto.Blowfish;
|
|
||||||
1982
src/core/vendor/js-codepage/cptable.js
vendored
1982
src/core/vendor/js-codepage/cptable.js
vendored
File diff suppressed because it is too large
Load Diff
515
src/core/vendor/js-codepage/cputils.js
vendored
515
src/core/vendor/js-codepage/cputils.js
vendored
@@ -1,515 +0,0 @@
|
|||||||
/* cputils.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
|
||||||
/* vim: set ft=javascript: */
|
|
||||||
/*jshint newcap: false */
|
|
||||||
(function(root, factory) {
|
|
||||||
"use strict";
|
|
||||||
if(typeof cptable === "undefined") {
|
|
||||||
if(typeof require !== "undefined"){
|
|
||||||
var cpt = require('./cptable');
|
|
||||||
if (typeof module !== 'undefined' && module.exports) module.exports = factory(cpt);
|
|
||||||
else root.cptable = factory(cpt);
|
|
||||||
} else throw new Error("cptable not found");
|
|
||||||
} else cptable = factory(cptable);
|
|
||||||
}(this, function(cpt){
|
|
||||||
"use strict";
|
|
||||||
var magic = {
|
|
||||||
"1200":"utf16le",
|
|
||||||
"1201":"utf16be",
|
|
||||||
"12000":"utf32le",
|
|
||||||
"12001":"utf32be",
|
|
||||||
"16969":"utf64le",
|
|
||||||
"20127":"ascii",
|
|
||||||
"65000":"utf7",
|
|
||||||
"65001":"utf8"
|
|
||||||
};
|
|
||||||
|
|
||||||
var sbcs_cache = [874,1250,1251,1252,1253,1254,1255,1256,10000];
|
|
||||||
var dbcs_cache = [932,936,949,950];
|
|
||||||
var magic_cache = [65001];
|
|
||||||
var magic_decode = {};
|
|
||||||
var magic_encode = {};
|
|
||||||
var cpdcache = {};
|
|
||||||
var cpecache = {};
|
|
||||||
|
|
||||||
var sfcc = function sfcc(x) { return String.fromCharCode(x); };
|
|
||||||
var cca = function cca(x) { return x.charCodeAt(0); };
|
|
||||||
|
|
||||||
var has_buf = (typeof Buffer !== 'undefined');
|
|
||||||
if(has_buf) {
|
|
||||||
var mdl = 1024, mdb = new Buffer(mdl);
|
|
||||||
var make_EE = function make_EE(E){
|
|
||||||
var EE = new Buffer(65536);
|
|
||||||
for(var i = 0; i < 65536;++i) EE[i] = 0;
|
|
||||||
var keys = Object.keys(E), len = keys.length;
|
|
||||||
for(var ee = 0, e = keys[ee]; ee < len; ++ee) {
|
|
||||||
if(!(e = keys[ee])) continue;
|
|
||||||
EE[e.charCodeAt(0)] = E[e];
|
|
||||||
}
|
|
||||||
return EE;
|
|
||||||
};
|
|
||||||
var sbcs_encode = function make_sbcs_encode(cp) {
|
|
||||||
var EE = make_EE(cpt[cp].enc);
|
|
||||||
return function sbcs_e(data, ofmt) {
|
|
||||||
var len = data.length;
|
|
||||||
var out, i=0, j=0, D=0, w=0;
|
|
||||||
if(typeof data === 'string') {
|
|
||||||
out = new Buffer(len);
|
|
||||||
for(i = 0; i < len; ++i) out[i] = EE[data.charCodeAt(i)];
|
|
||||||
} else if(Buffer.isBuffer(data)) {
|
|
||||||
out = new Buffer(2*len);
|
|
||||||
j = 0;
|
|
||||||
for(i = 0; i < len; ++i) {
|
|
||||||
D = data[i];
|
|
||||||
if(D < 128) out[j++] = EE[D];
|
|
||||||
else if(D < 224) { out[j++] = EE[((D&31)<<6)+(data[i+1]&63)]; ++i; }
|
|
||||||
else if(D < 240) { out[j++] = EE[((D&15)<<12)+((data[i+1]&63)<<6)+(data[i+2]&63)]; i+=2; }
|
|
||||||
else {
|
|
||||||
w = ((D&7)<<18)+((data[i+1]&63)<<12)+((data[i+2]&63)<<6)+(data[i+3]&63); i+=3;
|
|
||||||
if(w < 65536) out[j++] = EE[w];
|
|
||||||
else { w -= 65536; out[j++] = EE[0xD800 + ((w>>10)&1023)]; out[j++] = EE[0xDC00 + (w&1023)]; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
out = out.slice(0,j);
|
|
||||||
} else {
|
|
||||||
out = new Buffer(len);
|
|
||||||
for(i = 0; i < len; ++i) out[i] = EE[data[i].charCodeAt(0)];
|
|
||||||
}
|
|
||||||
if(!ofmt || ofmt === 'buf') return out;
|
|
||||||
if(ofmt !== 'arr') return out.toString('binary');
|
|
||||||
return [].slice.call(out);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
var sbcs_decode = function make_sbcs_decode(cp) {
|
|
||||||
var D = cpt[cp].dec;
|
|
||||||
var DD = new Buffer(131072), d=0, c="";
|
|
||||||
for(d=0;d<D.length;++d) {
|
|
||||||
if(!(c=D[d])) continue;
|
|
||||||
var w = c.charCodeAt(0);
|
|
||||||
DD[2*d] = w&255; DD[2*d+1] = w>>8;
|
|
||||||
}
|
|
||||||
return function sbcs_d(data) {
|
|
||||||
var len = data.length, i=0, j=0;
|
|
||||||
if(2 * len > mdl) { mdl = 2 * len; mdb = new Buffer(mdl); }
|
|
||||||
if(Buffer.isBuffer(data)) {
|
|
||||||
for(i = 0; i < len; i++) {
|
|
||||||
j = 2*data[i];
|
|
||||||
mdb[2*i] = DD[j]; mdb[2*i+1] = DD[j+1];
|
|
||||||
}
|
|
||||||
} else if(typeof data === "string") {
|
|
||||||
for(i = 0; i < len; i++) {
|
|
||||||
j = 2*data.charCodeAt(i);
|
|
||||||
mdb[2*i] = DD[j]; mdb[2*i+1] = DD[j+1];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for(i = 0; i < len; i++) {
|
|
||||||
j = 2*data[i];
|
|
||||||
mdb[2*i] = DD[j]; mdb[2*i+1] = DD[j+1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return mdb.slice(0, 2 * len).toString('ucs2');
|
|
||||||
};
|
|
||||||
};
|
|
||||||
var dbcs_encode = function make_dbcs_encode(cp) {
|
|
||||||
var E = cpt[cp].enc;
|
|
||||||
var EE = new Buffer(131072);
|
|
||||||
for(var i = 0; i < 131072; ++i) EE[i] = 0;
|
|
||||||
var keys = Object.keys(E);
|
|
||||||
for(var ee = 0, e = keys[ee]; ee < keys.length; ++ee) {
|
|
||||||
if(!(e = keys[ee])) continue;
|
|
||||||
var f = e.charCodeAt(0);
|
|
||||||
EE[2*f] = E[e] & 255; EE[2*f+1] = E[e]>>8;
|
|
||||||
}
|
|
||||||
return function dbcs_e(data, ofmt) {
|
|
||||||
var len = data.length, out = new Buffer(2*len), i=0, j=0, jj=0, k=0, D=0;
|
|
||||||
if(typeof data === 'string') {
|
|
||||||
for(i = k = 0; i < len; ++i) {
|
|
||||||
j = data.charCodeAt(i)*2;
|
|
||||||
out[k++] = EE[j+1] || EE[j]; if(EE[j+1] > 0) out[k++] = EE[j];
|
|
||||||
}
|
|
||||||
out = out.slice(0,k);
|
|
||||||
} else if(Buffer.isBuffer(data)) {
|
|
||||||
for(i = k = 0; i < len; ++i) {
|
|
||||||
D = data[i];
|
|
||||||
if(D < 128) j = D;
|
|
||||||
else if(D < 224) { j = ((D&31)<<6)+(data[i+1]&63); ++i; }
|
|
||||||
else if(D < 240) { j = ((D&15)<<12)+((data[i+1]&63)<<6)+(data[i+2]&63); i+=2; }
|
|
||||||
else { j = ((D&7)<<18)+((data[i+1]&63)<<12)+((data[i+2]&63)<<6)+(data[i+3]&63); i+=3; }
|
|
||||||
if(j<65536) { j*=2; out[k++] = EE[j+1] || EE[j]; if(EE[j+1] > 0) out[k++] = EE[j]; }
|
|
||||||
else { jj = j-65536;
|
|
||||||
j=2*(0xD800 + ((jj>>10)&1023)); out[k++] = EE[j+1] || EE[j]; if(EE[j+1] > 0) out[k++] = EE[j];
|
|
||||||
j=2*(0xDC00 + (jj&1023)); out[k++] = EE[j+1] || EE[j]; if(EE[j+1] > 0) out[k++] = EE[j];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
out = out.slice(0,k);
|
|
||||||
} else {
|
|
||||||
for(i = k = 0; i < len; i++) {
|
|
||||||
j = data[i].charCodeAt(0)*2;
|
|
||||||
out[k++] = EE[j+1] || EE[j]; if(EE[j+1] > 0) out[k++] = EE[j];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!ofmt || ofmt === 'buf') return out;
|
|
||||||
if(ofmt !== 'arr') return out.toString('binary');
|
|
||||||
return [].slice.call(out);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
var dbcs_decode = function make_dbcs_decode(cp) {
|
|
||||||
var D = cpt[cp].dec;
|
|
||||||
var DD = new Buffer(131072), d=0, c, w=0, j=0, i=0;
|
|
||||||
for(i = 0; i < 65536; ++i) { DD[2*i] = 0xFF; DD[2*i+1] = 0xFD;}
|
|
||||||
for(d = 0; d < D.length; ++d) {
|
|
||||||
if(!(c=D[d])) continue;
|
|
||||||
w = c.charCodeAt(0);
|
|
||||||
j = 2*d;
|
|
||||||
DD[j] = w&255; DD[j+1] = w>>8;
|
|
||||||
}
|
|
||||||
return function dbcs_d(data) {
|
|
||||||
var len = data.length, out = new Buffer(2*len), i=0, j=0, k=0;
|
|
||||||
if(Buffer.isBuffer(data)) {
|
|
||||||
for(i = 0; i < len; i++) {
|
|
||||||
j = 2*data[i];
|
|
||||||
if(DD[j]===0xFF && DD[j+1]===0xFD) { j=2*((data[i]<<8)+data[i+1]); ++i; }
|
|
||||||
out[k++] = DD[j]; out[k++] = DD[j+1];
|
|
||||||
}
|
|
||||||
} else if(typeof data === "string") {
|
|
||||||
for(i = 0; i < len; i++) {
|
|
||||||
j = 2*data.charCodeAt(i);
|
|
||||||
if(DD[j]===0xFF && DD[j+1]===0xFD) { j=2*((data.charCodeAt(i)<<8)+data.charCodeAt(i+1)); ++i; }
|
|
||||||
out[k++] = DD[j]; out[k++] = DD[j+1];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for(i = 0; i < len; i++) {
|
|
||||||
j = 2*data[i];
|
|
||||||
if(DD[j]===0xFF && DD[j+1]===0xFD) { j=2*((data[i]<<8)+data[i+1]); ++i; }
|
|
||||||
out[k++] = DD[j]; out[k++] = DD[j+1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return out.slice(0,k).toString('ucs2');
|
|
||||||
};
|
|
||||||
};
|
|
||||||
magic_decode[65001] = function utf8_d(data) {
|
|
||||||
if(typeof data === "string") return utf8_d(data.split("").map(cca));
|
|
||||||
var len = data.length, w = 0, ww = 0;
|
|
||||||
if(4 * len > mdl) { mdl = 4 * len; mdb = new Buffer(mdl); }
|
|
||||||
var i = 0;
|
|
||||||
if(len >= 3 && data[0] == 0xEF) if(data[1] == 0xBB && data[2] == 0xBF) i = 3;
|
|
||||||
for(var j = 1, k = 0, D = 0; i < len; i+=j) {
|
|
||||||
j = 1; D = data[i];
|
|
||||||
if(D < 128) w = D;
|
|
||||||
else if(D < 224) { w=(D&31)*64+(data[i+1]&63); j=2; }
|
|
||||||
else if(D < 240) { w=((D&15)<<12)+(data[i+1]&63)*64+(data[i+2]&63); j=3; }
|
|
||||||
else { w=(D&7)*262144+((data[i+1]&63)<<12)+(data[i+2]&63)*64+(data[i+3]&63); j=4; }
|
|
||||||
if(w < 65536) { mdb[k++] = w&255; mdb[k++] = w>>8; }
|
|
||||||
else {
|
|
||||||
w -= 65536; ww = 0xD800 + ((w>>10)&1023); w = 0xDC00 + (w&1023);
|
|
||||||
mdb[k++] = ww&255; mdb[k++] = ww>>>8; mdb[k++] = w&255; mdb[k++] = (w>>>8)&255;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return mdb.slice(0,k).toString('ucs2');
|
|
||||||
};
|
|
||||||
magic_encode[65001] = function utf8_e(data, ofmt) {
|
|
||||||
if(has_buf && Buffer.isBuffer(data)) {
|
|
||||||
if(!ofmt || ofmt === 'buf') return data;
|
|
||||||
if(ofmt !== 'arr') return data.toString('binary');
|
|
||||||
return [].slice.call(data);
|
|
||||||
}
|
|
||||||
var len = data.length, w = 0, ww = 0, j = 0;
|
|
||||||
var direct = typeof data === "string";
|
|
||||||
if(4 * len > mdl) { mdl = 4 * len; mdb = new Buffer(mdl); }
|
|
||||||
for(var i = 0; i < len; ++i) {
|
|
||||||
w = direct ? data.charCodeAt(i) : data[i].charCodeAt(0);
|
|
||||||
if(w <= 0x007F) mdb[j++] = w;
|
|
||||||
else if(w <= 0x07FF) {
|
|
||||||
mdb[j++] = 192 + (w >> 6);
|
|
||||||
mdb[j++] = 128 + (w&63);
|
|
||||||
} else if(w >= 0xD800 && w <= 0xDFFF) {
|
|
||||||
w -= 0xD800; ++i;
|
|
||||||
ww = (direct ? data.charCodeAt(i) : data[i].charCodeAt(0)) - 0xDC00 + (w << 10);
|
|
||||||
mdb[j++] = 240 + ((ww>>>18) & 0x07);
|
|
||||||
mdb[j++] = 144 + ((ww>>>12) & 0x3F);
|
|
||||||
mdb[j++] = 128 + ((ww>>>6) & 0x3F);
|
|
||||||
mdb[j++] = 128 + (ww & 0x3F);
|
|
||||||
} else {
|
|
||||||
mdb[j++] = 224 + (w >> 12);
|
|
||||||
mdb[j++] = 128 + ((w >> 6)&63);
|
|
||||||
mdb[j++] = 128 + (w&63);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!ofmt || ofmt === 'buf') return mdb.slice(0,j);
|
|
||||||
if(ofmt !== 'arr') return mdb.slice(0,j).toString('binary');
|
|
||||||
return [].slice.call(mdb, 0, j);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
var encache = function encache() {
|
|
||||||
if(has_buf) {
|
|
||||||
if(cpdcache[sbcs_cache[0]]) return;
|
|
||||||
var i=0, s=0;
|
|
||||||
for(i = 0; i < sbcs_cache.length; ++i) {
|
|
||||||
s = sbcs_cache[i];
|
|
||||||
if(cpt[s]) {
|
|
||||||
cpdcache[s] = sbcs_decode(s);
|
|
||||||
cpecache[s] = sbcs_encode(s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for(i = 0; i < dbcs_cache.length; ++i) {
|
|
||||||
s = dbcs_cache[i];
|
|
||||||
if(cpt[s]) {
|
|
||||||
cpdcache[s] = dbcs_decode(s);
|
|
||||||
cpecache[s] = dbcs_encode(s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for(i = 0; i < magic_cache.length; ++i) {
|
|
||||||
s = magic_cache[i];
|
|
||||||
if(magic_decode[s]) cpdcache[s] = magic_decode[s];
|
|
||||||
if(magic_encode[s]) cpecache[s] = magic_encode[s];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
var null_enc = function(data, ofmt) { return ""; };
|
|
||||||
var cp_decache = function cp_decache(cp) { delete cpdcache[cp]; delete cpecache[cp]; };
|
|
||||||
var decache = function decache() {
|
|
||||||
if(has_buf) {
|
|
||||||
if(!cpdcache[sbcs_cache[0]]) return;
|
|
||||||
sbcs_cache.forEach(cp_decache);
|
|
||||||
dbcs_cache.forEach(cp_decache);
|
|
||||||
magic_cache.forEach(cp_decache);
|
|
||||||
}
|
|
||||||
last_enc = null_enc; last_cp = 0;
|
|
||||||
};
|
|
||||||
var cache = {
|
|
||||||
encache: encache,
|
|
||||||
decache: decache,
|
|
||||||
sbcs: sbcs_cache,
|
|
||||||
dbcs: dbcs_cache
|
|
||||||
};
|
|
||||||
|
|
||||||
encache();
|
|
||||||
|
|
||||||
var BM = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
||||||
var SetD = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'(),-./:?";
|
|
||||||
var last_enc = null_enc, last_cp = 0;
|
|
||||||
var encode = function encode(cp, data, ofmt) {
|
|
||||||
if(cp === last_cp && last_enc) { return last_enc(data, ofmt); }
|
|
||||||
if(cpecache[cp]) { last_enc = cpecache[last_cp=cp]; return last_enc(data, ofmt); }
|
|
||||||
if(has_buf && Buffer.isBuffer(data)) data = data.toString('utf8');
|
|
||||||
var len = data.length;
|
|
||||||
var out = has_buf ? new Buffer(4*len) : [], w=0, i=0, j = 0, ww=0;
|
|
||||||
var C = cpt[cp], E, M = "";
|
|
||||||
var isstr = typeof data === 'string';
|
|
||||||
if(C && (E=C.enc)) for(i = 0; i < len; ++i, ++j) {
|
|
||||||
w = E[isstr? data.charAt(i) : data[i]];
|
|
||||||
if(w > 255) {
|
|
||||||
out[j] = w>>8;
|
|
||||||
out[++j] = w&255;
|
|
||||||
} else out[j] = w&255;
|
|
||||||
}
|
|
||||||
else if((M=magic[cp])) switch(M) {
|
|
||||||
case "utf8":
|
|
||||||
if(has_buf && isstr) { out = new Buffer(data, M); j = out.length; break; }
|
|
||||||
for(i = 0; i < len; ++i, ++j) {
|
|
||||||
w = isstr ? data.charCodeAt(i) : data[i].charCodeAt(0);
|
|
||||||
if(w <= 0x007F) out[j] = w;
|
|
||||||
else if(w <= 0x07FF) {
|
|
||||||
out[j] = 192 + (w >> 6);
|
|
||||||
out[++j] = 128 + (w&63);
|
|
||||||
} else if(w >= 0xD800 && w <= 0xDFFF) {
|
|
||||||
w -= 0xD800;
|
|
||||||
ww = (isstr ? data.charCodeAt(++i) : data[++i].charCodeAt(0)) - 0xDC00 + (w << 10);
|
|
||||||
out[j] = 240 + ((ww>>>18) & 0x07);
|
|
||||||
out[++j] = 144 + ((ww>>>12) & 0x3F);
|
|
||||||
out[++j] = 128 + ((ww>>>6) & 0x3F);
|
|
||||||
out[++j] = 128 + (ww & 0x3F);
|
|
||||||
} else {
|
|
||||||
out[j] = 224 + (w >> 12);
|
|
||||||
out[++j] = 128 + ((w >> 6)&63);
|
|
||||||
out[++j] = 128 + (w&63);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "ascii":
|
|
||||||
if(has_buf && typeof data === "string") { out = new Buffer(data, M); j = out.length; break; }
|
|
||||||
for(i = 0; i < len; ++i, ++j) {
|
|
||||||
w = isstr ? data.charCodeAt(i) : data[i].charCodeAt(0);
|
|
||||||
if(w <= 0x007F) out[j] = w;
|
|
||||||
else throw new Error("bad ascii " + w);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "utf16le":
|
|
||||||
if(has_buf && typeof data === "string") { out = new Buffer(data, M); j = out.length; break; }
|
|
||||||
for(i = 0; i < len; ++i) {
|
|
||||||
w = isstr ? data.charCodeAt(i) : data[i].charCodeAt(0);
|
|
||||||
out[j++] = w&255;
|
|
||||||
out[j++] = w>>8;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "utf16be":
|
|
||||||
for(i = 0; i < len; ++i) {
|
|
||||||
w = isstr ? data.charCodeAt(i) : data[i].charCodeAt(0);
|
|
||||||
out[j++] = w>>8;
|
|
||||||
out[j++] = w&255;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "utf32le":
|
|
||||||
for(i = 0; i < len; ++i) {
|
|
||||||
w = isstr ? data.charCodeAt(i) : data[i].charCodeAt(0);
|
|
||||||
if(w >= 0xD800 && w <= 0xDFFF) w = 0x10000 + ((w - 0xD800) << 10) + (data[++i].charCodeAt(0) - 0xDC00);
|
|
||||||
out[j++] = w&255; w >>= 8;
|
|
||||||
out[j++] = w&255; w >>= 8;
|
|
||||||
out[j++] = w&255; w >>= 8;
|
|
||||||
out[j++] = w&255;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "utf32be":
|
|
||||||
for(i = 0; i < len; ++i) {
|
|
||||||
w = isstr ? data.charCodeAt(i) : data[i].charCodeAt(0);
|
|
||||||
if(w >= 0xD800 && w <= 0xDFFF) w = 0x10000 + ((w - 0xD800) << 10) + (data[++i].charCodeAt(0) - 0xDC00);
|
|
||||||
out[j+3] = w&255; w >>= 8;
|
|
||||||
out[j+2] = w&255; w >>= 8;
|
|
||||||
out[j+1] = w&255; w >>= 8;
|
|
||||||
out[j] = w&255;
|
|
||||||
j+=4;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "utf7":
|
|
||||||
for(i = 0; i < len; i++) {
|
|
||||||
var c = isstr ? data.charAt(i) : data[i].charAt(0);
|
|
||||||
if(c === "+") { out[j++] = 0x2b; out[j++] = 0x2d; continue; }
|
|
||||||
if(SetD.indexOf(c) > -1) { out[j++] = c.charCodeAt(0); continue; }
|
|
||||||
var tt = encode(1201, c);
|
|
||||||
out[j++] = 0x2b;
|
|
||||||
out[j++] = BM.charCodeAt(tt[0]>>2);
|
|
||||||
out[j++] = BM.charCodeAt(((tt[0]&0x03)<<4) + ((tt[1]||0)>>4));
|
|
||||||
out[j++] = BM.charCodeAt(((tt[1]&0x0F)<<2) + ((tt[2]||0)>>6));
|
|
||||||
out[j++] = 0x2d;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default: throw new Error("Unsupported magic: " + cp + " " + magic[cp]);
|
|
||||||
}
|
|
||||||
else throw new Error("Unrecognized CP: " + cp);
|
|
||||||
out = out.slice(0,j);
|
|
||||||
if(!has_buf) return (ofmt == 'str') ? (out).map(sfcc).join("") : out;
|
|
||||||
if(!ofmt || ofmt === 'buf') return out;
|
|
||||||
if(ofmt !== 'arr') return out.toString('binary');
|
|
||||||
return [].slice.call(out);
|
|
||||||
};
|
|
||||||
var decode = function decode(cp, data) {
|
|
||||||
var F; if((F=cpdcache[cp])) return F(data);
|
|
||||||
if(typeof data === "string") return decode(cp, data.split("").map(cca));
|
|
||||||
var len = data.length, out = new Array(len), s="", w=0, i=0, j=1, k=0, ww=0;
|
|
||||||
var C = cpt[cp], D, M="";
|
|
||||||
if(C && (D=C.dec)) {
|
|
||||||
for(i = 0; i < len; i+=j) {
|
|
||||||
j = 2;
|
|
||||||
s = D[(data[i]<<8)+ data[i+1]];
|
|
||||||
if(!s) {
|
|
||||||
j = 1;
|
|
||||||
s = D[data[i]];
|
|
||||||
}
|
|
||||||
if(!s) throw new Error('Unrecognized code: ' + data[i] + ' ' + data[i+j-1] + ' ' + i + ' ' + j + ' ' + D[data[i]]);
|
|
||||||
out[k++] = s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if((M=magic[cp])) switch(M) {
|
|
||||||
case "utf8":
|
|
||||||
if(len >= 3 && data[0] == 0xEF) if(data[1] == 0xBB && data[2] == 0xBF) i = 3;
|
|
||||||
for(; i < len; i+=j) {
|
|
||||||
j = 1;
|
|
||||||
if(data[i] < 128) w = data[i];
|
|
||||||
else if(data[i] < 224) { w=(data[i]&31)*64+(data[i+1]&63); j=2; }
|
|
||||||
else if(data[i] < 240) { w=((data[i]&15)<<12)+(data[i+1]&63)*64+(data[i+2]&63); j=3; }
|
|
||||||
else { w=(data[i]&7)*262144+((data[i+1]&63)<<12)+(data[i+2]&63)*64+(data[i+3]&63); j=4; }
|
|
||||||
if(w < 65536) { out[k++] = String.fromCharCode(w); }
|
|
||||||
else {
|
|
||||||
w -= 65536; ww = 0xD800 + ((w>>10)&1023); w = 0xDC00 + (w&1023);
|
|
||||||
out[k++] = String.fromCharCode(ww); out[k++] = String.fromCharCode(w);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "ascii":
|
|
||||||
if(has_buf && Buffer.isBuffer(data)) return data.toString(M);
|
|
||||||
for(i = 0; i < len; i++) out[i] = String.fromCharCode(data[i]);
|
|
||||||
k = len; break;
|
|
||||||
case "utf16le":
|
|
||||||
if(len >= 2 && data[0] == 0xFF) if(data[1] == 0xFE) i = 2;
|
|
||||||
if(has_buf && Buffer.isBuffer(data)) return data.toString(M);
|
|
||||||
j = 2;
|
|
||||||
for(; i+1 < len; i+=j) {
|
|
||||||
out[k++] = String.fromCharCode((data[i+1]<<8) + data[i]);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "utf16be":
|
|
||||||
if(len >= 2 && data[0] == 0xFE) if(data[1] == 0xFF) i = 2;
|
|
||||||
j = 2;
|
|
||||||
for(; i+1 < len; i+=j) {
|
|
||||||
out[k++] = String.fromCharCode((data[i]<<8) + data[i+1]);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "utf32le":
|
|
||||||
if(len >= 4 && data[0] == 0xFF) if(data[1] == 0xFE && data[2] === 0 && data[3] === 0) i = 4;
|
|
||||||
j = 4;
|
|
||||||
for(; i < len; i+=j) {
|
|
||||||
w = (data[i+3]<<24) + (data[i+2]<<16) + (data[i+1]<<8) + (data[i]);
|
|
||||||
if(w > 0xFFFF) {
|
|
||||||
w -= 0x10000;
|
|
||||||
out[k++] = String.fromCharCode(0xD800 + ((w >> 10) & 0x3FF));
|
|
||||||
out[k++] = String.fromCharCode(0xDC00 + (w & 0x3FF));
|
|
||||||
}
|
|
||||||
else out[k++] = String.fromCharCode(w);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "utf32be":
|
|
||||||
if(len >= 4 && data[3] == 0xFF) if(data[2] == 0xFE && data[1] === 0 && data[0] === 0) i = 4;
|
|
||||||
j = 4;
|
|
||||||
for(; i < len; i+=j) {
|
|
||||||
w = (data[i]<<24) + (data[i+1]<<16) + (data[i+2]<<8) + (data[i+3]);
|
|
||||||
if(w > 0xFFFF) {
|
|
||||||
w -= 0x10000;
|
|
||||||
out[k++] = String.fromCharCode(0xD800 + ((w >> 10) & 0x3FF));
|
|
||||||
out[k++] = String.fromCharCode(0xDC00 + (w & 0x3FF));
|
|
||||||
}
|
|
||||||
else out[k++] = String.fromCharCode(w);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "utf7":
|
|
||||||
if(len >= 4 && data[0] == 0x2B && data[1] == 0x2F && data[2] == 0x76) {
|
|
||||||
if(len >= 5 && data[3] == 0x38 && data[4] == 0x2D) i = 5;
|
|
||||||
else if(data[3] == 0x38 || data[3] == 0x39 || data[3] == 0x2B || data[3] == 0x2F) i = 4;
|
|
||||||
}
|
|
||||||
for(; i < len; i+=j) {
|
|
||||||
if(data[i] !== 0x2b) { j=1; out[k++] = String.fromCharCode(data[i]); continue; }
|
|
||||||
j=1;
|
|
||||||
if(data[i+1] === 0x2d) { j = 2; out[k++] = "+"; continue; }
|
|
||||||
while(String.fromCharCode(data[i+j]).match(/[A-Za-z0-9+\/]/)) j++;
|
|
||||||
var dash = 0;
|
|
||||||
if(data[i+j] === 0x2d) { ++j; dash=1; }
|
|
||||||
var tt = [];
|
|
||||||
var o64 = "";
|
|
||||||
var c1=0, c2=0, c3=0;
|
|
||||||
var e1=0, e2=0, e3=0, e4=0;
|
|
||||||
for(var l = 1; l < j - dash;) {
|
|
||||||
e1 = BM.indexOf(String.fromCharCode(data[i+l++]));
|
|
||||||
e2 = BM.indexOf(String.fromCharCode(data[i+l++]));
|
|
||||||
c1 = e1 << 2 | e2 >> 4;
|
|
||||||
tt.push(c1);
|
|
||||||
e3 = BM.indexOf(String.fromCharCode(data[i+l++]));
|
|
||||||
if(e3 === -1) break;
|
|
||||||
c2 = (e2 & 15) << 4 | e3 >> 2;
|
|
||||||
tt.push(c2);
|
|
||||||
e4 = BM.indexOf(String.fromCharCode(data[i+l++]));
|
|
||||||
if(e4 === -1) break;
|
|
||||||
c3 = (e3 & 3) << 6 | e4;
|
|
||||||
if(e4 < 64) tt.push(c3);
|
|
||||||
}
|
|
||||||
o64 = decode(1201, tt);
|
|
||||||
for(l = 0; l < o64.length; ++l) out[k++] = o64.charAt(l);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default: throw new Error("Unsupported magic: " + cp + " " + magic[cp]);
|
|
||||||
}
|
|
||||||
else throw new Error("Unrecognized CP: " + cp);
|
|
||||||
return out.slice(0,k).join("");
|
|
||||||
};
|
|
||||||
var hascp = function hascp(cp) { return !!(cpt[cp] || magic[cp]); };
|
|
||||||
cpt.utils = { decode: decode, encode: encode, hascp: hascp, magic: magic, cache:cache };
|
|
||||||
return cpt;
|
|
||||||
}));
|
|
||||||
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.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user