Compare commits

...
146 Commits
Author SHA1 Message Date
n1474335 a62a6c2aa4 9.11.4 2019-11-13 18:05:31 +00:00
n1474335 4be06f6779 Merge branch 'n1073645-master' 2019-11-13 18:04:51 +00:00
n1474335 03f4740968 Tidied up consumeWhile and consumeUntil 2019-11-13 18:04:36 +00:00
n1474335 ea6d80edfb Merge branch 'master' of https://github.com/n1073645/CyberChef into n1073645-master 2019-11-13 17:59:51 +00:00
n1474335 68e8a221ff 9.11.3 2019-11-13 17:59:22 +00:00
n1474335 cce84c3782 Fixed bug in Base62 operations when using different alphabets 2019-11-13 17:59:16 +00:00
n1073645 c1878ca28b Linting adjustments 2019-11-13 17:15:54 +00:00
n1073645 e9b7a43b9a Adjustment to consumeWhile 2019-11-13 17:11:04 +00:00
n1073645 3921b4f445 Small correction to continueWhile 2019-11-13 09:59:55 +00:00
n1073645 dfd4cca43f Corrections 2019-11-13 09:02:36 +00:00
n1073645 4541d75f49 Improved continueUntil, added consumeWhile and made the EVTX extractor more complete 2019-11-12 13:17:04 +00:00
n1073645 9eda670026 up-to-date 2019-11-12 11:06:10 +00:00
n1073645 d3c13b118d Improved continueUntil, added consumeWhile and made the EVTX extractor more complete 2019-11-12 11:00:43 +00:00
n1073645 8e2345cf9e Improved continueUntil, added consumeWhile and made the EVTX extractor more complete 2019-11-11 16:08:03 +00:00
n1073645 d240d65c5f Improved continueUntil, added consumeWhile and made the EVTX extractor more complete 2019-11-11 15:47:16 +00:00
n1474335 d3473a7462 9.11.2 2019-11-08 17:35:38 +00:00
n1474335 6bfe4ee238 Merge branch 'n1073645-master' 2019-11-08 17:34:39 +00:00
n1474335 e61b7d598e Tidied up FileSignatures.mjs 2019-11-08 17:34:25 +00:00
n1073645 eb81b9217e SQLITE, EVT, EVTX and Signatures added 2019-11-08 17:08:14 +00:00
n1073645 4d9bfcad20 Comment the WAV extractor. 2019-11-08 15:00:20 +00:00
n1073645 2387452a56 Comment the WAV extractor. 2019-11-08 14:59:06 +00:00
n1073645 a4772941a7 Added WAV extractor. 2019-11-08 14:56:54 +00:00
n1474335 6318f78e29 9.11.1 2019-11-08 13:50:00 +00:00
n1474335 5e6f3cc5b4 Merge branch 'n1073645-master' 2019-11-08 13:49:51 +00:00
n1474335 04f1fa06ad Tidied up GIF and BZIP2 extractors 2019-11-08 13:49:39 +00:00
n1474335 8d660e53b2 Merge branch 'master' of https://github.com/n1073645/CyberChef into n1073645-master 2019-11-08 13:43:54 +00:00
n1073645 f3864b00fe Made GIF extractor more robust 2019-11-08 13:40:09 +00:00
n1073645 51cc94bf2a Made GIF extractor more robust 2019-11-08 13:38:17 +00:00
n1073645 f63d1354ba Merge pull request #878 from n1073645/master
Added extractors for BZIP2, XZ, GIF89
2019-11-08 11:56:26 +00:00
n1073645 80362cfa84 Bzip2 extractor completed 2019-11-08 11:39:50 +00:00
n1073645 447a6d7524 Comments for GIF. 2019-11-07 16:50:10 +00:00
n1073645 f022440b4a Tidied GIFextractor 2019-11-07 16:20:09 +00:00
n1073645 4f5e0c007d GIF extractor for GIF89a 2019-11-07 15:06:30 +00:00
n1073645 b83f6591bb XZ compression 2019-11-07 10:13:40 +00:00
n1073645 77a9481cf9 xz compression 2019-11-07 09:20:24 +00:00
n1474335 a8f029309d 9.11.0 2019-11-06 13:38:32 +00:00
n1474335 b0df8b7dca Updated CHANGELOG 2019-11-06 13:37:31 +00:00
n1474335 2cc05717e6 Merge branch 'cbeuw-blowfish-fix' 2019-11-06 13:34:31 +00:00
n1474335 b96394131f Tidied up Blowfish tests 2019-11-06 13:34:17 +00:00
n1474335 875c1019b2 Merge branch 'blowfish-fix' of https://github.com/cbeuw/CyberChef into cbeuw-blowfish-fix 2019-11-06 13:22:50 +00:00
n1474335 d1a0a39efa Merge branch 'dkarpo-master' 2019-11-06 13:21:42 +00:00
n1474335 fdfbf7ddf8 Merge branch 'master' of https://github.com/dkarpo/CyberChef into dkarpo-master 2019-11-06 13:20:41 +00:00
n1474335 414f8b5ba9 Added link to Lorenz wiki article in operation description 2019-11-06 13:17:44 +00:00
Derrick Karpo 03a1c566fc Add file extensions which are mandatory for the latest Node 12.x.
Note: This doesn't solve the upstream import's which still don't
comply but it preps CyberChef for it.
2019-11-06 06:01:52 -07:00
n1474335 0fc1c37e65 9.10.0 2019-11-06 12:17:41 +00:00
n1474335 6b4efb420e Updated CHANGELOG 2019-11-06 12:16:35 +00:00
n1474335 9ed2b26933 Tidied up Lorenz operation and created new Bletchley module for WW2-era ciphers 2019-11-06 12:14:22 +00:00
n1474335 70665534b8 Merge branch 'master' of https://github.com/VirtualColossus/CyberChef 2019-11-06 12:00:37 +00:00
n1474335 7244d4d343 9.9.0 2019-11-01 14:57:46 +00:00
n1474335 980c1e8681 Updated CHANGELOG 2019-11-01 14:57:41 +00:00
n1474335 e1378860d6 Added support for 109 more character encodings 2019-11-01 14:56:18 +00:00
VirtualColossus b9571db9f1 Merge branch 'master' into master 2019-10-31 15:33:54 +00:00
n1474335 734962ac22 9.8.0 2019-10-31 14:21:03 +00:00
n1474335 35103bf155 Updated CHANGELOG 2019-10-31 14:20:55 +00:00
n1474335 4c4d7b5d26 Merge branch 'jarrodconnolly-avro-to-json' 2019-10-31 14:17:55 +00:00
n1474335 daad633195 Tidied up Avro to JSON operation 2019-10-31 14:17:07 +00:00
VirtualColossus d5cfe9f262 removed duplicate test 2019-10-31 13:54:52 +00:00
n1474335 a2c46b3f66 Merge branch 'avro-to-json' of https://github.com/jarrodconnolly/CyberChef into jarrodconnolly-avro-to-json 2019-10-31 13:54:00 +00:00
n1474335 6a1d11b9b5 Argument hints are not tooltips instead of bmd-help elements 2019-10-31 13:39:06 +00:00
n1474335 0630c094e0 9.7.20 2019-10-31 13:00:22 +00:00
n1474335 ace71f20b3 Merge branch 'gsilvapt-master' 2019-10-31 13:00:15 +00:00
VirtualColossus c0e02451a1 Fixed bug using KT option, added tests 2019-10-31 07:28:33 +00:00
Jarrod Connolly 2d12a16771 Add Avro to JSON data format conversion 2019-10-30 22:09:42 -07:00
Gustavo Silva 9108b3923b diff.mjs: Fixes tests and adds default flag
* Sets default flag to `false` for `showSubtraction` flag.
    * Removes extra span for else case that was causing some tests to
    fail. Moreover, the previous behavior was defined as that.
    * Adds custom test for the showSubtraction option, both using the
    `showAdded` and `showRemoved` flags.
2019-10-29 23:39:14 +00:00
Gustavo Silva 726e117656 diff.mjs: Allows showing subtraction
Adds "Show Subtraction" button to allow seeing only the difference
    between two texts.
    When selected and combined, user can see only the characters or
    words that were added. If not combined, with either removed or added
    but selected, then nothing is displayed.
2019-10-29 23:12:24 +00:00
VirtualColossus ab524fff15 Mixed tabs & spaces 2019-10-29 21:52:18 +00:00
VirtualColossus 55eae9910f Tidied run function, added some tests 2019-10-29 21:39:29 +00:00
VirtualColossus d3138a7fdf Merge remote-tracking branch 'upstream/master' 2019-10-28 22:23:28 +00:00
n1474335 05e65a74ce Improved Magic scoring slightly 2019-10-28 17:26:13 +00:00
n1474335 6d138f345f 9.7.19 2019-10-27 15:27:36 +00:00
n1474335 3c165dd7e8 Merge branch 'mattnotmitt-chores/yara-update' 2019-10-27 15:27:12 +00:00
n1474335 04561d29b5 Dependency update 2019-10-27 15:26:48 +00:00
n1474335 e5e6c1a2dd Merge branch 'chores/yara-update' of https://github.com/mattnotmitt/CyberChef into mattnotmitt-chores/yara-update 2019-10-27 15:23:47 +00:00
n1474335 882efea314 Updated README 2019-10-27 15:21:41 +00:00
n1474335 89d979d92e Merge branch 'rianadon-theme-by-url' 2019-10-27 15:17:33 +00:00
n1474335 383aab5f85 Improved theme selection. Added changeTheme method. 2019-10-27 15:17:06 +00:00
n1474335 6659174f88 Merge branch 'theme-by-url' of https://github.com/rianadon/CyberChef into rianadon-theme-by-url 2019-10-27 14:43:59 +00:00
n1474335 3ca29b8744 Merge branch 'brian-digital-labs-autofocus-search' 2019-10-27 14:39:05 +00:00
n1474335 726bf3345e Added tabindex to ingredients 2019-10-27 14:38:55 +00:00
n1474335 b2d61482d5 Merge branch 'autofocus-search' of https://github.com/brian-digital-labs/CyberChef into brian-digital-labs-autofocus-search 2019-10-27 14:17:06 +00:00
n1474335 88d8e9a7f9 9.7.18 2019-10-27 14:13:37 +00:00
n1474335 0b0ddd3140 Merge branch 'mattnotmitt-chores/nightwatch-update' 2019-10-27 14:12:22 +00:00
Matt 3d4f74945c Update nightwatch and chromedriver
Rebase onto master
2019-10-26 16:59:41 +01:00
Matt 4387038351 Update libyara-wasm 2019-10-26 16:14:25 +01:00
Brian Hoang 49f444dfe9 auto focus on search bar and made searchbar and text area tab-able 2019-10-26 15:30:27 +01:00
Ryan Adolf 061533bb57 Document theme option in README 2019-10-24 16:37:10 -07:00
Ryan Adolf 6e2fb67d76 Theme configuration through url 2019-10-24 16:32:14 -07:00
n1474335 60f5093c6c Update .travis.yml 2019-10-21 13:56:52 +01:00
n1474335 665f91ec37 Update README.md 2019-10-21 13:49:42 +01:00
n1474335 0805a011b9 9.7.17 2019-10-18 13:57:26 +01:00
n1474335 3e3322e1f0 Fork no longer appends its merge delimiter to the end of the output. Closes #692 2019-10-18 13:57:21 +01:00
Matt 252b1b65c4 Add YARA rules node test 2019-10-18 12:58:17 +01:00
Matt e8b4536ec2 Updated yara to v3.11.0 and openssl to v1.1.1d
finally managed to fudge the compiler
2019-10-18 12:57:13 +01:00
n1474335 61d40b5a0b 9.7.16 2019-10-18 11:11:17 +01:00
n1474335 d175aa958c DES no longer requires an IV in ECB mode 2019-10-18 11:09:12 +01:00
n1474335 ac3c220789 9.7.15 2019-10-16 17:36:25 +01:00
n1474335 add65e121a Merge branch 'Storms-Engineering-master' 2019-10-16 17:36:02 +01:00
n1474335 de2e757691 Merge branch 'master' of https://github.com/Storms-Engineering/CyberChef into Storms-Engineering-master 2019-10-16 17:34:58 +01:00
n1474335 eb34ab4f6a 9.7.14 2019-10-16 17:23:59 +01:00
n1474335 08e4232166 Merge branch 'wh0-backslash' 2019-10-16 17:23:47 +01:00
n1474335 adf9772928 Added tests for Utils.parseEscapedChars 2019-10-16 17:22:48 +01:00
n1474335 562171ec86 Merge branch 'backslash' of https://github.com/wh0/CyberChef into wh0-backslash 2019-10-16 16:47:01 +01:00
n1474335 e9e162319f Merge branch 'BjoernAkAManf-master' 2019-10-16 16:32:20 +01:00
n1474335 17c9ffe107 Tidied up chainCommands function in Gruntfile 2019-10-16 16:32:06 +01:00
n1474335 1831c84a29 Merge branch 'master' of https://github.com/BjoernAkAManf/CyberChef into BjoernAkAManf-master 2019-10-16 16:23:09 +01:00
n1474335 7e27449204 Fixed search box appaerance in Firefox 2019-10-16 16:12:22 +01:00
n1474335 282476d530 Merge branch 'Xenonym-chore/remove-duplicate-issue-template' 2019-10-16 16:04:49 +01:00
n1474335 fce0728d5d Updated bug report template 2019-10-16 16:04:36 +01:00
n1474335 0e9ac90607 Merge branch 'chore/remove-duplicate-issue-template' of https://github.com/Xenonym/CyberChef into Xenonym-chore/remove-duplicate-issue-template 2019-10-16 15:59:59 +01:00
n1474335 5383f56b26 9.7.13 2019-10-16 15:51:06 +01:00
n1474335 a02484c6cd Merge branch 'Storms-Engineering-IV-length-Error' 2019-10-16 15:50:51 +01:00
n1474335 be365f66ef Added length check to Triple DES IVs 2019-10-16 15:50:37 +01:00
n1474335 011dc09d5e Merge branch 'IV-length-Error' of https://github.com/Storms-Engineering/CyberChef into Storms-Engineering-IV-length-Error 2019-10-16 15:43:47 +01:00
n1474335 fc4d6d2d2e 9.7.12 2019-10-16 15:39:56 +01:00
n1474335 9d73127cae Fixed some typos 2019-10-16 15:38:20 +01:00
n1474335 223743e3b5 Removed Clippy 2019-10-16 15:37:18 +01:00
n1474335 44ed372f21 9.7.11 2019-10-16 15:10:16 +01:00
n1474335 4d1f970105 Added test to ensure all operations are in a category. Added various operations to categories. 2019-10-16 15:10:03 +01:00
Storms-Engineering 3e93580aa4 DES Encrypt/Decrypt - checks length of IV string
Checks the length of IV string when encrypting.  DES encrypt/decrypt test swas updated to use utf8 instead of HEX.
2019-10-12 09:42:13 -08:00
Storms-Engineering 7a3ca027bb PHP Deserialize NULL values converted to correctly
PHP Deserialize now correctly returns N as a null instead of an empty object
2019-10-12 05:56:10 -08:00
Tan Zhen Yong 3c021919dd Rename feature request issue template
- to remain consistent with other issue templates using a `-` instead of `_`
2019-10-12 16:17:40 +08:00
Tan Zhen Yong 2106e8ddb0 Remove duplicate bug report issue template
The bug report issue template is duplicated (`bug-report.md` and
`bug_report.md`, note the `-`/`_` difference).

Thus, GitHub was unable to use the bug report issue template, and it
does not show up when a new issue is being created.

Let's remove the duplicate template `bug_report.md`.
2019-10-12 16:13:40 +08:00
wh0 d60d595254 Utils: don't consume three backslashes at a time 2019-10-06 17:07:58 -07:00
Björn Heinrichs c28999ec6f Fixed building on Windows
On Windows OperationConfig was not generated.
See #360 #645 for more Information.
2019-10-03 02:23:18 +02:00
Andy Wang 9872578d51 Add reference Python script 2019-10-01 23:20:27 +01:00
Andy Wang 3014696fcd Adapt API tests to comply with length requirements 2019-10-01 23:10:54 +01:00
Andy Wang 6b70f77dcd Add tests 2019-10-01 23:08:32 +01:00
Andy Wang 7f6d8bffe3 Remove unnecessary IV adaptation 2019-10-01 22:54:21 +01:00
Andy Wang 458307f5ed Add invalid key length error message 2019-10-01 22:53:50 +01:00
Andy Wang 294aa826f1 Remove base64 options 2019-10-01 22:53:10 +01:00
Andy Wang 912d63067c Fix #578 by refactoring and implementing the modes 2019-09-26 23:02:03 +01:00
Martin Gillow 8ece8ebec2 Updated description 2019-04-01 13:40:53 +01:00
martin gillow 4d39c3bbd2 Fixed code spacing and formatting 2019-03-30 13:42:29 +00:00
martin gillow 23ddb87c9f Fixed code spacing and formatting 2019-03-30 13:02:14 +00:00
martin gillow db662a7662 Removed debug. Final testing 2019-03-30 10:13:25 +00:00
martin gillow 39f3383709 Renamed option 2019-03-27 20:57:04 +00:00
martin gillow 4f8fc8d65e Fixed p5 limitation 2019-03-27 20:44:57 +00:00
Martin Gillow 0397ba857f Fixed motor wheel movement 2019-03-27 13:02:18 +00:00
martin gillow 444fb4555b Custom wheel settings 2019-03-25 21:10:47 +00:00
martin gillow 294f890a92 Merge branch 'master' of https://github.com/VirtualColossus/CyberChef 2019-03-25 19:47:50 +00:00
martin gillow 578502187d Added custom lug option 2019-03-25 19:37:20 +00:00
Martin Gillow 786082a9d0 Adding Lorenz SZ40/42 operation 2019-03-25 13:43:34 +00:00
Martin Gillow b6eb851a13 Added Lorenz SZ40/42 operation 2019-03-25 13:34:25 +00:00
Martin Gillow 93c41f044c Added Lorenz SZ40/42 operation 2019-03-25 13:31:13 +00:00
VirtualColossus a7f61397f7 Added Lorenz SZ40/42 Operation 2019-03-25 13:26:26 +00:00
VirtualColossus 0f5f20247a Added Lorenz SZ40/42 operation 2019-03-25 13:25:13 +00:00
101 changed files with 2831 additions and 3838 deletions

No files matched your search

+1 -2
View File
@@ -1,2 +1 @@
src/core/vendor/**
src/web/static/clippy_assets/**
src/core/vendor/**
+2 -2
View File
@@ -26,8 +26,8 @@ If applicable, add screenshots to help explain your problem.
**Desktop (if relevant, please complete the following information):**
- OS: [e.g. Windows]
- Browser [e.g. chrome, safari]
- Version [e.g. 22]
- Browser: [e.g. chrome 72, firefox 60]
- CyberChef version: [e.g. 9.7.14]
**Additional context**
Add any other context about the problem here.
-34
View File
@@ -1,34 +0,0 @@
---
name: Bug report
about: Create a report to help us improve
title: 'Bug report: <Insert title here>'
labels: bug
assignees: ''
---
<!-- Prefix the title above with 'Bug report:' -->
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior or a link to the recipe / input used to cause the bug:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Desktop (if relevant, please complete the following information):**
- OS: [e.g. Windows]
- Browser [e.g. chrome, safari]
- Version [e.g. 22]
**Additional context**
Add any other context about the problem here.
+1 -1
View File
@@ -1,6 +1,6 @@
language: node_js
node_js:
- lts/*
- lts/dubnium
cache: npm
addons:
chrome: stable
+22
View File
@@ -2,6 +2,18 @@
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]
@@ -185,6 +197,10 @@ 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
@@ -262,6 +278,9 @@ All major and minor version changes will be documented in this file. Details of
[@Ge0rg3]: https://github.com/Ge0rg3
[@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
[#173]: https://github.com/gchq/CyberChef/pull/173
@@ -308,6 +327,7 @@ All major and minor version changes will be documented in this file. Details of
[#515]: https://github.com/gchq/CyberChef/pull/515
[#516]: https://github.com/gchq/CyberChef/pull/516
[#525]: https://github.com/gchq/CyberChef/pull/525
[#528]: https://github.com/gchq/CyberChef/pull/528
[#530]: https://github.com/gchq/CyberChef/pull/530
[#531]: https://github.com/gchq/CyberChef/pull/531
[#533]: https://github.com/gchq/CyberChef/pull/533
@@ -322,3 +342,5 @@ All major and minor version changes will be documented in this file. Details of
[#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
+37 -18
View File
@@ -14,7 +14,6 @@ const path = require("path");
* @license Apache-2.0
*/
module.exports = function (grunt) {
grunt.file.defaultEncoding = "utf8";
grunt.file.preserveBOM = false;
@@ -102,6 +101,26 @@ module.exports = function (grunt) {
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({
clean: {
dev: ["build/dev/*"],
@@ -316,10 +335,10 @@ module.exports = function (grunt) {
},
exec: {
repoSize: {
command: [
command: chainCommands([
"git ls-files | wc -l | xargs printf '\n%b\ttracked files\n'",
"du -hs | egrep -o '^[^\t]*' | xargs printf '%b\trepository size\n'"
].join(";"),
]),
stderr: false
},
cleanGit: {
@@ -329,20 +348,20 @@ module.exports = function (grunt) {
command: "node --experimental-modules --no-warnings --no-deprecation src/web/static/sitemap.mjs > build/prod/sitemap.xml"
},
generateConfig: {
command: [
command: chainCommands([
"echo '\n--- Regenerating config files. ---'",
"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/generateConfig.mjs",
"echo '--- Config scripts finished. ---\n'"
].join(";")
])
},
generateNodeIndex: {
command: [
command: chainCommands([
"echo '\n--- Regenerating node index ---'",
"node --experimental-modules --no-warnings --no-deprecation src/node/config/scripts/generateNodeIndex.mjs",
"echo '--- Node index generated. ---\n'"
].join(";"),
]),
},
opTests: {
command: "node --experimental-modules --no-warnings --no-deprecation tests/operations/index.mjs"
@@ -354,40 +373,40 @@ module.exports = function (grunt) {
command: "node --experimental-modules --no-warnings --no-deprecation tests/node/index.mjs"
},
setupNodeConsumers: {
command: [
"echo '\n--- Testing node conumers ---'",
command: chainCommands([
"echo '\n--- Testing node consumers ---'",
"npm link",
`mkdir ${nodeConsumerTestPath}`,
`cp tests/node/consumers/* ${nodeConsumerTestPath}`,
`cd ${nodeConsumerTestPath}`,
"npm link cyberchef"
].join(";"),
]),
},
teardownNodeConsumers: {
command: [
command: chainCommands([
`rm -rf ${nodeConsumerTestPath}`,
"echo '\n--- Node consumer tests complete ---'"
].join(";"),
]),
},
testCJSNodeConsumer: {
command: [
command: chainCommands([
`cd ${nodeConsumerTestPath}`,
"node --no-warnings cjs-consumer.js",
].join(";"),
]),
stdout: false,
},
testESMNodeConsumer: {
command: [
command: chainCommands([
`cd ${nodeConsumerTestPath}`,
"node --no-warnings --experimental-modules esm-consumer.mjs",
].join(";"),
]),
stdout: false,
},
testESMDeepImportNodeConsumer: {
command: [
command: chainCommands([
`cd ${nodeConsumerTestPath}`,
"node --no-warnings --experimental-modules esm-deep-import-consumer.mjs",
].join(";"),
]),
stdout: false,
},
},
+9 -1
View File
@@ -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.
- 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.
- 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
+66 -29
View File
@@ -1,6 +1,6 @@
{
"name": "cyberchef",
"version": "9.7.10",
"version": "9.11.4",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -2149,6 +2149,11 @@
}
}
},
"avsc": {
"version": "5.4.16",
"resolved": "https://registry.npmjs.org/avsc/-/avsc-5.4.16.tgz",
"integrity": "sha512-Z85B8ZaEU2PWNPRJYuMSp5Hg7Nw3KPKW47lW/Kus7AcwV7fr6uJG3UckagqIPLydIeO/Cm+yjnJG7g0tliICOg=="
},
"aws-sign2": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
@@ -3107,9 +3112,9 @@
}
},
"chromedriver": {
"version": "76.0.1",
"resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-76.0.1.tgz",
"integrity": "sha512-+8BCemJLKPF2w/UpzA1uNgLWQrg1IgIO4ZYcsAjYYgqD8zUcvQ+RfwA/0TR1Zwv9Mkd8fdzTe21eZ2FyZ83DAg==",
"version": "77.0.0",
"resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-77.0.0.tgz",
"integrity": "sha512-mZa1IVx4HD8rDaItWbnS470mmypgiWsDiu98r0NkiT4uLm3qrANl4vOU6no6vtWtLQiW5kt1POcIbjeNpsLbXA==",
"dev": true,
"requires": {
"del": "^4.1.1",
@@ -3190,14 +3195,6 @@
"integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=",
"dev": true
},
"clippyjs": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/clippyjs/-/clippyjs-0.0.3.tgz",
"integrity": "sha512-i4sPaKbCA6PfXiwxNK35E1io6AXN7VGwEGZR9sE8RqOgXPNtRWKbFubmx87JwSuwIrdClO/rkTMjhl2ZyOHjug==",
"requires": {
"jquery": "^3.2.1"
}
},
"cliui": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
@@ -3254,6 +3251,22 @@
"integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
"dev": true
},
"codepage": {
"version": "1.14.0",
"resolved": "https://registry.npmjs.org/codepage/-/codepage-1.14.0.tgz",
"integrity": "sha1-jL4lSBMjVZ19MHVxsP/5HnodL5k=",
"requires": {
"commander": "~2.14.1",
"exit-on-epipe": "~1.0.1"
},
"dependencies": {
"commander": {
"version": "2.14.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.14.1.tgz",
"integrity": "sha512-+YR16o3rK53SmWHU3rEM3tPAh2rwb1yPcQX5irVn7mb0gXbwuCCrnkbV5+PBfETdfg1vui07nM6PCG1zndcjQw=="
}
}
},
"coffeescript": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/coffeescript/-/coffeescript-1.10.0.tgz",
@@ -5334,6 +5347,11 @@
"integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=",
"dev": true
},
"exit-on-epipe": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz",
"integrity": "sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw=="
},
"expand-brackets": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
@@ -6026,7 +6044,8 @@
"ansi-regex": {
"version": "2.1.1",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"aproba": {
"version": "1.2.0",
@@ -6047,12 +6066,14 @@
"balanced-match": {
"version": "1.0.0",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"brace-expansion": {
"version": "1.1.11",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@@ -6067,17 +6088,20 @@
"code-point-at": {
"version": "1.1.0",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"concat-map": {
"version": "0.0.1",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"console-control-strings": {
"version": "1.1.0",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"core-util-is": {
"version": "1.0.2",
@@ -6194,7 +6218,8 @@
"inherits": {
"version": "2.0.3",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"ini": {
"version": "1.3.5",
@@ -6206,6 +6231,7 @@
"version": "1.0.0",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"number-is-nan": "^1.0.0"
}
@@ -6220,6 +6246,7 @@
"version": "3.0.4",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"brace-expansion": "^1.1.7"
}
@@ -6227,12 +6254,14 @@
"minimist": {
"version": "0.0.8",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"minipass": {
"version": "2.3.5",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"safe-buffer": "^5.1.2",
"yallist": "^3.0.0"
@@ -6251,6 +6280,7 @@
"version": "0.5.1",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"minimist": "0.0.8"
}
@@ -6331,7 +6361,8 @@
"number-is-nan": {
"version": "1.0.1",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"object-assign": {
"version": "4.1.1",
@@ -6343,6 +6374,7 @@
"version": "1.4.0",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"wrappy": "1"
}
@@ -6428,7 +6460,8 @@
"safe-buffer": {
"version": "5.1.2",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"safer-buffer": {
"version": "2.1.2",
@@ -6464,6 +6497,7 @@
"version": "1.0.2",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
@@ -6483,6 +6517,7 @@
"version": "3.0.1",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"ansi-regex": "^2.0.0"
}
@@ -6526,12 +6561,14 @@
"wrappy": {
"version": "1.0.2",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"yallist": {
"version": "3.0.3",
"bundled": true,
"dev": true
"dev": true,
"optional": true
}
}
},
@@ -7565,9 +7602,9 @@
"dev": true
},
"https-proxy-agent": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.2.tgz",
"integrity": "sha512-c8Ndjc9Bkpfx/vCJueCPy0jlP4ccCCSNDp8xwCZzPjKJUm+B+u9WX2x98Qx4n1PiMNTWo3D7KK5ifNV/yJyRzg==",
"version": "2.2.4",
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz",
"integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==",
"dev": true,
"requires": {
"agent-base": "^4.3.0",
@@ -8575,9 +8612,9 @@
"integrity": "sha512-RqscTx95+RTKhFAyjedsboR0Lmo3zd8//EuRwQXkdWmsCwYlzarVRaiYg6kS1O8m10MCQkGdrnlK9L4eAmZUwA=="
},
"libyara-wasm": {
"version": "0.0.12",
"resolved": "https://registry.npmjs.org/libyara-wasm/-/libyara-wasm-0.0.12.tgz",
"integrity": "sha512-AjTe4FiBuH4F7HwGT/3UxoRenczXtrbM6oWGrifxb44LrkDh5VxRNg9zwfPpDA5Fcc1iYcXS0WVA/b3DGtD8cQ=="
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/libyara-wasm/-/libyara-wasm-1.0.1.tgz",
"integrity": "sha512-Vq0EcQ3HRJinFxxb00JZpjyX8NCerazVhSf3+TVt1c21T3pcEJJ3RkanAwT71lW6CCmmmKuNU4QwqsinmR6pKQ=="
},
"linkify-it": {
"version": "2.2.0",
+5 -4
View File
@@ -1,6 +1,6 @@
{
"name": "cyberchef",
"version": "9.7.10",
"version": "9.11.4",
"description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.",
"author": "n1474335 <n1474335@gmail.com>",
"homepage": "https://gchq.github.io/CyberChef",
@@ -43,7 +43,7 @@
"babel-eslint": "^10.0.3",
"babel-loader": "^8.0.6",
"babel-plugin-dynamic-import-node": "^2.3.0",
"chromedriver": "^76.0.1",
"chromedriver": "^77.0.0",
"colors": "^1.3.3",
"copy-webpack-plugin": "^5.0.4",
"css-loader": "^3.2.0",
@@ -86,6 +86,7 @@
"@babel/polyfill": "^7.4.4",
"@babel/runtime": "^7.5.5",
"arrive": "^2.4.1",
"avsc": "^5.4.16",
"babel-plugin-transform-builtin-extend": "1.1.2",
"bcryptjs": "^2.4.3",
"bignumber.js": "^9.0.0",
@@ -95,7 +96,7 @@
"bootstrap-material-design": "^4.1.2",
"bson": "^4.0.2",
"chi-squared": "^1.1.0",
"clippyjs": "0.0.3",
"codepage": "^1.14.0",
"core-js": "^3.2.1",
"crypto-api": "^0.8.5",
"crypto-js": "^3.1.9-1",
@@ -123,7 +124,7 @@
"jsrsasign": "8.0.12",
"kbpgp": "2.1.3",
"libbzip2-wasm": "0.0.4",
"libyara-wasm": "0.0.12",
"libyara-wasm": "^1.0.1",
"lodash": "^4.17.15",
"loglevel": "^1.6.3",
"loglevel-message-prefix": "^3.0.0",
+2 -2
View File
@@ -129,7 +129,7 @@ class Dish {
*
* @param {number} type - The data type of value, see Dish enums.
* @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) {
if (typeof type === "string") {
@@ -191,7 +191,7 @@ class Dish {
*
* @param {number} type - The data type of value, see Dish enums.
* @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) {
const clone = this.clone();
+7 -8
View File
@@ -201,9 +201,8 @@ class Utils {
* Utils.parseEscapedChars("\\n");
*/
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) {
if (a === "\\") return "\\"+b;
switch (b[0]) {
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) {
switch (a[0]) {
case "\\":
return "\\";
case "0":
@@ -214,7 +213,7 @@ class Utils {
case "5":
case "6":
case "7":
return String.fromCharCode(parseInt(b, 8));
return String.fromCharCode(parseInt(a, 8));
case "b":
return "\b";
case "t":
@@ -232,12 +231,12 @@ class Utils {
case "'":
return "'";
case "x":
return String.fromCharCode(parseInt(b.substr(1), 16));
return String.fromCharCode(parseInt(a.substr(1), 16));
case "u":
if (b[1] === "{")
return String.fromCodePoint(parseInt(b.slice(2, -1), 16));
if (a[1] === "{")
return String.fromCodePoint(parseInt(a.slice(2, -1), 16));
else
return String.fromCharCode(parseInt(b.substr(1), 16));
return String.fromCharCode(parseInt(a.substr(1), 16));
}
});
}
+8 -2
View File
@@ -59,7 +59,8 @@
"From Braille",
"Parse TLV",
"CSV to JSON",
"JSON to CSV"
"JSON to CSV",
"Avro to JSON"
]
},
{
@@ -108,7 +109,8 @@
"Enigma",
"Bombe",
"Multiple Bombe",
"Typex"
"Typex",
"Lorenz"
]
},
{
@@ -123,6 +125,7 @@
"Generate PGP Key Pair",
"PGP Encrypt",
"PGP Decrypt",
"PGP Verify",
"PGP Encrypt and Sign",
"PGP Decrypt and Verify",
"Parse SSH Host Key"
@@ -284,6 +287,7 @@
"Zip",
"Unzip",
"Bzip2 Decompress",
"Bzip2 Compress",
"Tar",
"Untar"
]
@@ -370,6 +374,7 @@
"Detect File Type",
"Scan for Embedded Files",
"Extract Files",
"YARA Rules",
"Remove EXIF",
"Extract EXIF",
"Extract RGBA",
@@ -401,6 +406,7 @@
"Cover Image",
"Image Hue/Saturation/Lightness",
"Sharpen Image",
"Normalise Image",
"Convert Image Format",
"Add Text To Image",
"Hex Density chart",
+1 -1
View File
@@ -22,7 +22,7 @@ export const ENCODING_SCHEME = [
/**
* 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
* when supporting multiple encoding schemes.
*
+436
View 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;
+120 -12
View File
@@ -12,16 +12,65 @@
export const IO_FORMAT = {
"UTF-8 (65001)": 65001,
"UTF-7 (65000)": 65000,
"UTF16LE (1200)": 1200,
"UTF16BE (1201)": 1201,
"UTF16 (1201)": 1201,
"UTF-16LE (1200)": 1200,
"UTF-16BE (1201)": 1201,
"UTF-32LE (12000)": 12000,
"UTF-32BE (12001)": 12001,
"IBM EBCDIC International (500)": 500,
"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,
"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-1251 Cyrillic (1251)": 1251,
"Windows-1252 Latin (1252)": 1252,
@@ -31,10 +80,6 @@ export const IO_FORMAT = {
"Windows-1256 Arabic (1256)": 1256,
"Windows-1257 Baltic (1257)": 1257,
"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-2 Latin 2 Central European (28592)": 28592,
"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-7 Latin/Greek (28597)": 28597,
"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-10 Latin 6 Nordic (28600)": 28600,
"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-15 Latin 9 (28605)": 28605,
"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 Simplified Chinese (51936)": 51936,
"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,
};
+1 -1
View File
@@ -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)"];
/**
* Armithmetic sequence delimiters
* Arithmetic sequence delimiters
*/
export const ARITHMETIC_DELIM_OPTIONS = ["Line feed", "Space", "Comma", "Semi-colon", "Colon", "CRLF"];
+330 -8
View File
@@ -40,7 +40,7 @@ export const FILE_SIGNATURES = {
4: [0x37, 0x39], // 7|9
5: 0x61 // a
},
extractor: null
extractor: extractGIF
},
{
name: "Portable Network Graphics image",
@@ -736,7 +736,7 @@ export const FILE_SIGNATURES = {
10: 0x56,
11: 0x45
},
extractor: null
extractor: extractWAV
},
{
name: "OGG audio",
@@ -1444,7 +1444,7 @@ export const FILE_SIGNATURES = {
1: 0x5a,
2: 0x68
},
extractor: null
extractor: extractBZIP2
},
{
name: "7zip",
@@ -1485,7 +1485,7 @@ export const FILE_SIGNATURES = {
4: 0x5a,
5: 0x0
},
extractor: null
extractor: extractXZ
},
{
name: "Tarball",
@@ -1870,7 +1870,7 @@ export const FILE_SIGNATURES = {
2: 0x4c,
3: 0x69
},
extractor: null
extractor: extractSQLITE
},
{
name: "BitTorrent link",
@@ -1993,7 +1993,7 @@ export const FILE_SIGNATURES = {
6: 0x4c,
7: 0x65
},
extractor: null
extractor: extractEVT
},
{
name: "Windows Event Log",
@@ -2009,7 +2009,7 @@ export const FILE_SIGNATURES = {
5: 0x6c,
6: 0x65
},
extractor: null
extractor: extractEVTX
},
{
name: "Windows Pagedump",
@@ -2331,6 +2331,133 @@ export const FILE_SIGNATURES = {
19: 0x46
},
extractor: null
},
{
name: "Bash",
extension: "bash",
mime: "application/bash",
description: "",
signature: {
0: 0x23, // #!/bin/bash
1: 0x21,
2: 0x2f,
3: 0x62,
4: 0x69,
5: 0x6e,
6: 0x2f,
7: 0x62,
8: 0x61,
9: 0x73,
10: 0x68,
},
extractor: null
},
{
name: "Shell",
extension: "sh",
mime: "application/sh",
description: "",
signature: {
0: 0x23, // #!/bin/sh
1: 0x21,
2: 0x2f,
3: 0x62,
4: 0x69,
5: 0x6e,
6: 0x2f,
7: 0x73,
8: 0x68,
},
extractor: null
},
{
name: "Python",
extension: "py,pyc,pyd,pyo,pyw,pyz",
mime: "application/python",
description: "",
signature: {
0: 0x23, // #!/usr/bin/python(2|3)
1: 0x21,
2: 0x2f,
3: 0x75,
4: 0x73,
5: 0x72,
6: 0x2f,
7: 0x62,
8: 0x69,
9: 0x6e,
10: 0x2f,
11: 0x70,
12: 0x79,
13: 0x74,
14: 0x68,
15: 0x6f,
16: 0x6e,
17: [0x32, 0x33, 0xa, 0xd],
},
extractor: null
},
{
name: "Ruby",
extension: "rb",
mime: "application/ruby",
description: "",
signature: {
0: 0x23, // #!/usr/bin/ruby
1: 0x21,
2: 0x2f,
3: 0x75,
4: 0x73,
5: 0x72,
6: 0x2f,
7: 0x62,
8: 0x69,
9: 0x6e,
10: 0x2f,
11: 0x72,
12: 0x75,
13: 0x62,
14: 0x79,
},
extractor: null
},
{
name: "perl",
extension: "pl,pm,t,pod",
mime: "application/perl",
description: "",
signature: {
0: 0x23, // #!/usr/bin/perl
1: 0x21,
2: 0x2f,
3: 0x75,
4: 0x73,
5: 0x72,
6: 0x2f,
7: 0x62,
8: 0x69,
9: 0x6e,
10: 0x2f,
11: 0x70,
12: 0x65,
13: 0x72,
14: 0x6c,
},
extractor: null
},
{
name: "php",
extension: "php,phtml,php3,php4,php5,php7,phps,php-s,pht,phar",
mime: "application/php",
description: "",
signature: {
0: 0x3c, // <?php
1: 0x3f,
2: 0x70,
3: 0x68,
4: 0x70,
},
extractor: null
}
]
};
@@ -2440,6 +2567,49 @@ export function extractJPEG(bytes, offset) {
}
/**
* GIF extractor.
*
* @param {Uint8Array} bytes
* @param {Number} offset
* @returns {Uint8Array}
*/
export function extractGIF(bytes, offset) {
const stream = new Stream(bytes.slice(offset));
// Move to application extension block.
stream.continueUntil([0x21, 0xff]);
// Move to Graphic Control Extension for frame #1.
stream.continueUntil([0x21, 0xf9]);
stream.moveForwardsBy(2);
while (stream.hasMore()) {
// Move to Image descriptor.
stream.moveForwardsBy(stream.readInt(1) + 1);
// Move past Image descriptor to the image data.
stream.moveForwardsBy(11);
// Loop until next Graphic Control Extension.
while (stream.getBytes(2) !== [0x21, 0xf9]) {
stream.moveBackwardsBy(2);
stream.moveForwardsBy(stream.readInt(1));
if (!stream.readInt(1))
break;
stream.moveBackwardsBy(1);
}
// When the end of the file is [0x00, 0x3b], end.
if (stream.readInt(1) === 0x3b)
break;
stream.moveForwardsBy(1);
}
return stream.carve();
}
/**
* Portable executable extractor.
* Assumes that the offset refers to an MZ header.
@@ -2463,7 +2633,7 @@ export function extractMZPE(bytes, offset) {
const numSections = stream.readInt(2, "le");
// Read Optional Header Magic to determine the state of the image file
// 0x10b = normal exeuctable, 0x107 = ROM image, 0x20b = PE32+ executable
// 0x10b = normal executable, 0x107 = ROM image, 0x20b = PE32+ executable
stream.moveForwardsBy(16);
const optionalMagic = stream.readInt(2, "le");
const pe32Plus = optionalMagic === 0x20b;
@@ -2602,6 +2772,26 @@ export function extractBMP(bytes, offset) {
}
/**
* WAV extractor.
*
* @param {Uint8Array} bytes
* @param {Number} offset
* @returns {Uint8Array}
*/
export function extractWAV(bytes, offset) {
const stream = new Stream(bytes.slice(offset));
// Move to file size field.
stream.moveTo(4);
// Move to file size.
stream.moveTo(stream.readInt(4, "le") - 4);
return stream.carve();
}
/**
* FLV extractor.
*
@@ -2689,6 +2879,31 @@ export function extractRTF(bytes, offset) {
}
/**
* SQLITE extractor.
*
* @param {Uint8Array} bytes
* @param {number} offset
* @returns {Uint8Array}
*/
export function extractSQLITE(bytes, offset) {
const stream = new Stream(bytes.slice(offset));
// Extract the size of the page.
stream.moveTo(16);
const pageSize = stream.readInt(2);
// Extract the number of pages.
stream.moveTo(28);
const numPages = stream.readInt(4);
// Move to the end of all the pages.
stream.moveTo(pageSize*numPages);
return stream.carve();
}
/**
* PList (XML) extractor.
*
@@ -2777,6 +2992,43 @@ export function extractGZIP(bytes, offset) {
}
/**
* BZIP2 extractor.
*
* @param {Uint8Array} bytes
* @param {Number} offset
* @returns {Uint8Array}
*/
export function extractBZIP2(bytes, offset) {
const stream = new Stream(bytes.slice(offset));
// The EOFs shifted between all possible combinations.
const lookingfor = [
[0x77, 0x24, 0x53, 0x85, 0x09],
[0xee, 0x48, 0xa7, 0x0a, 0x12],
[0xdc, 0x91, 0x4e, 0x14, 0x24],
[0xb9, 0x22, 0x9c, 0x28, 0x48],
[0x72, 0x45, 0x38, 0x50, 0x90],
[0xbb, 0x92, 0x29, 0xc2, 0x84],
[0x5d, 0xc9, 0x14, 0xe1, 0x42],
[0x2e, 0xe4, 0x8a, 0x70, 0xa1],
[0x17, 0x72, 0x45, 0x38, 0x50]
];
for (let i = 0; i < lookingfor.length; i++) {
// Continue until an EOF.
stream.continueUntil(lookingfor[i]);
if (stream.getBytes(5).join("") === lookingfor[i].join(""))
break;
// Jump back to the start if invalid EOF.
stream.moveTo(0);
}
stream.moveForwardsBy(4);
return stream.carve();
}
/**
* Zlib extractor.
*
@@ -2808,6 +3060,26 @@ export function extractZlib(bytes, offset) {
}
/**
* XZ extractor.
*
* @param {Uint8Array} bytes
* @param {Number} offset
* @returns {string}
*/
export function extractXZ(bytes, offset) {
const stream = new Stream(bytes.slice(offset));
// Move forward to EOF marker
stream.continueUntil([0x00, 0x00, 0x00, 0x00, 0x04, 0x59, 0x5a]);
// Move over EOF marker
stream.moveForwardsBy(7);
return stream.carve();
}
/**
* ELF extractor.
*
@@ -3059,3 +3331,53 @@ function readHuffmanCode(stream, table) {
return codeWithLength & 0xffff;
}
/**
* EVTX extractor.
*
* @param {Uint8Array} bytes
* @param {Number} offset
* @returns {Uint8Array}
*/
export function extractEVTX(bytes, offset) {
const stream = new Stream(bytes.slice(offset));
// Move to first ELFCHNK.
stream.moveTo(0x28);
const total = stream.readInt(4, "le") - 0x2c;
stream.moveForwardsBy(total);
while (stream.hasMore()) {
// Loop through ELFCHNKs.
if (stream.getBytes(7).join("") !== [0x45, 0x6c, 0x66, 0x43, 0x68, 0x6e, 0x6b].join(""))
break;
stream.moveForwardsBy(0xfff9);
}
stream.consumeWhile(0x00);
return stream.carve();
}
/**
* EVT extractor.
*
* @param {Uint8Array} bytes
* @param {Number} offset
* @returns {Uint8Array}
*/
export function extractEVT(bytes, offset) {
const stream = new Stream(bytes.slice(offset));
// Extract offset of EOF.
stream.moveTo(0x14);
const eofOffset = stream.readInt(4, "le");
stream.moveTo(eofOffset);
// Extract the size of the EOF.
const eofSize = stream.readInt(4, "le");
// Move past EOF.
stream.moveForwardsBy(eofSize-4);
return stream.carve();
}
+1 -1
View File
@@ -178,7 +178,7 @@ export function scanForFileTypes(buf, categories=Object.keys(FILE_SIGNATURES)) {
* @param {Uint8Array} buf - The buffer to search
* @param {Object} sig - A single signature object (Not an array of signatures)
* @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) {
// Find values for first key and value in sig
+7 -7
View File
@@ -355,17 +355,17 @@ class Magic {
let aScore = a.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 (a.isUTF8) aScore -= 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 (a.useful) aScore = 100;
if (b.useful) bScore = 100;
if (a.useful && aScore > 100) aScore = 100;
if (b.useful && bScore > 100) bScore = 100;
// Shorter recipes are better, so we add the length of the recipe to the score
aScore += a.recipe.length;
@@ -498,7 +498,7 @@ class Magic {
* Taken from http://wikistats.wmflabs.org/display.php?t=wp
*
* @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) {
return {
+1 -1
View File
@@ -37,7 +37,7 @@ export async function parseQrCode(input, normalise) {
image = await jimp.read(image);
}
} 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());
+57 -7
View File
@@ -155,19 +155,69 @@ export default class Stream {
}
// val is an array
let found = false;
while (!found && this.position < this.length) {
while (++this.position < this.length && this.bytes[this.position] !== val[0]) {
continue;
}
/**
* Builds the skip forward table from the value to be searched.
*
* @param {Uint8Array} val
* @param {Number} len
* @returns {Uint8Array}
*/
function preprocess(val, len) {
const skiptable = new Array();
val.forEach((element, index) => {
skiptable[element] = len - index;
});
return skiptable;
}
const length = val.length;
const initial = val[length-1];
this.position = length;
// Get the skip table.
const skiptable = preprocess(val, length);
let found = true;
while (this.position < this.length) {
// Until we hit the final element of val in the stream.
while ((this.position < this.length) && (this.bytes[this.position++] !== initial));
found = true;
for (let i = 1; i < val.length; i++) {
if (this.position + i > this.length || this.bytes[this.position + i] !== val[i])
// Loop through the elements comparing them to val.
for (let x = length-1; x >= 0; x--) {
if (this.bytes[this.position - length + x] !== val[x]) {
found = false;
// If element is not equal to val's element then jump forward by the correct amount.
this.position += skiptable[val[x]];
break;
}
}
if (found) {
this.position -= length;
break;
}
}
}
/**
* Consume bytes if they match the supplied value.
*
* @param {Number} val
*/
consumeWhile(val) {
while (this.position < this.length) {
if (this.bytes[this.position] !== val) {
break;
}
this.position++;
}
this.bitPos = 0;
}
/**
* Consume the next byte if it matches the supplied value.
*
+76
View 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;
+1 -1
View File
@@ -50,7 +50,7 @@ class BLAKE2b extends Operation {
/**
* @param {ArrayBuffer} input
* @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) {
const [outSize, outFormat] = args;
+1 -1
View File
@@ -51,7 +51,7 @@ class BLAKE2s extends Operation {
/**
* @param {ArrayBuffer} input
* @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) {
const [outSize, outFormat] = args;
+1 -1
View File
@@ -20,7 +20,7 @@ class BSONDeserialise extends Operation {
super();
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.infoURL = "https://wikipedia.org/wiki/BSON";
this.inputType = "ArrayBuffer";
+1 -1
View File
@@ -20,7 +20,7 @@ class BSONSerialise extends Operation {
super();
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.infoURL = "https://wikipedia.org/wiki/BSON";
this.inputType = "string";
+2 -2
View File
@@ -4,12 +4,12 @@
* @license Apache-2.0
*/
import Operation from "../Operation";
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";
} from "../lib/Bacon.mjs";
/**
* Bacon Cipher Decode operation
+2 -2
View File
@@ -4,12 +4,12 @@
* @license Apache-2.0
*/
import Operation from "../Operation";
import Operation from "../Operation.mjs";
import {
BACON_ALPHABETS,
BACON_TRANSLATIONS_FOR_ENCODING, BACON_TRANSLATION_AB,
swapZeroAndOne
} from "../lib/Bacon";
} from "../lib/Bacon.mjs";
/**
* Bacon Cipher Encode operation
+22 -28
View File
@@ -6,23 +6,9 @@
import Operation from "../Operation.mjs";
import Utils from "../Utils.mjs";
import forge from "node-forge/dist/forge.min.js";
import OperationError from "../errors/OperationError.mjs";
import { Blowfish } from "../vendor/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
};
import { Blowfish } from "../lib/Blowfish.mjs";
/**
* Blowfish Decrypt operation
@@ -57,12 +43,12 @@ class BlowfishDecrypt extends Operation {
{
"name": "Mode",
"type": "option",
"value": ["CBC", "PCBC", "CFB", "OFB", "CTR", "ECB"]
"value": ["CBC", "CFB", "OFB", "CTR", "ECB"]
},
{
"name": "Input",
"type": "option",
"value": ["Hex", "Base64", "Raw"]
"value": ["Hex", "Raw"]
},
{
"name": "Output",
@@ -79,21 +65,29 @@ class BlowfishDecrypt extends Operation {
*/
run(input, args) {
const key = Utils.convertToByteString(args[0].string, args[0].option),
iv = Utils.convertToByteArray(args[1].string, args[1].option),
[,, mode, inputType, outputType] = args;
iv = Utils.convertToByteString(args[1].string, args[1].option),
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, {
outputType: BLOWFISH_OUTPUT_TYPE_LOOKUP[inputType], // This actually means inputType. The library is weird.
cipherMode: BLOWFISH_MODE_LOOKUP[mode]
});
const decipher = Blowfish.createDecipher(key, mode);
decipher.start({iv: iv});
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.");
}
}
}
+22 -29
View File
@@ -6,24 +6,9 @@
import Operation from "../Operation.mjs";
import Utils from "../Utils.mjs";
import forge from "node-forge/dist/forge.min.js";
import OperationError from "../errors/OperationError.mjs";
import { Blowfish } from "../vendor/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
};
import { Blowfish } from "../lib/Blowfish.mjs";
/**
* Blowfish Encrypt operation
@@ -58,7 +43,7 @@ class BlowfishEncrypt extends Operation {
{
"name": "Mode",
"type": "option",
"value": ["CBC", "PCBC", "CFB", "OFB", "CTR", "ECB"]
"value": ["CBC", "CFB", "OFB", "CTR", "ECB"]
},
{
"name": "Input",
@@ -68,7 +53,7 @@ class BlowfishEncrypt extends Operation {
{
"name": "Output",
"type": "option",
"value": ["Hex", "Base64", "Raw"]
"value": ["Hex", "Raw"]
}
];
}
@@ -80,21 +65,29 @@ class BlowfishEncrypt extends Operation {
*/
run(input, args) {
const key = Utils.convertToByteString(args[0].string, args[0].option),
iv = Utils.convertToByteArray(args[1].string, args[1].option),
[,, mode, inputType, outputType] = args;
iv = Utils.convertToByteString(args[1].string, args[1].option),
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);
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, {
outputType: BLOWFISH_OUTPUT_TYPE_LOOKUP[outputType],
cipherMode: BLOWFISH_MODE_LOOKUP[mode]
});
return outputType === "Raw" ? Utils.byteArrayToChars(enc) : enc;
if (outputType === "Hex") {
return cipher.output.toHex();
} else {
return cipher.output.getBytes();
}
}
}
+1 -1
View File
@@ -23,7 +23,7 @@ class Bombe extends Operation {
super();
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&lt;-&gt;C, B&lt;-&gt;A, and C&lt;-&gt;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.inputType = "string";
+1 -1
View File
@@ -6,7 +6,7 @@
import Operation from "../Operation.mjs";
import OperationError from "../errors/OperationError.mjs";
import cptable from "../vendor/js-codepage/cptable.js";
import cptable from "codepage";
/**
* Citrix CTX1 Decode operation
+1 -1
View File
@@ -5,7 +5,7 @@
*/
import Operation from "../Operation.mjs";
import cptable from "../vendor/js-codepage/cptable.js";
import cptable from "codepage";
/**
* Citrix CTX1 Encode operation
+6
View File
@@ -73,6 +73,12 @@ class DESDecrypt extends Operation {
DES uses a key length of 8 bytes (64 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);
+6
View File
@@ -73,6 +73,12 @@ class DESEncrypt extends Operation {
DES uses a key length of 8 bytes (64 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);
+1 -1
View File
@@ -5,7 +5,7 @@
*/
import Operation from "../Operation.mjs";
import cptable from "../vendor/js-codepage/cptable.js";
import cptable from "codepage";
import {IO_FORMAT} from "../lib/ChrEnc.mjs";
/**
+1 -1
View File
@@ -4,7 +4,7 @@
* @license Apache-2.0
*/
import Operation from "../Operation";
import Operation from "../Operation.mjs";
/**
+7 -1
View File
@@ -47,6 +47,11 @@ class Diff extends Operation {
"type": "boolean",
"value": true
},
{
"name": "Show subtraction",
"type": "boolean",
"value": false
},
{
"name": "Ignore whitespace",
"type": "boolean",
@@ -67,6 +72,7 @@ class Diff extends Operation {
diffBy,
showAdded,
showRemoved,
showSubtraction,
ignoreWhitespace
] = args,
samples = input.split(sampleDelim);
@@ -116,7 +122,7 @@ class Diff extends Operation {
if (showAdded) output += "<span class='hl5'>" + Utils.escapeHtml(diff[i].value) + "</span>";
} else if (diff[i].removed) {
if (showRemoved) output += "<span class='hl3'>" + Utils.escapeHtml(diff[i].value) + "</span>";
} else {
} else if (!showSubtraction) {
output += Utils.escapeHtml(diff[i].value);
}
}
+1 -1
View File
@@ -5,7 +5,7 @@
*/
import Operation from "../Operation.mjs";
import cptable from "../vendor/js-codepage/cptable.js";
import cptable from "codepage";
import {IO_FORMAT} from "../lib/ChrEnc.mjs";
/**
+1 -1
View File
@@ -21,7 +21,7 @@ class Enigma extends Operation {
super();
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>&lt;</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.inputType = "string";
+4 -4
View File
@@ -76,8 +76,8 @@ class Fork extends Operation {
}
const recipe = new Recipe();
let output = "",
progress = 0;
const outputs = [];
let progress = 0;
state.forkOffset += state.progress + 1;
@@ -104,10 +104,10 @@ class Fork extends Operation {
}
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;
return state;
}
+12 -5
View File
@@ -42,15 +42,22 @@ class FromBase62 extends Operation {
*/
run(input, args) {
if (input.length < 1) return [];
const ALPHABET = Utils.expandAlphRange(args[0]).join("");
const BN = BigNumber.clone({ ALPHABET });
const alphabet = Utils.expandAlphRange(args[0]).join("");
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, "");
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");
}
}
+1 -1
View File
@@ -57,7 +57,7 @@ class HammingDistance extends Operation {
samples = input.split(delim);
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) {
+759
View 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;
+1 -1
View File
@@ -54,7 +54,7 @@ class MultipleBombe extends Operation {
super();
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.infoURL = "https://wikipedia.org/wiki/Bombe";
this.inputType = "string";
+1 -2
View File
@@ -128,8 +128,7 @@ class PHPDeserialize extends Operation {
switch (kind) {
case "n":
expect(";");
return "";
return "null";
case "i":
case "d":
case "b": {
+5 -5
View File
@@ -4,11 +4,11 @@
* @license Apache-2.0
*/
import Operation from "../Operation";
import OperationError from "../errors/OperationError";
import Utils from "../Utils";
import { fromBase64 } from "../lib/Base64";
import { fromHex, toHexFast } from "../lib/Hex";
import Operation from "../Operation.mjs";
import OperationError from "../errors/OperationError.mjs";
import Utils from "../Utils.mjs";
import { fromBase64 } from "../lib/Base64.mjs";
import { fromHex, toHexFast } from "../lib/Hex.mjs";
/**
* Parse SSH Host Key operation
+1 -1
View File
@@ -77,7 +77,7 @@ class RawInflate extends Operation {
}),
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]
// Look for the first two square brackets:
+2 -2
View File
@@ -64,7 +64,7 @@ class RemoveWhitespace extends Operation {
run(input, args) {
const [
removeSpaces,
removeCariageReturns,
removeCarriageReturns,
removeLineFeeds,
removeTabs,
removeFormFeeds,
@@ -73,7 +73,7 @@ class RemoveWhitespace extends Operation {
let data = input;
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 (removeTabs) data = data.replace(/\t/g, "");
if (removeFormFeeds) data = data.replace(/\f/g, "");
@@ -7,7 +7,7 @@
import Operation from "../Operation.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";
/**
+6 -3
View File
@@ -44,12 +44,15 @@ class ToBase62 extends Operation {
input = new Uint8Array(input);
if (input.length < 1) return "";
const ALPHABET = Utils.expandAlphRange(args[0]).join("");
const BN = BigNumber.clone({ ALPHABET });
const alphabet = Utils.expandAlphRange(args[0]).join("");
const BN62 = BigNumber.clone({ ALPHABET: alphabet });
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);
}
+1 -1
View File
@@ -108,7 +108,7 @@ class ToQuotedPrintable extends Operation {
* @private
* @param {number} nr
* @param {byteArray[]} ranges
* @returns {bolean}
* @returns {boolean}
*/
_checkRanges(nr, ranges) {
for (let i = ranges.length - 1; i >= 0; i--) {
+6
View File
@@ -75,6 +75,12 @@ class TripleDESDecrypt extends Operation {
Triple DES uses a key length of 24 bytes (192 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);
+6
View File
@@ -75,6 +75,12 @@ class TripleDESEncrypt extends Operation {
Triple DES uses a key length of 24 bytes (192 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);
+2 -2
View File
@@ -22,8 +22,8 @@ class Typex extends Operation {
super();
this.name = "Typex";
this.module = "Default";
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>&lt;</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.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 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>&lt;</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.inputType = "string";
this.outputType = "string";
@@ -56,7 +56,7 @@ class UNIXTimestampToWindowsFiletime extends Operation {
} else if (units === "Milliseconds (ms)") {
input = input.multipliedBy(new BigNumber("10000"));
} else if (units === "Microseconds (μs)") {
input = input.multiplyiedBy(new BigNumber("10"));
input = input.multipliedBy(new BigNumber("10"));
} else if (units === "Nanoseconds (ns)") {
input = input.dividedBy(new BigNumber("100"));
} else {
+1 -1
View File
@@ -49,7 +49,7 @@ class URLEncode extends Operation {
* @returns {string}
*/
encodeAllChars (str) {
// TODO Do this programatically
// TODO Do this programmatically
return encodeURIComponent(str)
.replace(/!/g, "%21")
.replace(/#/g, "%23")
+1 -1
View File
@@ -55,7 +55,7 @@ class VigenèreDecode extends Operation {
keyIndex = alphabet.indexOf(chr);
msgIndex = alphabet.indexOf(input[i]);
// 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];
} else if (alphabet.indexOf(input[i].toLowerCase()) >= 0) {
chr = key[(i - fail) % key.length].toLowerCase();
+1 -1
View File
@@ -20,7 +20,7 @@ class Whirlpool extends Operation {
this.name = "Whirlpool";
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.inputType = "ArrayBuffer";
this.outputType = "string";
+1 -1
View File
@@ -61,7 +61,7 @@ class YARARules extends Operation {
* @param {Object[]} args
* @returns {string}
*/
run(input, args) {
async run(input, args) {
if (isWorkerEnvironment())
self.sendStatusMessage("Instantiating YARA...");
const [rules, showStrings, showLengths, showMeta, showCounts] = args;
-652
View File
@@ -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;
File diff suppressed because it is too large. Load diff
-515
View File
@@ -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;
}));
+3 -3
View File
@@ -12,7 +12,7 @@ import NodeDish from "./NodeDish.mjs";
import NodeRecipe from "./NodeRecipe.mjs";
import OperationConfig from "../core/config/OperationConfig.json";
import { sanitise, removeSubheadingsFromArray, sentenceToCamelCase } from "./apiUtils.mjs";
import ExludedOperationError from "../core/errors/ExcludedOperationError.mjs";
import ExcludedOperationError from "../core/errors/ExcludedOperationError.mjs";
/**
@@ -320,12 +320,12 @@ export function bake() {
* Explain that the given operation is not included in the Node.js version.
* @param {String} name - name of operation
*/
export function _explainExludedFunction(name) {
export function _explainExcludedFunction(name) {
/**
* Throw new error type with useful message.
*/
const func = () => {
throw new ExludedOperationError(`Sorry, the ${name} operation is not available in the Node.js version of CyberChef.`);
throw new ExcludedOperationError(`Sorry, the ${name} operation is not available in the Node.js version of CyberChef.`);
};
// Add opName prop so NodeRecipe can handle it, just like wrap does.
func.opName = name;
+1 -1
View File
@@ -71,7 +71,7 @@ export function sanitise(str) {
/**
* sonething like this => somethingLikeThis
* something like this => somethingLikeThis
* ABC a sentence => ABCASentence
*/
export function sentenceToCamelCase(str) {
+1 -1
View File
@@ -1,5 +1,5 @@
/**
* Operations to exlude from the Node API
* Operations to exclude from the Node API
*
* @author d98762656 [d98762625@gmail.com]
* @copyright Crown Copyright 2018
@@ -39,7 +39,7 @@ let code = `/**
import NodeDish from "./NodeDish.mjs";
import { _wrap, help, bake, _explainExludedFunction } from "./api.mjs";
import { _wrap, help, bake, _explainExcludedFunction } from "./api.mjs";
import File from "./File.mjs";
import { OperationError, DishError, ExcludedOperationError } from "../core/errors/index";
import {
@@ -70,7 +70,7 @@ includedOperations.forEach((op) => {
});
excludedOperations.forEach((op) => {
code += ` "${decapitalise(op)}": _explainExludedFunction("${op}"),\n`;
code += ` "${decapitalise(op)}": _explainExcludedFunction("${op}"),\n`;
});
code += ` };
+6
View File
@@ -453,6 +453,7 @@ class App {
* Searches the URI parameters for recipe and input parameters.
* If recipe is present, replaces the current recipe with the recipe provided in the URI.
* If input is present, decodes and sets the input to the one provided in the URI.
* If theme is present, uses the theme.
*
* @fires Manager#statechange
*/
@@ -491,6 +492,11 @@ class App {
} catch (err) {}
}
// Read in theme from URI params
if (this.uriParams.theme) {
this.manager.options.changeTheme(Utils.escapeHtml(this.uriParams.theme));
}
this.autoBakePause = false;
window.dispatchEvent(this.manager.statechange);
}
+45 -23
View File
@@ -31,7 +31,9 @@ class HTMLIngredient {
this.target = config.target;
this.defaultIndex = config.defaultIndex || 0;
this.toggleValues = config.toggleValues;
this.id = "ing-" + this.app.nextIngId();
this.ingId = this.app.nextIngId();
this.id = "ing-" + this.ingId;
this.tabIndex = this.ingId + 2; // Input = 1, Search = 2
this.min = (typeof config.min === "number") ? config.min : "";
this.max = (typeof config.max === "number") ? config.max : "";
this.step = config.step || 1;
@@ -52,40 +54,46 @@ class HTMLIngredient {
case "binaryString":
case "byteArray":
html += `<div class="form-group">
<label for="${this.id}" class="bmd-label-floating">${this.name}</label>
<label for="${this.id}"
${this.hint ? `data-toggle="tooltip" title="${this.hint}"` : ""}
class="bmd-label-floating">${this.name}</label>
<input type="text"
class="form-control arg"
id="${this.id}"
tabindex="${this.tabIndex}"
arg-name="${this.name}"
value="${this.value}"
${this.disabled ? "disabled" : ""}>
${this.hint ? "<span class='bmd-help'>" + this.hint + "</span>" : ""}
</div>`;
break;
case "shortString":
case "binaryShortString":
html += `<div class="form-group inline">
<label for="${this.id}" class="bmd-label-floating inline">${this.name}</label>
<label for="${this.id}"
${this.hint ? `data-toggle="tooltip" title="${this.hint}"` : ""}
class="bmd-label-floating inline">${this.name}</label>
<input type="text"
class="form-control arg inline"
id="${this.id}"
tabindex="${this.tabIndex}"
arg-name="${this.name}"
value="${this.value}"
${this.disabled ? "disabled" : ""}>
${this.hint ? "<span class='bmd-help'>" + this.hint + "</span>" : ""}
</div>`;
break;
case "toggleString":
html += `<div class="form-group input-group">
<div class="toggle-string">
<label for="${this.id}" class="bmd-label-floating toggle-string">${this.name}</label>
<label for="${this.id}"
${this.hint ? `data-toggle="tooltip" title="${this.hint}"` : ""}
class="bmd-label-floating toggle-string">${this.name}</label>
<input type="text"
class="form-control arg toggle-string"
id="${this.id}"
tabindex="${this.tabIndex}"
arg-name="${this.name}"
value="${this.value}"
${this.disabled ? "disabled" : ""}>
${this.hint ? "<span class='bmd-help'>" + this.hint + "</span>" : ""}
</div>
<div class="input-group-append">
<button class="btn btn-secondary dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">${this.toggleValues[0]}</button>
@@ -100,41 +108,46 @@ class HTMLIngredient {
break;
case "number":
html += `<div class="form-group inline">
<label for="${this.id}" class="bmd-label-floating inline">${this.name}</label>
<label for="${this.id}"
${this.hint ? `data-toggle="tooltip" title="${this.hint}"` : ""}
class="bmd-label-floating inline">${this.name}</label>
<input type="number"
class="form-control arg inline"
id="${this.id}"
tabindex="${this.tabIndex}"
arg-name="${this.name}"
value="${this.value}"
min="${this.min}"
max="${this.max}"
step="${this.step}"
${this.disabled ? "disabled" : ""}>
${this.hint ? "<span class='bmd-help'>" + this.hint + "</span>" : ""}
</div>`;
break;
case "boolean":
html += `<div class="form-group inline boolean-arg">
<div class="checkbox">
<label>
<label ${this.hint ? `data-toggle="tooltip" title="${this.hint}"` : ""}>
<input type="checkbox"
class="arg"
id="${this.id}"
tabindex="${this.tabIndex}"
arg-name="${this.name}"
${this.value ? " checked" : ""}
${this.disabled ? " disabled" : ""}
value="${this.name}"> ${this.name}
</label>
${this.hint ? "<span class='bmd-help'>" + this.hint + "</span>" : ""}
</div>
</div>`;
break;
case "option":
html += `<div class="form-group inline">
<label for="${this.id}" class="bmd-label-floating inline">${this.name}</label>
<label for="${this.id}"
${this.hint ? `data-toggle="tooltip" title="${this.hint}"` : ""}
class="bmd-label-floating inline">${this.name}</label>
<select
class="form-control arg inline"
id="${this.id}"
tabindex="${this.tabIndex}"
arg-name="${this.name}"
${this.disabled ? "disabled" : ""}>`;
for (i = 0; i < this.value.length; i++) {
@@ -147,16 +160,18 @@ class HTMLIngredient {
}
}
html += `</select>
${this.hint ? "<span class='bmd-help'>" + this.hint + "</span>" : ""}
</div>`;
break;
case "populateOption":
case "populateMultiOption":
html += `<div class="form-group">
<label for="${this.id}" class="bmd-label-floating">${this.name}</label>
<label for="${this.id}"
${this.hint ? `data-toggle="tooltip" title="${this.hint}"` : ""}
class="bmd-label-floating">${this.name}</label>
<select
class="form-control arg no-state-change populate-option"
id="${this.id}"
tabindex="${this.tabIndex}"
arg-name="${this.name}"
${this.disabled ? "disabled" : ""}>`;
for (i = 0; i < this.value.length; i++) {
@@ -172,7 +187,6 @@ class HTMLIngredient {
}
}
html += `</select>
${this.hint ? "<span class='bmd-help'>" + this.hint + "</span>" : ""}
</div>`;
eventFn = this.type === "populateMultiOption" ?
@@ -182,14 +196,16 @@ class HTMLIngredient {
break;
case "editableOption":
html += `<div class="form-group input-group">
<label for="${this.id}" class="bmd-label-floating">${this.name}</label>
<label for="${this.id}"
${this.hint ? `data-toggle="tooltip" title="${this.hint}"` : ""}
class="bmd-label-floating">${this.name}</label>
<input type="text"
class="form-control arg"
id="${this.id}"
tabindex="${this.tabIndex}"
arg-name="${this.name}"
value="${this.value[this.defaultIndex].value}"
${this.disabled ? "disabled" : ""}>
${this.hint ? "<span class='bmd-help'>" + this.hint + "</span>" : ""}
<div class="input-group-append">
<button type="button"
class="btn btn-secondary dropdown-toggle dropdown-toggle-split"
@@ -211,14 +227,16 @@ class HTMLIngredient {
break;
case "editableOptionShort":
html += `<div class="form-group input-group inline">
<label for="${this.id}" class="bmd-label-floating inline">${this.name}</label>
<label for="${this.id}"
${this.hint ? `data-toggle="tooltip" title="${this.hint}"` : ""}
class="bmd-label-floating inline">${this.name}</label>
<input type="text"
class="form-control arg inline"
id="${this.id}"
tabindex="${this.tabIndex}"
arg-name="${this.name}"
value="${this.value[this.defaultIndex].value}"
${this.disabled ? "disabled" : ""}>
${this.hint ? "<span class='bmd-help'>" + this.hint + "</span>" : ""}
<div class="input-group-append inline">
<button type="button"
class="btn btn-secondary dropdown-toggle dropdown-toggle-split"
@@ -240,22 +258,27 @@ class HTMLIngredient {
break;
case "text":
html += `<div class="form-group">
<label for="${this.id}" class="bmd-label-floating">${this.name}</label>
<label for="${this.id}"
${this.hint ? `data-toggle="tooltip" title="${this.hint}"` : ""}
class="bmd-label-floating">${this.name}</label>
<textarea
class="form-control arg"
id="${this.id}"
tabindex="${this.tabIndex}"
arg-name="${this.name}"
rows="${this.rows ? this.rows : 3}"
${this.disabled ? "disabled" : ""}>${this.value}</textarea>
${this.hint ? "<span class='bmd-help'>" + this.hint + "</span>" : ""}
</div>`;
break;
case "argSelector":
html += `<div class="form-group inline">
<label for="${this.id}" class="bmd-label-floating inline">${this.name}</label>
<label for="${this.id}"
${this.hint ? `data-toggle="tooltip" title="${this.hint}"` : ""}
class="bmd-label-floating inline">${this.name}</label>
<select
class="form-control arg inline arg-selector"
id="${this.id}"
tabindex="${this.tabIndex}"
arg-name="${this.name}"
${this.disabled ? "disabled" : ""}>`;
for (i = 0; i < this.value.length; i++) {
@@ -266,7 +289,6 @@ class HTMLIngredient {
</option>`;
}
html += `</select>
${this.hint ? "<span class='bmd-help'>" + this.hint + "</span>" : ""}
</div>`;
this.manager.addDynamicListener(".arg-selector", "change", this.argSelectorChange, this);
+2 -2
View File
@@ -168,7 +168,7 @@
<div id="workspace-wrapper">
<div id="operations" class="split split-horizontal no-select">
<div class="title no-select">Operations</div>
<input id="search" type="search" class="form-control" placeholder="Search..." autocomplete="off">
<input id="search" type="search" class="form-control" placeholder="Search..." autocomplete="off" tabindex="2">
<ul id="search-results" class="op-list"></ul>
<div id="categories" class="panel-group no-select"></div>
</div>
@@ -266,7 +266,7 @@
</div>
<div class="textarea-wrapper no-select input-wrapper" id="input-wrapper">
<div id="input-highlighter" class="no-select"></div>
<textarea id="input-text" class="input-text" spellcheck="false"></textarea>
<textarea id="input-text" class="input-text" spellcheck="false" tabindex="1" autofocus></textarea>
<div class="input-file" id="input-file">
<div class="file-overlay" id="file-overlay"></div>
<div style="position: relative; height: 100%;">
@@ -1 +0,0 @@
clippy.ready('Clippy', {"overlayCount": 1, "sounds": ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15"], "framesize": [124, 93], "animations": {"Congratulate": {"frames": [{"duration": 100, "images": [[0, 0]], "sound": "15"}, {"duration": 10, "images": [[124, 0]]}, {"duration": 10, "images": [[248, 0]]}, {"duration": 10, "images": [[372, 0]], "sound": "14"}, {"duration": 10, "images": [[496, 0]]}, {"duration": 10, "images": [[620, 0]]}, {"duration": 10, "images": [[744, 0]]}, {"duration": 10, "images": [[868, 0]]}, {"duration": 10, "images": [[992, 0]], "sound": "1"}, {"duration": 100, "images": [[1116, 0]]}, {"duration": 100, "images": [[1240, 0]]}, {"duration": 100, "images": [[1364, 0]]}, {"duration": 1200, "images": [[1488, 0]]}, {"duration": 100, "images": [[1612, 0]], "sound": "10"}, {"duration": 100, "images": [[1736, 0]]}, {"duration": 1200, "images": [[1488, 0]]}, {"duration": 100, "images": [[1860, 0]]}, {"duration": 100, "images": [[1984, 0]]}, {"duration": 100, "images": [[2108, 0]]}, {"duration": 100, "images": [[2232, 0]]}, {"duration": 100, "images": [[2356, 0]], "exitBranch": 21}, {"duration": 100, "images": [[0, 0]]}]}, "LookRight": {"frames": [{"duration": 100, "images": [[0, 0]], "exitBranch": 6}, {"duration": 100, "images": [[620, 651]], "exitBranch": 5}, {"duration": 100, "images": [[744, 651]], "exitBranch": 4}, {"duration": 1200, "images": [[868, 651]]}, {"duration": 100, "images": [[992, 651]]}, {"duration": 100, "images": [[1116, 651]]}, {"duration": 100, "images": [[0, 0]]}]}, "SendMail": {"frames": [{"duration": 100, "images": [[0, 0]], "sound": "15"}, {"duration": 100, "images": [[1240, 1209]]}, {"duration": 100, "images": [[1364, 1209]]}, {"duration": 100, "images": [[1488, 1209]]}, {"duration": 100, "images": [[1612, 1209]]}, {"duration": 100, "images": [[1736, 1209]]}, {"duration": 100, "images": [[1860, 1209]]}, {"duration": 100, "images": [[1984, 1209]]}, {"duration": 100, "images": [[2108, 1209]]}, {"duration": 100, "images": [[2232, 1209]]}, {"duration": 100, "images": [[2356, 1209]]}, {"duration": 100, "images": [[2480, 1209]]}, {"duration": 100, "images": [[2604, 1209]]}, {"duration": 100, "images": [[2728, 1209]]}, {"duration": 100, "images": [[2852, 1209]]}, {"duration": 100, "images": [[2976, 1209]]}, {"duration": 100, "images": [[3100, 1209]]}, {"duration": 100, "images": [[3224, 1209]]}, {"duration": 100, "images": [[0, 1302]]}, {"duration": 100, "images": [[124, 1302]]}, {"duration": 100, "images": [[248, 1302]]}, {"duration": 100, "images": [[372, 1302]], "sound": "14"}, {"duration": 100, "images": [[496, 1302]], "exitBranch": 24}, {"duration": 100, "images": [[620, 1302]]}, {"duration": 100, "images": [[744, 1302]], "exitBranch": 26}, {"duration": 100, "images": [[868, 1302]]}, {"duration": 100, "images": [[992, 1302]], "exitBranch": 27}, {"duration": 100, "images": [[1116, 1302]], "exitBranch": 28}, {"duration": 100, "images": [[1240, 1302]], "exitBranch": 29}, {"duration": 100, "images": [[1364, 1302]], "exitBranch": 30}, {"duration": 100, "images": [[1488, 1302]], "exitBranch": 31}, {"duration": 100, "images": [[1612, 1302]], "exitBranch": 32}, {"duration": 100, "images": [[1736, 1302]]}, {"duration": 100, "images": [[1860, 1302]]}, {"duration": 100, "images": [[1984, 1302]]}, {"duration": 100, "images": [[2108, 1302]]}, {"duration": 100, "images": [[2232, 1302]]}, {"duration": 100, "images": [[2356, 1302]]}, {"duration": 100, "images": [[2480, 1302]]}, {"duration": 100, "images": [[2604, 1302]]}, {"duration": 100, "images": [[2728, 1302]]}, {"duration": 100, "images": [[2852, 1302]]}, {"duration": 100, "images": [[2976, 1302]]}, {"duration": 100, "images": [[3100, 1302]]}, {"duration": 100, "images": [[3224, 1302]]}, {"duration": 100, "images": [[0, 1395]]}, {"duration": 100, "images": [[124, 1395]]}, {"duration": 100, "images": [[248, 1395]], "exitBranch": 48}, {"duration": 100, "images": [[372, 1395]], "exitBranch": 49}, {"duration": 100, "images": [[496, 1395]]}, {"duration": 100, "images": [[620, 1395]], "sound": "4"}, {"duration": 100, "images": [[744, 1395]]}, {"duration": 100, "images": [[868, 1395]]}, {"duration": 600}, {"duration": 100, "images": [[992, 1395]]}, {"duration": 100, "images": [[1116, 1395]]}, {"duration": 100, "images": [[1240, 1395]]}, {"duration": 100, "images": [[1364, 1395]]}, {"duration": 100, "images": [[1488, 1395]]}, {"duration": 100, "images": [[1612, 1395]]}, {"duration": 100, "images": [[1736, 1395]]}, {"duration": 100, "images": [[1860, 1395]]}, {"duration": 100, "images": [[0, 0]]}]}, "Thinking": {"frames": [{"duration": 100, "images": [[0, 0]], "sound": "15"}, {"duration": 100, "images": [[124, 93]]}, {"duration": 100, "images": [[248, 93]]}, {"duration": 100, "images": [[372, 93]]}, {"duration": 100, "images": [[496, 93]], "sound": "14"}, {"duration": 100, "images": [[620, 93]]}, {"duration": 100, "images": [[744, 93]]}, {"duration": 100, "images": [[868, 93]]}, {"duration": 100, "images": Line truncated
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

-62
View File
@@ -1,62 +0,0 @@
.clippy, .clippy-balloon {
position: fixed;
z-index: 1000;
cursor: pointer;
}
.clippy-balloon {
background: #FFC;
color: black;
padding: 8px;
border: 1px solid black;
border-radius: 5px;
}
.clippy-content {
max-width: 200px;
min-width: 120px;
font-family: "Microsoft Sans", sans-serif;
font-size: 10pt;
}
.clippy-tip {
width: 10px;
height: 16px;
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAgCAMAAAAlvKiEAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAAlQTFRF///MAAAA////52QwgAAAAAN0Uk5T//8A18oNQQAAAGxJREFUeNqs0kEOwCAIRFHn3//QTUU6xMyyxii+jQosrTPkyPEM6IN3FtzIRk1U4dFeKWQiH6pRRowMVKEmvronEynkwj0uZJgR22+YLopPSo9P34wJSamLSU7lSIWLJU7NkNomNlhqxUeAAQC+TQLZyEuJBwAAAABJRU5ErkJggg==) no-repeat;
position: absolute;
}
.clippy-top-left .clippy-tip {
top: 100%;
margin-top: 0px;
left: 100%;
margin-left: -50px;
}
.clippy-top-right .clippy-tip {
top: 100%;
margin-top: 0px;
left: 0;
margin-left: 50px;
background-position: -10px 0;
}
.clippy-bottom-right .clippy-tip {
top: 0;
margin-top: -16px;
left: 0;
margin-left: 50px;
background-position: -10px -16px;
}
.clippy-bottom-left .clippy-tip {
top: 0;
margin-top: -16px;
left: 100%;
margin-left: -50px;
background-position: 0px -16px;
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 229 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 238 B

@@ -159,10 +159,6 @@ div.toggle-string {
width: calc(100% - 13px);
}
.operation .bmd-form-group .bmd-help {
margin-top: -17px;
}
.input-group .form-control {
border-top-left-radius: 4px !important;
}
-1
View File
@@ -8,7 +8,6 @@
/* Libraries */
import "highlight.js/styles/vs.css";
import "../static/clippy_assets/clippy.css";
/* Frameworks */
import "./vendors/bootstrap.scss";
-8
View File
@@ -82,14 +82,6 @@ a:focus {
border-color: var(--btn-success-hover-border-colour);
}
input[type="search"] {
appearance: searchfield;
}
input[type="search"]::-webkit-search-cancel-button {
appearance: searchfield-cancel-button;
}
select.form-control:not([size]):not([multiple]), select.custom-file-control:not([size]):not([multiple]) {
height: unset !important;
}
+1 -1
View File
@@ -25,7 +25,7 @@ class ControlsWaiter {
/**
* Initialise Bootstrap componenets
* Initialise Bootstrap components
*/
initComponents() {
$("body").bootstrapMaterialDesign();
+1 -1
View File
@@ -172,7 +172,7 @@ class OperationsWaiter {
$(el).find("[data-toggle=popover]").addBack("[data-toggle=popover]")
.popover({trigger: "manual"})
.on("mouseenter", function(e) {
if (e.buttons > 0) return; // Mouse button held down - likely dragging an opertion
if (e.buttons > 0) return; // Mouse button held down - likely dragging an operation
const _this = this;
$(this).popover("show");
$(".popover").on("mouseleave", function () {
+17 -3
View File
@@ -58,7 +58,7 @@ class OptionsWaiter {
/**
* Handler for options click events.
* Dispays the options pane.
* Displays the options pane.
*
* @param {event} e
*/
@@ -153,14 +153,28 @@ class OptionsWaiter {
/**
* Changes the theme by setting the class of the <html> element.
* Theme change event listener
*
* @param {Event} e
*/
themeChange(e) {
const themeClass = e.target.value;
document.querySelector(":root").className = themeClass;
this.changeTheme(themeClass);
}
/**
* Changes the theme by setting the class of the <html> element.
*
* @param (string} theme
*/
changeTheme(theme) {
document.querySelector(":root").className = theme;
// Update theme selection
const themeSelect = document.getElementById("theme");
themeSelect.selectedIndex = themeSelect.querySelector(`option[value="${theme}"`).index;
}
+1 -1
View File
@@ -174,7 +174,7 @@ class OutputWaiter {
}
/**
* Updates the stored bake ID for the output in the ouptut array
* Updates the stored bake ID for the output in the output array
*
* @param {number} bakeId
* @param {number} inputNum
+2
View File
@@ -399,6 +399,8 @@ class RecipeWaiter {
this.buildRecipeOperation(item);
document.getElementById("rec-list").appendChild(item);
$(item).find("[data-toggle='tooltip']").tooltip();
item.dispatchEvent(this.manager.operationadd);
return item;
}
+1 -294
View File
@@ -4,17 +4,13 @@
* @license Apache-2.0
*/
import clippy from "clippyjs";
import "../static/clippy_assets/agents/Clippy/agent.js";
import clippyMap from "../static/clippy_assets/agents/Clippy/map.png";
/**
* Waiter to handle seasonal events and easter eggs.
*/
class SeasonalWaiter {
/**
* SeasonalWaiter contructor.
* SeasonalWaiter constructor.
*
* @param {App} app - The main view object for CyberChef.
* @param {Manager} manager - The CyberChef event manager.
@@ -22,8 +18,6 @@ class SeasonalWaiter {
constructor(app, manager) {
this.app = app;
this.manager = manager;
this.clippyAgent = null;
}
@@ -34,14 +28,6 @@ class SeasonalWaiter {
// Konami code
this.kkeys = [];
window.addEventListener("keydown", this.konamiCodeListener.bind(this));
// Clippy
const now = new Date();
if (now.getMonth() === 3 && now.getDate() === 1) {
this.addClippyOption();
this.manager.addDynamicListener(".option-item #clippy", "change", this.setupClippy, this);
this.setupClippy();
}
}
@@ -65,285 +51,6 @@ class SeasonalWaiter {
}
}
/**
* Creates an option in the Options menu for turning Clippy on or off
*/
addClippyOption() {
const optionsBody = document.getElementById("options-body"),
optionItem = document.createElement("span");
optionItem.className = "bmd-form-group is-filled";
optionItem.innerHTML = `<div class="checkbox option-item">
<label for="clippy">
<input type="checkbox" option="clippy" id="clippy" checked="">
Use the Clippy helper
</label>
</div>`;
optionsBody.appendChild(optionItem);
if (!("clippy" in this.app.options)) {
this.app.options.clippy = true;
}
this.manager.options.load();
}
/**
* Sets up Clippy for April Fools Day
*/
setupClippy() {
// Destroy any previous agents
if (this.clippyAgent) {
this.clippyAgent.closeBalloonImmediately();
this.clippyAgent.hide();
}
if (!this.app.options.clippy) {
if (this.clippyTimeouts) this.clippyTimeouts.forEach(t => clearTimeout(t));
return;
}
// Set base path to # to prevent external network requests
const clippyAssets = "#";
// Shim the library to prevent external network requests
shimClippy(clippy);
const self = this;
clippy.load("Clippy", (agent) => {
shimClippyAgent(agent);
self.clippyAgent = agent;
agent.show();
agent.speak("Hello, I'm Clippy, your personal cyber assistant!");
}, undefined, clippyAssets);
// Watch for the Auto Magic button appearing
const magic = document.getElementById("magic");
const observer = new MutationObserver((mutationsList, observer) => {
// Read in message and recipe
let msg, recipe;
for (const mutation of mutationsList) {
if (mutation.attributeName === "data-original-title") {
msg = magic.getAttribute("data-original-title");
}
if (mutation.attributeName === "data-recipe") {
recipe = magic.getAttribute("data-recipe");
}
}
// Close balloon if it is currently showing a magic hint
const balloon = self.clippyAgent._balloon._balloon;
if (balloon.is(":visible") && balloon.text().indexOf("That looks like encoded data") >= 0) {
self.clippyAgent._balloon.hide(true);
this.clippyAgent._balloon._hidden = true;
}
// If a recipe was found, get Clippy to tell the user
if (recipe) {
recipe = this.manager.controls.generateStateUrl(true, true, JSON.parse(recipe));
msg = `That looks like encoded data!<br><br>${msg}<br><br>Click <a class="clippyMagicRecipe" href="${recipe}">here</a> to load this recipe.`;
// Stop current balloon activity immediately and trigger speak again
this.clippyAgent.closeBalloonImmediately();
self.clippyAgent.speak(msg, true);
// self.clippyAgent._queue.next();
}
});
observer.observe(document.getElementById("magic"), {attributes: true});
// Play animations for various things
this.manager.addListeners("#search", "click", () => {
this.clippyAgent.play("Searching");
}, this);
this.manager.addListeners("#save,#save-to-file", "click", () => {
this.clippyAgent.play("Save");
}, this);
this.manager.addListeners("#clr-recipe,#clr-io", "click", () => {
this.clippyAgent.play("EmptyTrash");
}, this);
this.manager.addListeners("#bake", "click", e => {
if (e.target.closest("button").textContent.toLowerCase().indexOf("bake") >= 0) {
this.clippyAgent.play("Thinking");
} else {
this.clippyAgent.play("EmptyTrash");
}
this.clippyAgent._queue.clear();
}, this);
this.manager.addListeners("#input-text", "keydown", () => {
this.clippyAgent.play("Writing");
this.clippyAgent._queue.clear();
}, this);
this.manager.addDynamicListener("a.clippyMagicRecipe", "click", (e) => {
this.clippyAgent.play("Congratulate");
}, this);
this.clippyTimeouts = [];
// Show challenge after timeout
this.clippyTimeouts.push(setTimeout(() => {
const hex = "1f 8b 08 00 ae a1 9b 5c 00 ff 05 40 a1 12 00 10 0c fd 26 61 5b 76 aa 9d 26 a8 02 02 37 84 f7 fb bb c5 a4 5f 22 c6 09 e5 6e c5 4c 2d 3f e9 30 a6 ea 41 a2 f2 ac 1c 00 00 00";
self.clippyAgent.speak(`How about a fun challenge?<br><br>Try decoding this (click to load):<br><a href="#recipe=[]&input=${encodeURIComponent(btoa(hex))}">${hex}</a>`, true);
self.clippyAgent.play("GetAttention");
}, 1 * 60 * 1000));
this.clippyTimeouts.push(setTimeout(() => {
self.clippyAgent.speak("<i>Did you know?</i><br><br>You can load files into CyberChef up to around 500MB using drag and drop or the load file button.", 15000);
self.clippyAgent.play("Wave");
}, 2 * 60 * 1000));
this.clippyTimeouts.push(setTimeout(() => {
self.clippyAgent.speak("<i>Did you know?</i><br><br>You can use the 'Fork' operation to split up your input and run the recipe over each branch separately.<br><br><a class='clippyMagicRecipe' href=\"#recipe=Fork('%5C%5Cn','%5C%5Cn',false)From_UNIX_Timestamp('Seconds%20(s)')&amp;input=OTc4MzQ2ODAwCjEwMTI2NTEyMDAKMTA0NjY5NjQwMAoxMDgxMDg3MjAwCjExMTUzMDUyMDAKMTE0OTYwOTYwMA\">Here's an example</a>.", 15000);
self.clippyAgent.play("Print");
}, 3 * 60 * 1000));
this.clippyTimeouts.push(setTimeout(() => {
self.clippyAgent.speak("<i>Did you know?</i><br><br>The 'Magic' operation uses a number of methods to detect encoded data and the operations which can be used to make sense of it. A technical description of these methods can be found <a href=\"https://github.com/gchq/CyberChef/wiki/Automatic-detection-of-encoded-data-using-CyberChef-Magic\">here</a>.", 15000);
self.clippyAgent.play("Alert");
}, 4 * 60 * 1000));
this.clippyTimeouts.push(setTimeout(() => {
self.clippyAgent.speak("<i>Did you know?</i><br><br>You can use parts of the input as arguments to operations.<br><br><a class='clippyMagicRecipe' href=\"#recipe=Register('key%3D(%5B%5C%5Cda-f%5D*)',true,false)Find_/_Replace(%7B'option':'Regex','string':'.*data%3D(.*)'%7D,'$1',true,false,true)RC4(%7B'option':'Hex','string':'$R0'%7D,'Hex','Latin1')&amp;input=aHR0cDovL21hbHdhcmV6LmJpei9iZWFjb24ucGhwP2tleT0wZTkzMmE1YyZkYXRhPThkYjdkNWViZTM4NjYzYTU0ZWNiYjMzNGUzZGIxMQ\">Click here for an example</a>.", 15000);
self.clippyAgent.play("CheckingSomething");
}, 5 * 60 * 1000));
}
}
/**
* Shims various ClippyJS functions to modify behaviour.
*
* @param {Clippy} clippy - The Clippy library
*/
function shimClippy(clippy) {
// Shim _loadSounds so that it doesn't actually try to load any sounds
clippy.load._loadSounds = function _loadSounds (name, path) {
let dfd = clippy.load._sounds[name];
if (dfd) return dfd;
// set dfd if not defined
dfd = clippy.load._sounds[name] = $.Deferred();
// Resolve immediately without loading
dfd.resolve({});
return dfd.promise();
};
// Shim _loadMap so that it uses the local copy
clippy.load._loadMap = function _loadMap (path) {
let dfd = clippy.load._maps[path];
if (dfd) return dfd;
// set dfd if not defined
dfd = clippy.load._maps[path] = $.Deferred();
const src = clippyMap;
const img = new Image();
img.onload = dfd.resolve;
img.onerror = dfd.reject;
// start loading the map;
img.setAttribute("src", src);
return dfd.promise();
};
// Make sure we don't request the remote map
clippy.Animator.prototype._setupElement = function _setupElement (el) {
const frameSize = this._data.framesize;
el.css("display", "none");
el.css({ width: frameSize[0], height: frameSize[1] });
el.css("background", "url('" + clippyMap + "') no-repeat");
return el;
};
}
/**
* Shims various ClippyJS Agent functions to modify behaviour.
*
* @param {Agent} agent - The Clippy Agent
*/
function shimClippyAgent(agent) {
// Turn off all sounds
agent._animator._playSound = () => {};
// Improve speak function to support HTML markup
const self = agent._balloon;
agent._balloon.speak = (complete, text, hold) => {
self._hidden = false;
self.show();
const c = self._content;
// set height to auto
c.height("auto");
c.width("auto");
// add the text
c.html(text);
// set height
c.height(c.height());
c.width(c.width());
c.text("");
self.reposition();
self._complete = complete;
self._sayWords(text, hold, complete);
if (hold) agent._queue.next();
};
// Improve the _sayWords function to allow HTML and support timeouts
agent._balloon.WORD_SPEAK_TIME = 60;
agent._balloon._sayWords = (text, hold, complete) => {
self._active = true;
self._hold = hold;
const words = text.split(/[^\S-]/);
const time = self.WORD_SPEAK_TIME;
const el = self._content;
let idx = 1;
clearTimeout(self.holdTimeout);
self._addWord = $.proxy(function () {
if (!self._active) return;
if (idx > words.length) {
delete self._addWord;
self._active = false;
if (!self._hold) {
complete();
self.hide();
} else if (typeof hold === "number") {
self.holdTimeout = setTimeout(() => {
self._hold = false;
complete();
self.hide();
}, hold);
}
} else {
el.html(words.slice(0, idx).join(" "));
idx++;
self._loop = window.setTimeout($.proxy(self._addWord, self), time);
}
}, self);
self._addWord();
};
// Add break-word to balloon CSS
agent._balloon._balloon.css("word-break", "break-word");
// Close the balloon on click (unless it was a link)
agent._balloon._balloon.click(e => {
if (e.target.nodeName !== "A") {
agent._balloon.hide(true);
agent._balloon._hidden = true;
}
});
// Add function to immediately close the balloon even if it is currently doing something
agent.closeBalloonImmediately = () => {
agent._queue.clear();
agent._balloon.hide(true);
agent._balloon._hidden = true;
agent._queue.next();
};
}
export default SeasonalWaiter;
+1 -1
View File
@@ -33,7 +33,7 @@ class WindowWaiter {
/**
* Handler for window blur events.
* Saves the current time so that we can calculate how long the window was unfocussed for when
* Saves the current time so that we can calculate how long the window was unfocused for when
* focus is returned.
*/
windowBlur() {
+1 -1
View File
@@ -353,7 +353,7 @@ class WorkerWaiter {
* @param {object} workerObj - Object containing the worker information
* @param {ChefWorker} workerObj.worker - The actual worker object
* @param {number} workerObj.inputNum - The inputNum of the input being baked by the worker
* @param {boolean} workerObj.active - If true, the worker is currrently baking an input
* @param {boolean} workerObj.active - If true, the worker is currently baking an input
*/
workerFinished(workerObj) {
const workerIdx = this.chefWorkers.indexOf(workerObj);
+1 -1
View File
@@ -945,7 +945,7 @@ self.updateMaxTabs = function(maxTabs, activeTab) {
* @param {boolean} searchData.showLoading - If true, include loading inputs in the results
* @param {boolean} searchData.showLoaded - If true, include loaded inputs in the results
* @param {string} searchData.filter - A regular expression to match the inputs on
* @param {string} searchData.filterType - Either "CONTENT" or "FILENAME". Detemines what should be matched with filter
* @param {string} searchData.filterType - Either "CONTENT" or "FILENAME". Determines what should be matched with filter
* @param {number} searchData.numResults - The maximum number of results to be returned
*/
self.filterTabs = function(searchData) {
+8 -5
View File
@@ -13,13 +13,16 @@
import {
setLongTestFailure,
logTestReport,
} from "../lib/utils";
} from "../lib/utils.mjs";
import TestRegister from "../lib/TestRegister.mjs";
import "./tests/nodeApi";
import "./tests/operations";
import "./tests/File";
import "./tests/NodeDish";
import "./tests/nodeApi.mjs";
import "./tests/operations.mjs";
import "./tests/File.mjs";
import "./tests/Dish.mjs";
import "./tests/NodeDish.mjs";
import "./tests/Utils.mjs";
import "./tests/Categories.mjs";
const testStatus = {
allTestsPassing: true,
+19
View File
@@ -0,0 +1,19 @@
import TestRegister from "../../lib/TestRegister.mjs";
import Categories from "../../../src/core/config/Categories.json";
import OperationConfig from "../../../src/core/config/OperationConfig.json";
import it from "../assertionHandler.mjs";
import assert from "assert";
TestRegister.addApiTests([
it("Categories: operations should be in a category", () => {
const catOps = [];
Categories.forEach(cat => {
catOps.push(...cat.ops);
});
for (const op in OperationConfig) {
assert(catOps.includes(op), `'${op}' operation is not present in any category`);
}
}),
]);
@@ -1,6 +1,6 @@
import TestRegister from "../../lib/TestRegister.mjs";
import Dish from "../../src/core/Dish.mjs";
import it from "../node/assertionHandler.mjs";
import Dish from "../../../src/core/Dish.mjs";
import it from "../../node/assertionHandler.mjs";
import assert from "assert";
TestRegister.addApiTests([
+23
View File
@@ -0,0 +1,23 @@
import TestRegister from "../../lib/TestRegister.mjs";
import Utils from "../../../src/core/Utils.mjs";
import it from "../assertionHandler.mjs";
import assert from "assert";
TestRegister.addApiTests([
it("Utils: should parse six backslashes correctly", () => {
assert.equal(Utils.parseEscapedChars("\\\\\\\\\\\\"), "\\\\\\");
}),
it("Utils: should parse escaped quotes correctly", () => {
assert.equal(Utils.parseEscapedChars("\\'"), "'");
}),
it("Utils: should parse escaped quotes and backslashes correctly", () => {
assert.equal(Utils.parseEscapedChars("\\\\'"), "\\'");
}),
it("Utils: should parse escaped quotes and escaped backslashes correctly", () => {
assert.equal(Utils.parseEscapedChars("\\\\\\'"), "\\'");
}),
]);
+33 -16
View File
@@ -31,7 +31,7 @@ import {
cartesianProduct,
CSSMinify,
toBase64,
toHex,
toHex
} from "../../../src/node/index";
import chef from "../../../src/node/index.mjs";
import TestRegister from "../../lib/TestRegister.mjs";
@@ -186,27 +186,29 @@ Full hash: $2a$10$ODeP1.6fMsb.ENk2ngPUCO7qTGVPyHA9TqDVcyupyed8FjsiF65L6`;
it("Blowfish encrypt", () => {
const result = chef.blowfishEncrypt("Fool's Gold", {
key: {
string: "One",
string: "0011223344556677",
option: "hex",
},
iv: {
string: "Two",
string: "exparrot",
option: "utf8"
}
},
mode: "CBC"
});
assert.strictEqual(result.toString(), "8999b513bf2ff064b2977dea7e05f1b5");
assert.strictEqual(result.toString(), "55a2838980078ffe1722b08d5fa1d481");
}),
it("Blowfish decrypt", () => {
const result = chef.blowfishDecrypt("8999b513bf2ff064b2977dea7e05f1b5", {
const result = chef.blowfishDecrypt("55a2838980078ffe1722b08d5fa1d481", {
key: {
string: "One",
string: "0011223344556677",
option: "hex",
},
iv: {
string: "Two",
string: "exparrot",
option: "utf8",
}
},
mode: "CBC"
});
assert.strictEqual(result.toString(), "Fool's Gold");
}),
@@ -353,10 +355,10 @@ color: white;
it("Decode text", () => {
const encoded = chef.encodeText("Ugly Duckling", {
encoding: "UTF16LE (1200)",
encoding: "UTF-16LE (1200)",
});
const result = chef.decodeText(encoded, {
encoding: "UTF16LE (1200)",
encoding: "UTF-16LE (1200)",
});
assert.strictEqual(result.toString(), "Ugly Duckling");
}),
@@ -400,7 +402,7 @@ color: white;
},
iv: {
string: "threetwo",
option: "Hex",
option: "utf8",
},
mode: "ECB",
});
@@ -415,7 +417,7 @@ color: white;
},
iv: {
string: "threetwo",
option: "Hex",
option: "utf8",
},
mode: "ECB",
});
@@ -943,10 +945,10 @@ smothering ampersand abreast
chef.tripleDESDecrypt(
chef.tripleDESEncrypt("Destroy Money", {
key: {string: "30 31 2f 30 34 2f 31 39 39 39 20 32 32 3a 33 33 3a 30 3130 31 2f 30 34", option: "Hex"},
iv: {string: "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0000 00 00 00 00", option: "Hex"}}),
iv: {string: "00 00 00 00 00 00 00 00", option: "Hex"}}),
{
key: {string: "30 31 2f 30 34 2f 31 39 39 39 20 32 32 3a 33 33 3a 30 3130 31 2f 30 34", option: "Hex"},
iv: {string: "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0000 00 00 00 00", option: "Hex"}
iv: {string: "00 00 00 00 00 00 00 00", option: "Hex"}
}).toString(),
"Destroy Money");
}),
@@ -1028,7 +1030,7 @@ ExifImageHeight: 57`);
const zipped = chef.zip("some file content", {
filename: "sample.zip",
comment: "added",
operaringSystem: "Unix",
operatingSystem: "Unix",
});
assert.strictEqual(zipped.type, 7);
@@ -1059,5 +1061,20 @@ ExifImageHeight: 57`);
assert.equal(unzipped.value[0].data, "some content");
}),
it("YARA Rule Matching", async () => {
const input = "foobar foobar bar foo foobar";
const output = "Rule \"foo\" matches (4 times):\nPos 0, length 3, identifier $re1, data: \"foo\"\nPos 7, length 3, identifier $re1, data: \"foo\"\nPos 18, length 3, identifier $re1, data: \"foo\"\nPos 22, length 3, identifier $re1, data: \"foo\"\nRule \"bar\" matches (4 times):\nPos 3, length 3, identifier $re1, data: \"bar\"\nPos 10, length 3, identifier $re1, data: \"bar\"\nPos 14, length 3, identifier $re1, data: \"bar\"\nPos 25, length 3, identifier $re1, data: \"bar\"\n";
const res = await chef.YARARules(input, {
rules: "rule foo {strings: $re1 = /foo/ condition: $re1} rule bar {strings: $re1 = /bar/ condition: $re1}",
showStrings: true,
showStringLengths: true,
showMetadata: true
});
assert.equal(output, res.value);
}),
]);
+3 -3
View File
@@ -91,13 +91,13 @@ import "./tests/Protobuf.mjs";
import "./tests/ParseSSHHostKey.mjs";
import "./tests/DefangIP.mjs";
import "./tests/ParseUDP.mjs";
import "./tests/AvroToJSON.mjs";
import "./tests/Lorenz.mjs";
// Cannot test operations that use the File type yet
// import "./tests/SplitColourChannels.mjs";
// import "./tests/nodeApi/nodeApi.mjs";
// import "./tests/nodeApi/ops.mjs";
const testStatus = {
allTestsPassing: true,
counts: {
+66
View File
@@ -0,0 +1,66 @@
/**
* Avro to JSON tests.
*
* @author jarrodconnolly [jarrod@nestedquotes.ca]
* @copyright Crown Copyright 2019
* @license Apache-2.0
*/
import TestRegister from "../../lib/TestRegister";
TestRegister.addTests([
{
name: "Avro to JSON: no input (force JSON true)",
input: "",
expectedOutput: "Please provide an input.",
recipeConfig: [
{
op: "Avro to JSON",
args: [true]
}
],
},
{
name: "Avro to JSON: no input (force JSON false)",
input: "",
expectedOutput: "Please provide an input.",
recipeConfig: [
{
op: "Avro to JSON",
args: [false]
}
],
},
{
name: "Avro to JSON: small (force JSON true)",
input: "\x4f\x62\x6a\x01\x04\x16\x61\x76\x72\x6f\x2e\x73\x63\x68\x65\x6d\x61\x96\x01\x7b\x22\x74\x79\x70\x65\x22\x3a\x22\x72\x65" +
"\x63\x6f\x72\x64\x22\x2c\x22\x6e\x61\x6d\x65\x22\x3a\x22\x73\x6d\x61\x6c\x6c\x22\x2c\x22\x66\x69\x65\x6c\x64\x73\x22\x3a" +
"\x5b\x7b\x22\x6e\x61\x6d\x65\x22\x3a\x22\x6e\x61\x6d\x65\x22\x2c\x22\x74\x79\x70\x65\x22\x3a\x22\x73\x74\x72\x69\x6e\x67" +
"\x22\x7d\x5d\x7d\x14\x61\x76\x72\x6f\x2e\x63\x6f\x64\x65\x63\x08\x6e\x75\x6c\x6c\x00\x4e\x02\x47\x63\x2e\x37\x02\xe5\xb7" +
"\x5c\xda\xb9\xa6\x2f\x15\x41\x02\x0e\x0c\x6d\x79\x6e\x61\x6d\x65\x4e\x02\x47\x63\x2e\x37\x02\xe5\xb7\x5c\xda\xb9\xa6\x2f" +
"\x15\x41",
expectedOutput: "{\n \"name\": \"myname\"\n}",
recipeConfig: [
{
op: "Avro to JSON",
args: [true]
}
],
},
{
name: "Avro to JSON: small (force JSON false)",
input: "\x4f\x62\x6a\x01\x04\x16\x61\x76\x72\x6f\x2e\x73\x63\x68\x65\x6d\x61\x96\x01\x7b\x22\x74\x79\x70\x65\x22\x3a\x22\x72\x65" +
"\x63\x6f\x72\x64\x22\x2c\x22\x6e\x61\x6d\x65\x22\x3a\x22\x73\x6d\x61\x6c\x6c\x22\x2c\x22\x66\x69\x65\x6c\x64\x73\x22\x3a" +
"\x5b\x7b\x22\x6e\x61\x6d\x65\x22\x3a\x22\x6e\x61\x6d\x65\x22\x2c\x22\x74\x79\x70\x65\x22\x3a\x22\x73\x74\x72\x69\x6e\x67" +
"\x22\x7d\x5d\x7d\x14\x61\x76\x72\x6f\x2e\x63\x6f\x64\x65\x63\x08\x6e\x75\x6c\x6c\x00\x4e\x02\x47\x63\x2e\x37\x02\xe5\xb7" +
"\x5c\xda\xb9\xa6\x2f\x15\x41\x02\x0e\x0c\x6d\x79\x6e\x61\x6d\x65\x4e\x02\x47\x63\x2e\x37\x02\xe5\xb7\x5c\xda\xb9\xa6\x2f" +
"\x15\x41",
expectedOutput: "{\"name\":\"myname\"}\n",
recipeConfig: [
{
op: "Avro to JSON",
args: [false]
}
],
}
]);
+2 -2
View File
@@ -69,7 +69,7 @@ TestRegister.addTests([
],
},
{
name: "Generate Base64 Windows Powershell",
name: "Generate Base64 Windows PowerShell",
input: "ZABpAHIAIAAiAGMAOgBcAHAAcgBvAGcAcgBhAG0AIABmAGkAbABlAHMAIgAgAA==",
expectedOutput: "dir \"c:\\program files\" ",
recipeConfig: [
@@ -79,7 +79,7 @@ TestRegister.addTests([
},
{
"op": "Decode text",
"args": ["UTF16LE (1200)"]
"args": ["UTF-16LE (1200)"]
},
{
"op": "Encode text",
+1 -1
View File
@@ -42,7 +42,7 @@ TestRegister.addTests([
{
name: "Fork, Comment, Base64",
input: "cat\nsat\nmat",
expectedOutput: "Y2F0\nc2F0\nbWF0\n",
expectedOutput: "Y2F0\nc2F0\nbWF0",
recipeConfig: [
{
"op": "Fork",
+375
View File
@@ -1376,4 +1376,379 @@ DES uses a key length of 8 bytes (64 bits).`,
}
],
},
/*
The following expectedOutputs are generated with this Python script with pyCryptoDome
from Crypto.Cipher import Blowfish
import binascii
input_data = b"The quick brown fox jumps over the lazy dog."
key = binascii.unhexlify("0011223344556677")
iv = binascii.unhexlify("0000000000000000")
mode = Blowfish.MODE_CBC
if mode == Blowfish.MODE_ECB or mode == Blowfish.MODE_CBC:
padding_len = 8-(len(input_data) & 7)
for i in range(padding_len):
input_data += bytes([padding_len])
cipher = Blowfish.new(key, mode) # set iv, nonce, segment_size etc. here
cipher_text = cipher.encrypt(input_data)
cipher_text = binascii.hexlify(cipher_text).decode("UTF-8")
print("Encrypted: {}".format(cipher_text))
*/
{
name: "Blowfish Encrypt: ECB, ASCII",
input: "The quick brown fox jumps over the lazy dog.",
expectedOutput: "f7784137ab1bf51546c0b120bdb7fed4509116e49283b35fab0e4292ac86251a9bf908330e3393815e3356bb26524027",
recipeConfig: [
{
"op": "Blowfish Encrypt",
"args": [
{"option": "Hex", "string": "0011223344556677"}, // Key
{"option": "Hex", "string": "0000000000000000"}, // IV
"ECB", // Mode
"Raw", // Input
"Hex" // Output
]
}
],
},
{
name: "Blowfish Encrypt: ECB, Binary",
input: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
expectedOutput: "3d1bf0e87d83782d435a0ca58179ca290184867f52295af5c0fb4dcac7c6c68942906bb421d05925cc7d9cd21532376a0f6ae4c3f008b250381ffa9624f5eb697dbd44de48cf5593ea7dbf5842238474b546ceeb29f6cf327a7d13698786b8d14451f52fb0f5760a",
recipeConfig: [
{
"op": "Blowfish Encrypt",
"args": [
{"option": "Hex", "string": "0011223344556677"}, // Key
{"option": "Hex", "string": "0000000000000000"}, // IV
"ECB", // Mode
"Hex", // Input
"Hex" // Output
]
}
],
},
{
name: "Blowfish Decrypt: ECB, ASCII",
input: "f7784137ab1bf51546c0b120bdb7fed4509116e49283b35fab0e4292ac86251a9bf908330e3393815e3356bb26524027",
expectedOutput: "The quick brown fox jumps over the lazy dog.",
recipeConfig: [
{
"op": "Blowfish Decrypt",
"args": [
{"option": "Hex", "string": "0011223344556677"}, // Key
{"option": "Hex", "string": "0000000000000000"}, // IV
"ECB", // Mode
"Hex", // Input
"Raw" // Output
]
}
],
},
{
name: "Blowfish Decrypt: ECB, Binary",
input: "3d1bf0e87d83782d435a0ca58179ca290184867f52295af5c0fb4dcac7c6c68942906bb421d05925cc7d9cd21532376a0f6ae4c3f008b250381ffa9624f5eb697dbd44de48cf5593ea7dbf5842238474b546ceeb29f6cf327a7d13698786b8d14451f52fb0f5760a",
expectedOutput: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
recipeConfig: [
{
"op": "Blowfish Decrypt",
"args": [
{"option": "Hex", "string": "0011223344556677"}, // Key
{"option": "Hex", "string": "0000000000000000"}, // IV
"ECB", // Mode
"Hex", // Input
"Hex" // Output
]
}
],
},
{
name: "Blowfish Encrypt: CBC, ASCII",
input: "The quick brown fox jumps over the lazy dog.",
expectedOutput: "398433f39e938286a35fc240521435b6972f3fe96846b54ab9351aa5fa9e10a6a94074e883d1cb36cb9657c817274b60",
recipeConfig: [
{
"op": "Blowfish Encrypt",
"args": [
{"option": "Hex", "string": "0011223344556677"}, // Key
{"option": "Hex", "string": "ffeeddccbbaa9988"}, // IV
"CBC", // Mode
"Raw", // Input
"Hex" // Output
]
}
],
},
{
name: "Blowfish Encrypt: CBC, Binary",
input: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
expectedOutput: "3b42c51465896524e66c2fd2404c8c2b4eb26c760671f131c3372d374f48283ca9a5404d3d8aabd2a886c6551393ca41c682580f1c81f16046e3bec7b59247bdfca1d40bf2ad8ede9de99cb44b36658f775999d37776b3b1a085b9530e54ece69e1875e1bdc8cdcf",
recipeConfig: [
{
"op": "Blowfish Encrypt",
"args": [
{"option": "Hex", "string": "0011223344556677"}, // Key
{"option": "Hex", "string": "ffeeddccbbaa9988"}, // IV
"CBC", // Mode
"Hex", // Input
"Hex" // Output
]
}
],
},
{
name: "Blowfish Decrypt: CBC, ASCII",
input: "398433f39e938286a35fc240521435b6972f3fe96846b54ab9351aa5fa9e10a6a94074e883d1cb36cb9657c817274b60",
expectedOutput: "The quick brown fox jumps over the lazy dog.",
recipeConfig: [
{
"op": "Blowfish Decrypt",
"args": [
{"option": "Hex", "string": "0011223344556677"}, // Key
{"option": "Hex", "string": "ffeeddccbbaa9988"}, // IV
"CBC", // Mode
"Hex", // Input
"Raw" // Output
]
}
],
},
{
name: "Blowfish Decrypt: CBC, Binary",
input: "3b42c51465896524e66c2fd2404c8c2b4eb26c760671f131c3372d374f48283ca9a5404d3d8aabd2a886c6551393ca41c682580f1c81f16046e3bec7b59247bdfca1d40bf2ad8ede9de99cb44b36658f775999d37776b3b1a085b9530e54ece69e1875e1bdc8cdcf",
expectedOutput: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
recipeConfig: [
{
"op": "Blowfish Decrypt",
"args": [
{"option": "Hex", "string": "0011223344556677"}, // Key
{"option": "Hex", "string": "ffeeddccbbaa9988"}, // IV
"CBC", // Mode
"Hex", // Input
"Hex" // Output
]
}
],
},
{
name: "Blowfish Encrypt: CFB, ASCII",
input: "The quick brown fox jumps over the lazy dog.",
// pyCryptoDome produces a different value with default settings. This is due to segment_size having
// a default value of 8 bits. Setting it to 64 (one full block) will yield the same result.
expectedOutput: "c8ca123592570c1fcb138d4ec08f7af14ad49363245be1ac25029c8ffc508b3217e75faaa5566426180fec8f",
recipeConfig: [
{
"op": "Blowfish Encrypt",
"args": [
{"option": "Hex", "string": "0011223344556677"}, // Key
{"option": "Hex", "string": "ffeeddccbbaa9988"}, // IV
"CFB", // Mode
"Raw", // Input
"Hex" // Output
]
}
],
},
{
name: "Blowfish Encrypt: CFB, Binary",
input: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
// see above. pyCryptoDome produces a different value with its default settings
expectedOutput: "e6ac1324d1576beab00e855de3f4ac1f5e3cbf89f4c2a743a5737895067ac5012e5bdb92477e256cc07bf691b58e721179b550e694abb0be7cbdc42586db755bf795f4338f47d356c57453afa6277e46aaeb3405f9744654a477f06c2ad92ede90555759",
recipeConfig: [
{
"op": "Blowfish Encrypt",
"args": [
{"option": "Hex", "string": "0011223344556677"}, // Key
{"option": "Hex", "string": "ffeeddccbbaa9988"}, // IV
"CFB", // Mode
"Hex", // Input
"Hex" // Output
]
}
],
},
{
name: "Blowfish Decrypt: CFB, ASCII",
input: "c8ca123592570c1fcb138d4ec08f7af14ad49363245be1ac25029c8ffc508b3217e75faaa5566426180fec8f",
expectedOutput: "The quick brown fox jumps over the lazy dog.",
// see above. pyCryptoDome produces a different value with its default settings
recipeConfig: [
{
"op": "Blowfish Decrypt",
"args": [
{"option": "Hex", "string": "0011223344556677"}, // Key
{"option": "Hex", "string": "ffeeddccbbaa9988"}, // IV
"CFB", // Mode
"Hex", // Input
"Raw" // Output
]
}
],
},
{
name: "Blowfish Decrypt: CFB, Binary",
input: "e6ac1324d1576beab00e855de3f4ac1f5e3cbf89f4c2a743a5737895067ac5012e5bdb92477e256cc07bf691b58e721179b550e694abb0be7cbdc42586db755bf795f4338f47d356c57453afa6277e46aaeb3405f9744654a477f06c2ad92ede90555759",
expectedOutput: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
// see above. pyCryptoDome produces a different value with its default settings
recipeConfig: [
{
"op": "Blowfish Decrypt",
"args": [
{"option": "Hex", "string": "0011223344556677"}, // Key
{"option": "Hex", "string": "ffeeddccbbaa9988"}, // IV
"CFB", // Mode
"Hex", // Input
"Hex" // Output
]
}
],
},
{
name: "Blowfish Encrypt: OFB, ASCII",
input: "The quick brown fox jumps over the lazy dog.",
expectedOutput: "c8ca123592570c1fffcee88b9823b9450dc9c48e559123c1df1984214212bae7e44114d29dba79683d10cce5",
recipeConfig: [
{
"op": "Blowfish Encrypt",
"args": [
{"option": "Hex", "string": "0011223344556677"}, // Key
{"option": "Hex", "string": "ffeeddccbbaa9988"}, // IV
"OFB", // Mode
"Raw", // Input
"Hex" // Output
]
}
],
},
{
name: "Blowfish Encrypt: OFB, Binary",
input: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
expectedOutput: "e6ac1324d1576bea4ceb5be7691c35e4919f18be06cc2a926025ef0973222e987de7c63cd71ed3b19190ba006931d9cbdf412f5b1ac7155904ca591f693fe11aa996e17866e0de4b2eb7ff5effabf94b0f49ed159202caf72745ac2f024d86f942d83767",
recipeConfig: [
{
"op": "Blowfish Encrypt",
"args": [
{"option": "Hex", "string": "0011223344556677"}, // Key
{"option": "Hex", "string": "ffeeddccbbaa9988"}, // IV
"OFB", // Mode
"Hex", // Input
"Hex" // Output
]
}
],
},
{
name: "Blowfish Decrypt: OFB, ASCII",
input: "c8ca123592570c1fffcee88b9823b9450dc9c48e559123c1df1984214212bae7e44114d29dba79683d10cce5",
expectedOutput: "The quick brown fox jumps over the lazy dog.",
recipeConfig: [
{
"op": "Blowfish Decrypt",
"args": [
{"option": "Hex", "string": "0011223344556677"}, // Key
{"option": "Hex", "string": "ffeeddccbbaa9988"}, // IV
"OFB", // Mode
"Hex", // Input
"Raw" // Output
]
}
],
},
{
name: "Blowfish Decrypt: OFB, Binary",
input: "e6ac1324d1576bea4ceb5be7691c35e4919f18be06cc2a926025ef0973222e987de7c63cd71ed3b19190ba006931d9cbdf412f5b1ac7155904ca591f693fe11aa996e17866e0de4b2eb7ff5effabf94b0f49ed159202caf72745ac2f024d86f942d83767",
expectedOutput: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
recipeConfig: [
{
"op": "Blowfish Decrypt",
"args": [
{"option": "Hex", "string": "0011223344556677"}, // Key
{"option": "Hex", "string": "ffeeddccbbaa9988"}, // IV
"OFB", // Mode
"Hex", // Input
"Hex" // Output
]
}
],
},
{
name: "Blowfish Encrypt: CTR, ASCII",
input: "The quick brown fox jumps over the lazy dog.",
expectedOutput: "e2a5e0f03ad4877101c7cf83861ad93477adb57acac4bebc315a7bae34b4e6a54e5532db457a3131dcd9dda6",
recipeConfig: [
{
"op": "Blowfish Encrypt",
"args": [
{"option": "Hex", "string": "0011223344556677"}, // Key
// pyCryptoDome only allows the size of the nonce to be [0,7] bytes.
// Internally, it right-pads the nonce to 7 bytes long if it wasn't already 7 bytes,
// and the last (8th) byte is used for counter.
// Therefore a pyCryptoDome nonce of "aabbccdd" is equivalent to an IV of "aabbccdd00000000" here.
{"option": "Hex", "string": "0000000000000000"}, // IV (nonce)
"CTR", // Mode
"Raw", // Input
"Hex" // Output
]
}
],
},
{
name: "Blowfish Encrypt: CTR, Binary",
input: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
expectedOutput: "ccc3e1e179d4e084b2e27cef77255595ebfb694a9999b7ef8e661086058472dad7f3e0350fde9be87059ab43d5b800aa08be4c00f3f2e99402fe2702c39e8663dbcbb146700d63432227f1045f116bfd4b65022ca20b70427ddcfd7441cb3c75f4d3fff0",
recipeConfig: [
{
"op": "Blowfish Encrypt",
"args": [
{"option": "Hex", "string": "0011223344556677"}, // Key
// See notes above
{"option": "Hex", "string": "0000000000000000"}, // IV (nonce)
"CTR", // Mode
"Hex", // Input
"Hex" // Output
]
}
],
},
{
name: "Blowfish Decrypt: CTR, ASCII",
input: "e2a5e0f03ad4877101c7cf83861ad93477adb57acac4bebc315a7bae34b4e6a54e5532db457a3131dcd9dda6",
expectedOutput: "The quick brown fox jumps over the lazy dog.",
recipeConfig: [
{
"op": "Blowfish Decrypt",
"args": [
{"option": "Hex", "string": "0011223344556677"}, // Key
// See notes above
{"option": "Hex", "string": "0000000000000000"}, // IV (nonce)
"CTR", // Mode
"Hex", // Input
"Raw" // Output
]
}
],
},
{
name: "Blowfish Decrypt: CTR, Binary",
input: "ccc3e1e179d4e084b2e27cef77255595ebfb694a9999b7ef8e661086058472dad7f3e0350fde9be87059ab43d5b800aa08be4c00f3f2e99402fe2702c39e8663dbcbb146700d63432227f1045f116bfd4b65022ca20b70427ddcfd7441cb3c75f4d3fff0",
expectedOutput: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
recipeConfig: [
{
"op": "Blowfish Decrypt",
"args": [
{"option": "Hex", "string": "0011223344556677"}, // Key
// See notes above
{"option": "Hex", "string": "0000000000000000"}, // IV (nonce)
"CTR", // Mode
"Hex", // Input
"Hex" // Output
]
}
],
},
]);
+1 -1
View File
@@ -57,7 +57,7 @@ TestRegister.addTests([
{
name: "Fork, Conditional Jump, Encodings",
input: "Some data with a 1 in it\nSome data with a 2 in it",
expectedOutput: "U29tZSBkYXRhIHdpdGggYSAxIGluIGl0\n53 6f 6d 65 20 64 61 74 61 20 77 69 74 68 20 61 20 32 20 69 6e 20 69 74\n",
expectedOutput: "U29tZSBkYXRhIHdpdGggYSAxIGluIGl0\n53 6f 6d 65 20 64 61 74 61 20 77 69 74 68 20 61 20 32 20 69 6e 20 69 74",
recipeConfig: [
{"op": "Fork", "args": ["\\n", "\\n", false]},
{"op": "Conditional Jump", "args": ["1", false, "skipReturn", "10"]},
+108
View File
@@ -0,0 +1,108 @@
/**
* Lorenz SZ40/42a/42b machine tests.
*
* @author VirtualColossus
* @copyright Crown Copyright 2019
* @license Apache-2.0
*/
import TestRegister from "../../lib/TestRegister.mjs";
TestRegister.addTests([
{
// Simple test first - plain text to ITA2
name: "Lorenz SZ40: no pattern, plain text",
input: "HELLO WORLD, THIS IS A TEST MESSAGE.",
expectedOutput: "HELLO9WORLD55N889THIS9IS9A9TEST9MESSAGE55M",
recipeConfig: [
{
"op": "Lorenz",
"args": ["SZ40", "No Pattern", false, "Send", "Plaintext", "Plaintext", "5/8/9", 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ".x...xx.x.x..xxx.x.x.xxxx.x.x.x.x.x..x.xx.x", ".xx.x.xxx..x.x.x..x.xx.x.xxx.x....x.xx.x.x.x..x", ".x.x.x..xxx....x.x.xx.x.x.x..xxx.x.x..x.x.xx..x.x.x", ".xx...xxxxx.x.x.xx...x.xx.x.x..x.x.xx.x..x.x.x.x.x.x.", "xx...xx.x..x.xx.x...x.x.x.x.x.x.x.x.xx..xxxx.x.x...xx.x..x.", "x.x.x.x.x.x...x.x.x...x.x.x...x.x....", ".xxxx.xxxx.xxx.xxxx.xx....xxx.xxxx.xxxx.xxxx.xxxx.xxx.xxxx...", ".x...xxx.x.xxxx.x...x.x..xxx....xx.xxxx..", "x..xxx...x.xxxx..xx..x..xx.xx..", "..xx..x.xxx...xx...xx..xx.xx.", "xx..x..xxxx..xx.xxx....x..", "xx..xx....xxxx.x..x.x.."]
}
]
},
{
// KH Pattern
name: "Lorenz SZ40: KH pattern, plain text, all 1s",
input: "HELLO WORLD, THIS IS A TEST MESSAGE.",
expectedOutput: "VIC3TS/CUJA/3II9W9JWDI5DAFXT4SOIF3999IZD9T",
recipeConfig: [
{
"op": "Lorenz",
"args": ["SZ40", "KH Pattern", false, "Send", "Plaintext", "Plaintext", "5/8/9", 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ".x...xx.x.x..xxx.x.x.xxxx.x.x.x.x.x..x.xx.x", ".xx.x.xxx..x.x.x..x.xx.x.xxx.x....x.xx.x.x.x..x", ".x.x.x..xxx....x.x.xx.x.x.x..xxx.x.x..x.x.xx..x.x.x", ".xx...xxxxx.x.x.xx...x.xx.x.x..x.x.xx.x..x.x.x.x.x.x.", "xx...xx.x..x.xx.x...x.x.x.x.x.x.x.x.xx..xxxx.x.x...xx.x..x.", "x.x.x.x.x.x...x.x.x...x.x.x...x.x....", ".xxxx.xxxx.xxx.xxxx.xx....xxx.xxxx.xxxx.xxxx.xxxx.xxx.xxxx...", ".x...xxx.x.xxxx.x...x.x..xxx....xx.xxxx..", "x..xxx...x.xxxx..xx..x..xx.xx..", "..xx..x.xxx...xx...xx..xx.xx.", "xx..x..xxxx..xx.xxx....x..", "xx..xx....xxxx.x..x.x.."]
}
]
},
{
// KH Pattern, Random Start
name: "Lorenz SZ40: KH pattern, plain text, random start",
input: "HELLO WORLD, THIS IS A TEST MESSAGE.",
expectedOutput: "KGZP5ONYCHNNOXS9SN45MIE3SC3DJBZVJUOE5SLVGI",
recipeConfig: [
{
"op": "Lorenz",
"args": ["SZ40", "KH Pattern", false, "Send", "Plaintext", "Plaintext", "5/8/9", 20, 40, 3, 9, 27, 36, 4, 1, 9, 14, 21, 8, ".x...xx.x.x..xxx.x.x.xxxx.x.x.x.x.x..x.xx.x", ".xx.x.xxx..x.x.x..x.xx.x.xxx.x....x.xx.x.x.x..x", ".x.x.x..xxx....x.x.xx.x.x.x..xxx.x.x..x.x.xx..x.x.x", ".xx...xxxxx.x.x.xx...x.xx.x.x..x.x.xx.x..x.x.x.x.x.x.", "xx...xx.x..x.xx.x...x.x.x.x.x.x.x.x.xx..xxxx.x.x...xx.x..x.", "x.x.x.x.x.x...x.x.x...x.x.x...x.x....", ".xxxx.xxxx.xxx.xxxx.xx....xxx.xxxx.xxxx.xxxx.xxxx.xxx.xxxx...", ".x...xxx.x.xxxx.x...x.x..xxx....xx.xxxx..", "x..xxx...x.xxxx..xx..x..xx.xx..", "..xx..x.xxx...xx...xx..xx.xx.", "xx..x..xxxx..xx.xxx....x..", "xx..xx....xxxx.x..x.x.."]
}
]
},
{
// ZMUG Pattern, Random Start
name: "Lorenz SZ40: ZMUG pattern, plain text, random start",
input: "HELLO WORLD, THIS IS A TEST MESSAGE.",
expectedOutput: "IQVPAANDCA3CHDNO3V/CZQ/BTPZIKW8YAAQXQGLDMV",
recipeConfig: [
{
"op": "Lorenz",
"args": ["SZ40", "ZMUG Pattern", false, "Send", "Plaintext", "Plaintext", "5/8/9", 20, 40, 3, 9, 27, 36, 4, 1, 9, 14, 21, 8, ".x...xx.x.x..xxx.x.x.xxxx.x.x.x.x.x..x.xx.x", ".xx.x.xxx..x.x.x..x.xx.x.xxx.x....x.xx.x.x.x..x", ".x.x.x..xxx....x.x.xx.x.x.x..xxx.x.x..x.x.xx..x.x.x", ".xx...xxxxx.x.x.xx...x.xx.x.x..x.x.xx.x..x.x.x.x.x.x.", "xx...xx.x..x.xx.x...x.x.x.x.x.x.x.x.xx..xxxx.x.x...xx.x..x.", "x.x.x.x.x.x...x.x.x...x.x.x...x.x....", ".xxxx.xxxx.xxx.xxxx.xx....xxx.xxxx.xxxx.xxxx.xxxx.xxx.xxxx...", ".x...xxx.x.xxxx.x...x.x..xxx....xx.xxxx..", "x..xxx...x.xxxx..xx..x..xx.xx..", "..xx..x.xxx...xx...xx..xx.xx.", "xx..x..xxxx..xx.xxx....x..", "xx..xx....xxxx.x..x.x.."]
}
]
},
{
// Bream Pattern, Random Start
name: "Lorenz SZ40: Bream pattern, plain text, random start",
input: "HELLO WORLD, THIS IS A TEST MESSAGE.",
expectedOutput: "/89OALRPJEZQGOO84WOEQZ/I9NBRZOQPBTANC8E/GK",
recipeConfig: [
{
"op": "Lorenz",
"args": ["SZ40", "BREAM Pattern", false, "Send", "Plaintext", "Plaintext", "5/8/9", 20, 40, 3, 9, 27, 36, 4, 1, 9, 14, 21, 8, ".x...xx.x.x..xxx.x.x.xxxx.x.x.x.x.x..x.xx.x", ".xx.x.xxx..x.x.x..x.xx.x.xxx.x....x.xx.x.x.x..x", ".x.x.x..xxx....x.x.xx.x.x.x..xxx.x.x..x.x.xx..x.x.x", ".xx...xxxxx.x.x.xx...x.xx.x.x..x.x.xx.x..x.x.x.x.x.x.", "xx...xx.x..x.xx.x...x.x.x.x.x.x.x.x.xx..xxxx.x.x...xx.x..x.", "x.x.x.x.x.x...x.x.x...x.x.x...x.x....", ".xxxx.xxxx.xxx.xxxx.xx....xxx.xxxx.xxxx.xxxx.xxxx.xxx.xxxx...", ".x...xxx.x.xxxx.x...x.x..xxx....xx.xxxx..", "x..xxx...x.xxxx..xx..x..xx.xx..", "..xx..x.xxx...xx...xx..xx.xx.", "xx..x..xxxx..xx.xxx....x..", "xx..xx....xxxx.x..x.x.."]
}
]
},
{
// KH Pattern, all 1s
name: "Lorenz SZ42a: KH pattern, plain text, all 1s",
input: "HELLO WORLD, THIS IS A TEST MESSAGE.",
expectedOutput: "VIC3TS/ZOHUYXWLTUXPV9ZNOTW9IXJPFDLIBB5ZD9K",
recipeConfig: [
{
"op": "Lorenz",
"args": ["SZ42a", "KH Pattern", false, "Send", "Plaintext", "Plaintext", "5/8/9", 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ".x...xx.x.x..xxx.x.x.xxxx.x.x.x.x.x..x.xx.x", ".xx.x.xxx..x.x.x..x.xx.x.xxx.x....x.xx.x.x.x..x", ".x.x.x..xxx....x.x.xx.x.x.x..xxx.x.x..x.x.xx..x.x.x", ".xx...xxxxx.x.x.xx...x.xx.x.x..x.x.xx.x..x.x.x.x.x.x.", "xx...xx.x..x.xx.x...x.x.x.x.x.x.x.x.xx..xxxx.x.x...xx.x..x.", "x.x.x.x.x.x...x.x.x...x.x.x...x.x....", ".xxxx.xxxx.xxx.xxxx.xx....xxx.xxxx.xxxx.xxxx.xxxx.xxx.xxxx...", ".x...xxx.x.xxxx.x...x.x..xxx....xx.xxxx..", "x..xxx...x.xxxx..xx..x..xx.xx..", "..xx..x.xxx...xx...xx..xx.xx.", "xx..x..xxxx..xx.xxx....x..", "xx..xx....xxxx.x..x.x.."]
}
]
},
{
// KH Pattern, Full Test on real message
name: "Lorenz SZ42a: Receive, KH pattern, ITA2 output",
input: "J3KF+LXT/.+YTMLE/RFVC-SE///4GYX3Q.Z3GVWKWDVAPURPYL/.UYAI.EOW3ZBVVAQRTO/PACJ.NLVLZYYNTU.IDCPKTEZOSWCOBNWFJ+UAKE+WU-JMWYWLXRM+M/HV+TVTC-FOGN3QZG4J.VLM/KK+OVC/YIWTSZUDTSY+3LCCHZADQ-3VBXKEOCSO/+ZBFN34-F.+4UVFVLIP4KFGRBFIVFFJX/FKFSHJ.VUJVWXE+LFAICDYX3EZD33U+GSOGXPAXHTJSNUQI+PXS3JRG+-U+YZITF/SM4LIDPSYMVJM/BL/YHDGBG/UI+EM.JEMX.YQNUWTLAUCLUSDMZGXCQ3CPPCCYLTJC4KXB--G4VGQ4J.EYTEVSG33DVLVPDGNOGAJOUWGFY4KGO-4+IRKDPGDHGBQLFSS/YDP/FM-/BANLERZEMT.U3XZA43RGYD+-J4VYRTONRYF/OI4Y+I3LXUFAHGRT.RXCO3HKCQIML.VHVIGHBWBTU3RZFN.J.WGNLSGLYBJT+TPM-RHHMXTNDSVUO3W/4ORZ4UY.LA-XZYVLCZROMPM3RYSLUD-SNQQA+RK/UV4K/GOSSMJRGIZYPO+BEEB+OEWAWKYXW.-NKUQERUM-PA4WFNKU-Q-LNC.D-A3C.FB.RFOGZHUWTEAYB3HNHCEW.N33QEEVUEC3OOR4BRNLH/IF3+DJJ3S3J4XA+Z3SMT/K4L-IDLQWCLMQ3TO3PNYVCGZCXUMSSBH.BWMGGTIYSC/UBX/PE+3IZZ.Z/CCWLSL+4/4+IET/ELBCBDAM4ELKDAGB3O.3J+IEQQJ.U.VSAQSAYZAU+3YOZWPPPV/YOVOE/P/E4UOZYK4PE3A.ETZGFBCZE.4WA3PSDR3XMLJLH+S3UWOA.T-RID-MA.CVZGLNYK4U.HBPSA+3U+BLSGS/FNRXMOMEBBABIPOAGDWA-4T/B.L.HDSAJE.HE-4FZW+SDBAYCNBTEODDALCMIG-QNM+-PEFC+ABNQ-MVT3-GHKAN/ENZLPMJRVRB+4NBCRTFDVNLRTPIGIEZGSPUXMW3WJQTOEV+WA-HJZLX-JQID-X++FFGKCTO.3.F+JIISVTXKC+..YM/SOQUIAS-IAGJJPRYLLT.EJBJAMRP+MS-ZRUVLBBE-UNYQGBBHEB+QCHYYHVN.NHKS-YG3BNZKQJBO-FQ.SZB/JRFILGUZUZVCOVGULEKU4/HRBGYIZVLCM3/ONJ-OBIRSCT+IZCB-TTZMDQWQUCIVTGTTYNEOTTORM-FSKS3WJWL/ZXOCOCYGC.BRIRKXK.FLJUSP/-G.WP.MMVHBYREWQZZAN/BKSEYDBGXAUV+NUKUKIKIGS+VO-4EY/GWI+SGJOJCBYGGMY4+/EMGULCSC-Y+CXLIECYC-+-ZXHSPOTFGFDWIFT-4XXDDLMMKT433WH/BX-OILWDJC/FFE-ZYH3C4GI4T/3KUJQ4YNBQWXWB-RM.Q3GG/4Z-AIGW4GYYEBXRJHXQA..-.G/3W/-LVS+4GS-+FRYIOFYGUK-FEYA4J-ZB-MSPAM/WLLJ3GFMJP/GGF-C+O-KQ.K4PWVL+3O.LX4TUD+Y+QOO3GTJT+.MR-4JSRXD-X4SCIDIVLCDEGSOZOGWXQZOZ.3PPQ4ZYXKL+QETCM/3/--CHG4+W.BNHTB+Z-NZCO+QEB+-/FNJ+NSHTO+CW.CM/VHIM-S.3VAFDJ3MEH.G+NQFDCUSK+MCKDLEC-TFWSYBQSWE4UOQOXY-E.ESE4OLJQOBUQZUSLRWV-AVOYX3CKS3ZFUAQAWESYMXQV/4MOXORAVKOIELRXCSRAEU/KEFDQWQ-BWEXGALS/.JLQ/CEKT-4C+TWDNGST-UQ-ERBP.YZ-ZH/Q3ITMN-O3P/JBEVZUOY4CTNY4PKCB3YIW/+BOKDEZE.VCTROQDTAXI3VKGYQVOKSCXPDDAD4DLTELK.GDDLTRPXORSFTDOGB.-NQJHNM/4/JOTIVGOQF+FC.GDX4DMT.UBRVUIBCHGLDBZSFSICVVAF4TN.BMAP-IQR-LBCQ/TTHH",
expectedOutput: "XWOLLE9WI9R99AUCH9BLEIBEN955Z88KR99GWFRL5X89FUES959WPYP9QXT9QIPQ9V9AACQEM9959AA899QEE9959AA8999AN99OB5M89SUEDW/ST5V9AA8GEHEIME9KOMMANDOSACHE5AA89959AA89NUR9ZUR9PERSOENLICHENSINTERRICHTUNG5N889WEITERGABE9VERBOTEN5MA9AA8LAGEBERICHT9VOM99GSEPMM98NN99VOM9959EPMRM9QORT9AA889KATEN9NN9KAT9NN9KARTEN9959Q9C9QSVPP9PPP9A9MA98889ROEM959QM89WESTEN9959C899AOK999L9U9C88889ROEMS59QWM89A5M89K5MCMA989PANZERUNTERSTUEZ9NN9PANZSRUNTERSTUETZTESFEINDANGRIFFE99GEGEN9EIGENE9STUETZPU9NKTFRONT9NAHMEN9O4D9ELSTER5N89SOHL5N89RAU9NN9RAU9N9UND9BAD9BRAMBACH95K9WR8889NN9995KWT88SKM9BFO9HOF5LM89NEUE9STUETZPUNKTFRONT9B99DIESER9ORT5M89UEBRIGE9CORPSFRONT9BEIDERSEITIGE9AUFKLAERUNGSTAETIGKEI5M9DIESER9ORT5M89I/BRIGE9KORPSFRONT9BEIDERSEITIGE9AUFKLAERUNGSTAETIGKEI5MA99A8STELWV5M89ROEM959QEM89A5M8K5MMA989ZUNEHMENDER9FEINDDRUCK9IM9RAUXSN9UND99W99BAERNAU95K9T889NN9959KWT889KM9SW9MARIENBAD5LM889FEINDAFGRIF9F99VON99SO99GEGEN9PAULUSBRUNN5M899LAGE9DORT9UNGEKL4ERT5M89SCHWACHE99EIGENEN9SICHERUNGEN9DURCH9FEIND9AUS99SCHAENWAWDE9UND9WOSANT995K9Y89KM9SO99TACHAU5L89NACH9O99ZURUECKGEWOFNN9TURUEIKGEWORFEN5M89FEIND99MIT9INF9UND9PZ5M89IN9PEISSIGKAU9UND9WLAD9NS9DAHENTEN5M89EIGENE9SICHERANGEN9IN9MOLGAU959A89DRI9UND9WLAD9N993AHENTEN5M89EIGENE9SIC4ERUNGENSIGKAU9UND9WLAD9N99DAHENTEN5M89EUGENE9SICHERUNGEN9IN9MOLGAU959A89DRISSGLOBEN959A89WURKAU5M89IM9A9SNN9IM9RAUM99TAUS99PANZERUNTERSTUETZTE99FEINDANGRIFFE5MA99AA899A5X8O5M8K5M99QC9MA9989UEBER9ISAR9MIT9INF9UND9PZ5M89UEBERBESETZTEJ9FEIND9STIESZ99UEBER9S9NN9UEBER99VILSA9BSCHNITT9VOR9UND9NAHXS9AUNKIRCHEN959A89ALDERSBACH959A89EGGERSDORF995KWP889KM9W9P49SAU5LMA9A88ROEM9959IWM89A5MLK5MCMA989DWP889KM9W9PASSAU5LMASA88ROEM9959IWM89A5MLK5MCMA989DER9ZWISCHEN9PLATTLING9UND9LANDAI9FU9NN3/UF99BREITER9FRONT99UEBER9DIE9ISAR99UEBERB99NNN9UEBER5ESETZTE99FEIND9DRUECKTE9EIGENEN9LINIE5N89TROTZ9HIFTIGEN9WIDERST4F3ES5N89AUN9VISLABSCHNITT9ZUREUCK585M89FEINDPANZER9N9NN9IN9ARTOFJFN9IN9ARNTORF959KQT889KM9SO9LANDAU5B89UND99N9ROTTESDORF599IN9ARNZORZ959KQT889KM9SO9LANDAU5L89UND99N9ROTTESDORF59KI89KM9S9LANDAUGWMA59A89ROEM959QEM8939NN9959A899ROEM9959QK4OLE",
recipeConfig: [
{
"op": "Lorenz",
"args": ["SZ42a", "KH Pattern", false, "Receive", "Plaintext", "ITA2", "5/8/9", 12, 12, 41, 45, 17, 12, 3, 11, 31, 29, 12, 23, ".x...xx.x.x..xxx.x.x.xxxx.x.x.x.x.x..x.xx.x", ".xx.x.xxx..x.x.x..x.xx.x.xxx.x....x.xx.x.x.x..x", ".x.x.x..xxx....x.x.xx.x.x.x..xxx.x.x..x.x.xx..x.x.x", ".xx...xxxxx.x.x.xx...x.xx.x.x..x.x.xx.x..x.x.x.x.x.x.", "xx...xx.x..x.xx.x...x.x.x.x.x.x.x.x.xx..xxxx.x.x...xx.x..x.", "x.x.x.x.x.x...x.x.x...x.x.x...x.x....", ".xxxx.xxxx.xxx.xxxx.xx....xxx.xxxx.xxxx.xxxx.xxxx.xxx.xxxx...", ".x...xxx.x.xxxx.x...x.x..xxx....xx.xxxx..", "x..xxx...x.xxxx..xx..x..xx.xx..", "..xx..x.xxx...xx...xx..xx.xx.", "xx..x..xxxx..xx.xxx....x..", "xx..xx....xxxx.x..x.x.."]
}
]
},
{
// ZMUG Pattern, Full Test, Receive
name: "Lorenz SZ42b: Receive, ZMUG pattern, KT-Schalte, Plaintext output",
input: "YQPLQQX4OJGFOKBXROZVPBVIJOXSMQSMTMHX8VSBBMIHKJTYKR4ANTQRPCJXR3YE8KVLDN8SQN4VCJQUW3BB4HWEXRD4LUJNF99DV5FLQ4IRANWRCLYX//J8YSIWO44LCPTCBKX4TZGBPYHCE/FBJ4DSBFF5YLOVPBSRUDQULTTO9BYLLUCRGTM/VXQCS8XUDLY/5O3TPSYFQ89RQRGG/IEOKULB8MHQQBHIWRW38W5XSPT9YF8WJGN3HMEBY8XKQW/3BC888Q3JC/K8SOXJWONNQCM8Z4UQQQGE8RL3GXZ3YI4O/RBCF5JXJE5W5GJAT9/9XP9V8SFZLKUBUPD4HXABGLB8D3E4YTERP3GGISVNYHOL3BQVJUOFEBZMYHBKFGPWEOGGMFGF/EVGWT584T8BMURIBSIBELCANKT/VXHUHONHFPJ/OBCQGCQPFQSQW3GEFCQKY9Z4/KVIQJPJQ4ZQJZP/PEIHQG4H99B58HD5/XCLRBPXMR8P84CMHO5RYODKY94NINO4OGY8TOF9BD9EPD5U3P9KMJ/WBXX9CO9SHMK5KHQFA9BE35R4OSAPCAXZ9SALUKVPVVYB8MGGK3XSVLKGUT/8JVIF5DSDUQT3ZKZTICJTSGXVZAZ4WWGAMOFWUN94OZR4Y8AVLGZHOV/UHCURM5RQPKDCEMRBWLKYLTTGGE8ZIVP4HJMVW5HWKOHRZ4OIUL5OZJOVHL9AQUZA93F3H9QNS5VZYZXUM8AD3RZC9CQ5B//4J8/B35XVB9MHMYQSVQPFWSXWEDU5NHXBSO/W/NBW3V/KO5VHIZQRZOKIJSV4G9Y/H3FIYLBH5/XA3AYRPUREKAQL5WTXJ4EK3EAYQ8GIDXTBXMUFUGKZHZZZPYAQMQOXZAGKP4SPIEIKVUPVPRVRSXSDRJSS3XM5KOTUVK3O435VB93H4HB8IEXHDGCJ3VHPG48VZKB4GHRNFHDQ8LN4P9TI3VD9//LACSHQJZWK5/WLC5/PHN5JTVWAOXWX59/SIZ4ADMXO5GCMYSPNLR33CFLKGSN/ZYCFAR5I4/ZQRWCVGY9GCAA5GJCW55HXVGAKGZG/V9Q9AGB9WAVKJX9DM/FOCHWZXAVEPMKTSQJYPWCYFTH3WXZRVAFCLHFMFQUGUWDHQQSUF/QSPSY/8PWPU9B8WUXFE5IPYCSYX3FKEGXIY8DCNLOWZTU8N98ZNWL8QDP/JHTU5YNHN8OI8TMBBIUQEOVT4S/N9V//LZCQ5LN3X43LUG/KDVSOXUTKOP5VTI/OUV98ULIJW9EBVUMBYBLOIKJX/XUHHYPB/N3PEVBFJGXGO3H8VTIO9D8IV5FAL5DZDOC88WNITD/CEZOB3IS8W//ZIBFQOMG3HNUXV3YMM5QH8YYPV/EJMUCKSNRTGFHBZJFTX59CMRM/D5GVFWHF8QWPY44IKNLH8A9SMHYUNXGDJBX9PA4CJPRO4RZSPTG4SYBLHMSV/9UJPUJEPHPZWSDKMMMN/WEHOZDXBPWS3DHG9SBWFTB85HOPZYTVZ9KSBGZ8PAIGGIVXU/8YIFQGQDDDVDDV3TL8L5G9C/98CYDUGWWCGQCQLS4Y8BGSSMYLOODGA/YMRWI9LJI8TXT3ZYZ8NR/3RNDYHR9DINKB//HWPJETJ8/RFXSV/SKWEBKOMSJ9W393JH8E/G3UX/5CD35H4BZOU8GYELU4EUYNYP/UUBYQZKLIPFPOPZ8WNJ4WR5QWIZVMQ9BCVZM3MB8BES5APTTVTBSILLUQHY9X/A9FFQWR5DUMNHPUKVZDYB38ZSI3CNCZPG9C/UKYRX5YWXEIBIMCBNRPGGCZKHLNG4T/R5K4LSBZUVNGBCHPI/JUIZ/IMFXEE4KYSEMYBPWBZ/UCANCY4MPXFQB3NRZQOSLBOMD9TP3IY8RQWIEG9HG3CH8AI/GGPGLXNNV4Q/ZOMVCVS4UCQFFEMMWK/RSV8RXQQPSOT8GYAUXOUJQ9VQCHAS4FL3WAMQXARHYNEPYS5TR3/MHCUSPE33NWZ48X3J9HWEJGIKOTLKAJXXAQ5X3YVLGNSSM3XT/9E/PBTN5PHCJLWKICIHER/QQMVGAGCVTKBUL3B3GQUKLKZ38YMOOJ5DTAFZSFZLVO4UZXGNNR4SJ3JFMLKDP3MXSZXX3YVLGXF3O8H5JHBZFTOZ4JDTLQGHLD5XOBLVQI/MQXS4EJAIU/VLYIGGJWNOTTF9AEQSEEGT84GI355YLVTTDGVICR8ACXJFHPTHRG8UXCLIHMW4Z3CUV89YLL3W3HDC5HUUDJ/PUS54PIJ98IXL3SEEOWWPGFN9O9ICPG4K8558ONZOHSW/U4ZRSC4C3UOHHIEARXSCZDZM4IBDBLRI99DEKKIAYPJSOSC59XGUVKSPHV9FRE35A5SII3G3DRQDQKTSC9DNUPBXVD3ORPX9NM3BK3PB5PIWUZKNCL4I4IWVO4FE4GCZBHSZWN3GS88G884DUFDUFE9RJEEKM3AJHNSEANJWQMRP5DUXHEKDWAAQGZYUL3EXY4ALN4NR3SF5CFOTZ9FGNJDFQEZU4TTVORUVS5WIZBQLZQF5HD4TTYIRPAZDNPCIYS93ZY5QQEBTYIYCQ4AJGK83BFOIK9S5GAJCBYLKSDADHOS4/XVSHDYBFSO3FZIHHHWSJ5L4R33KCXOW8T9KFQ4C8UCOCOCKXU8JJ5R9JL88UAJQ4HXWDBQ45JGY/AYGP8PMGWWLFM/9SP5OHR3FQKDIYIAOLKWM8OT8JO4W9ET5LIZMMNJBNN/A999JNG3ALKLKEK/HWZJUC5PLAILQJ8MCOO8T3X98H4ZKFIKYUKDI4ODART/K4JZDHMBY4X/BDKOYRJ/CQKZCFFBY3494/DUFHLVYZL5VG35KFSVC9IXI4S3RB3FXBDCYYKVUUTBTEFNJVRB3H5BU9NGUGJ3FBD9OOXWRTUZ8GHAHKPNL5TTUHNGMARBKFQMKFN4ODB4Y8OKCJPFQNHIGK8WFYOHI/ZW/PMHF4JAFIAYNNPOYJY/AFTDSOPNGP8GK94X3QY4A/THAWWGH3LSRST4/AV8GY4QV53A5MRYF3K3MWK5YJAWLLYWV9U/CZN4WAV3OELTO45G5IEY4P845ZJJAYGTBHXBFE5XJ5C5FFUFXCOUSWTU/LSSQ/VWNP9BSOLUB5PLNWAZF4O8LKGTA9ZAAVRIW8CP3UFS5I5N/MNMVCRD/3AM/XUPGMJAM45AY4VDA5XY4F8ZV4NXZMPZROZ/QFPLOQ/3WSZ8/FXEJEFC9W3UJGOO4RL9FEVQL/DYDAK8JLMVPY9IPYXBX3WIYOLYB5VDUAJBKCINPZZ5843H/8ZIZCVQ4RTVCOTSATJC4ZVBXYROCDXRIPGH5/WS83Y4TAA45YBPNGFFSY3I/O3JIKWMAS9TYTY38JMIEREZWOYWT3ZYRA84IRDX93H3JJQSFL43JOLPPX3UDF59RL3ESVR8J83QKTJLSJAEQOBZ8FCLWIRBXOUXQOKQ/AE885X/VQIUFETMEUC48CJMKQIJQ9ZVPHOJMCIR93GTVYWMIYMPOWFWOL99NRTWQAQ3WKLF//F3VDQDS8HLLDRKESD89OU9PSPIXW5/TX35KZUONYTLQKMGRWTSV3/5/BJZV9MHPL5UZR4ZMJZEXUE8F8E3RVDEDGVQWENRFYBOEKQMBILPWUFXZQB9XGYOSZKS8IRL9VMH5DWE3WHY3FRR83I55XUXHBJ5BMAPOHIGHQIZ/RSSAK83AUEW4Q5DZ9WTDKRMLT9OYH/VZGXUMEOV/4PL3P/SSIHX3UQIVDVQKZWHYQGZO9NLMPRSJV8/G5FTKLJ8FSKRAOZ/FZCRJLBRIBTJPGUDLFGYBXBVMJQQA3MSHFDZE/HRUOUGYZJNNWARNXNYKAWYQQWMES8K4UCFEGHDPYD/NK/U/B84NI54QLJWW/8NTWPOS/ENS355GHATHAFKK4ONFQR/WHNY3IQTTCBWF35XYXLSOXV5AIZBIGDNFDHL5OO4H/3SJBJBPTQ/3WAAO9ZGW9GYP8/JKVZKK/O9VEMBDKIJYMMVCGODXZY3QNUB8EOWKXS3HT9OFV5JJCDC9FE3FUZJOHL4HH4PA9YFA5TI5ZHFPG/RXQ/5ZMGNSTHWZC4ZC9JA8JNHKT/HNE8CLU9QF385/HDJAEEGSKGPFRKDHEPAXDH9M8Q8KQKEGYWDI9ERQGWMDPZYS/WS9PRP3/3MUKLQIKR5V4GYHNQWTB/SZM9VPQSJZLLKIF5WC5EHTILCZ95RMOJZ89LPJMPRNZ4ERL8HXZIL5B9KEBFN4YJ4LNEQOSS5ILTYECXG/MY9MRQWHFM8QFLI8CAG3BUUG53XPH4CE8GUQKZBKLNAGWXORPFZR3V9XTLBBATUTFUPC/ULGGWLFMCSP8KUYIFXTZ8V4HUQLS9MKYMJMLF/94U3PNELHVWRMISI9QYL53O5XDSFP84VOOAYCKJE4HPG3GA8MGGZVMSBMT5KWQ9V88USEMD3T8IYMIYFENMRZURQLNCICODEG/ZW4HNTOKZMC//ZGQL/XBC8STG3RXKMCO9NSVQQ8QDFDZWNIAENP/J898ADWNHCDCIO5XT8PR4BCDDAQEJV4LGLRALWU5YUL5GBDH//4TQJHBP8JWWMVBV89E/VMRUCLXGKABKSXK5KXWF9NIZB/ADKX38LTZIUBBMWIMMNZXO/EKXEGZBQZD8CYXXRVVF3/NIDWVFYU99H5KJ9DE55N59LRTPLL9PAKPPLSRC38SEUGYSUG5GRTV/5WIDY9YBNDIS4QEBELA/4QVPMVWZG3R9HSE/ZXYK8GGHQ5WVDSYI4RZTBYMUL8QLMPB4P43Y9R3PAWWZRFNNIEXPL83DVJWL3YDG/OJ9UN5CS/L3LDTGMVHMFKZE/BD4MVKJTWFXWPR4KJXYUGIZBZZMTH/JM3MIWOV/ETI5NNOUSLUYL89G3X/TPHC3A/CTNT5HM4CX5PQDMKRSLAOFGPNVRFSE/HDZFE8LFIY Line truncated
expectedOutput: "IF I SAID BLETCHLEY PARK, ENIGMA AND ALAN TURING, I WOULD THINK MANY OF YOU WOULD KNOW A LITTLE ABOUT THEM, THANKS TO THE WORK OF BOTH BLETCHLEY PARK AND RECENT FILMS SUCH AS THE IMITATION GAME. NOW, WHAT ABOUT IF I SAID COLOSSUS, TOMMY FLOWERS AND BILL TUTTE? I SUSPECT THAT VERY FEW PEOPLE, EVEN IN THE LOCAL AREA AROUND BLETCHLEY PARK AND MILTON KEYNES, WOULD BE FAMILIAR WITH THESE NAMES. COLOSSUS IS, ARGUABLY, THE WORLDS FIRST ELECTRONIC COMPUTER EVER BUILT AND ITS STORY IS EVEN MORE AMAZING THAN ENIGMA, BUT IT HAS RECEIVED SIGNIFICANTLY LESS PUBLIC RECOGNITION. MANY PEOPLE WHO HAVE HEARD OF COLOSSUS BELIEVE THAT IT IS SOMETHING TO DO WITH ENIGMA, BUT THIS IS NOT THE CASE IN FACT, IT WAS BUILT TO CRACK A HARDER AND MORE SECRETIVE DEVICE BUILT BY THE LORENZ COMPANY IN GERMANY. ADOLF HITLER, REALISING THE REQUIREMENT FOR FAST AND SECURE COMMUNICATION BETWEEN HIS HIGH COMMAND AND GENERALS IN THE FIELD, ORDERED A FORMIDABLE CIPHER ATTACHMENT WHICH COULD SEND AND RECEIVE ENCODED MESSAGES AT A MUCH HIGHER RATE THAN ENIGMA. THEY BUILT A MACHINE WHICH, RATHER THAN HAVING THREE OR FOUR WHEELS LIKE ENIGMA, HAD TWELVE WHEELS, EACH OF WHICH COULD HAVE ITS SETTINGS ALTERED TO MAKE DECIPHERING THE COMMUNICATIONS EXTREMELY DIFFICULT, IF NOT (THEY HOPED) IMPOSSIBLE. IN 1940, BLETCHLEY PARK STARTED PICKING UP NEW TRANSMISSIONS, BUT NOBODY KNEW WHAT WAS ENCIPHERING THE CODES. THESE TRANSMISSIONS WERE RECORDED AND MANUALLY TRANSCRIBED ONTO PUNCHED TAPE AND SENT ON TO BLETCHLEY PARK. FINALLY, ON 30TH AUGUST 1941, A BREAKTHROUGH WAS MADE A GERMAN OPERATOR MANUALLY TYPED OUT AND TRANSMITTED A 4000 CHARACTER ENCODED MESSAGE. UNFORTUNATELY FOR HIM, THE RECEIVING END REPLIED SORRY, SEND IT AGAIN. IT WAS STRICTLY FORBIDDEN TO SEND TWO MESSAGES WITH THE SAME SETTINGS, BUT BEING ANNOYED AT HAVING TO TYPE THIS OUT AGAIN, HE DID JUST THAT AND STARTED TYPING AGAIN. TO SAVE TIME THOUGH, HE SHORTENED SOME OF THE WORDS (JUST LIKE WE WOULD TYPE NO RATHER THAN NUMBER) BUT DOING THIS MEANT THAT BLETCHLEY PARK HAD TWO MESSAGES, BOTH SENT WITH THE SAME KEY GENERATED BY THE MACHINE BUT WITH DIFFERENT ORIGINAL TEXTS. BRIGADIER JOHN TILTMAN, A SENIOR CODE BREAKER, WORKED HARD FOR TEN DAYS AND MANAGED TO SUCCESSFULLY SPLIT THESE MESSAGES BACK INTO GERMAN. MORE IMPORTANTLY, HE ALSO WORKED OUT THE ORIGINAL KEY STRING WHICH WAS GENERATED BY THIS NEW UNKNOWN MACHINE. VERY LITTLE PROGRESS WAS MADE TO CRACK THIS CODE, UNTIL THE KEY AND MESSAGES ENDED UP ON THE DESK OF A NEW MATHEMATICIAN BY THE NAME OF BILL TUTTE, WHO HAD JUST RECENTLY JOINED BLETCHLEY PARK. AFTER WEEKS OF PAINSTAKING MANUAL WORK WITH PAPER AND PENCIL, DRAWING OUT GRIDS OF DOTS AND CROSSES, HE FINALLY DISCOVERED A REPEATING PATTERN USING ROWS OF 41. HE CORRECTLY REALISED THIS WAS HOW MANY POSITIONS THE FIRST OF THE ENCODING WHEELS MUST HAVE IN THE UNKNOWN MACHINE. FROM THIS BREAK, WITH THE ASSISTANCE OF OTHER CODEBREAKERS, HE MANAGED TO SUCCESSFULLY RECREATE THE WORKINGS OF THE WHOLE MACHINE. REMEMBER, THIS WAS WITHOUT EVER SEEING THE LORENZ WHICH WAS AN ASTOUNDING PIECE OF WORK. BILL TUTTE, WHOSE CENTENARY WILL BE CELEBRATED IN MAY THIS YEAR, DID FURTHER WORK ON METHODS WHICH COULD POTENTIALLY BREAK INTO AN ENCODED MESSAGE, BUT IT INVOLVED A HUGE AMOUNT OF MANUAL EFFORT TO COUNT RESULTS FROM ALL SETTINGS UNTIL THE CORRECT ONE WAS FOUND. MAX NEWMAN MANAGED THE CONSTRUCTION OF A MACHINE TO USE TUTTES CALCULATIONS, WHICH WAS NICKNAMED HEATH ROBINSON, BUT IT WAS, UNFORTUNATELY, RELATIVELY SLOW AND UNRELIABLE. THEY INVITED, TOMMY FLOWERS, FROM THE POST OFFICE RESEARCH STATION IN DOLLIS HILL TO SEE IF HE COULD IMPROVE THE MACHINE. TOMMY FLOWERS CAME BACK TO THEM WITH A PLAN TO BUILD A NEW MACHINE USING 1500 THERMIONIC VALVES. VALVES AT THIS TIME WERE BELIEVED TO BE UNRELIABLE AND REQUIRE REGULAR REPLACEMENT, BUT TOMMY FLOWERS KNEW FROM HIS RESEARCH THAT IF NOT SWITCHED OFF, THEY WORKED PERFECTLY. WHILE BLETCHLEY PARK INITIALLY REFUSED, FLOWERS RETURNED TO DOLLIS HILL AND PERSUADED HIS SUPERIORS TO CONTINUE TO BUILD THIS MACHINE. IN JANUARY 1944, THE FIRST COLOSSUS WAS DELIVERED TO BLETCHLEY PARK, AND BY FEBRUARY WAS RUNNING SUCCESSFULLY AND RELIABLY FIRST TIME, MUCH TO EVERYONES ASTONISHMENT THEY QUICKLY PLACED ORDERS FOR AS MANY AS POSSIBLE, FLOWERS ALREADY HAVING STARTED WORKING ON A FASTER MARK 2. A FURTHER NINE COLOSSUS COMPUTERS WERE DELIVERED TO BLETCHLEY PARK BY THE END OF THE WAR (APPROXIMATELY ONE PER MONTH) AND THEY HELPED BREAK AN AMAZING 63 MILLION CHARACTERS, SHORTENING THE CONFLICT AND SAVING MANY LIVES. AFTER THE WAR, CHURCHILL ORDERED THE DISMANTLING OF ALL BUT TWO OF THE MACHINES AND THEIR EXISTENCE WAS KEPT SECRET FOR THIRTY YEARS. TONY SALE, AN ELECTRONIC ENGINEER WORKING AS SENIOR CURATOR AT THE SCIENCE MUSEUM, ALONG WITH SEVERAL COLLEAGUES STARTED, IN 1991, THE CAMPAIGN TO SAVE BLETCHLEY PARK FROM PROPERTY DEVELOPERS. HE ALSO BEGAN GATHERING INFORMATION ABOUT COLOSSUS. BY 1993, HE HAD RECOVERED EIGHT PHOTOGRAPHS FROM 1945, PLUS SOMELine truncated
recipeConfig: [
{
"op": "Lorenz",
"args": ["SZ42b", "ZMUG Pattern", true, "Receive", "Plaintext", "Plaintext", "5/8/9", 32, 28, 24, 11, 44, 6, 50, 34, 12, 18, 18, 9, ".x...xx.x.x..xxx.x.x.xxxx.x.x.x.x.x..x.xx.x", ".xx.x.xxx..x.x.x..x.xx.x.xxx.x....x.xx.x.x.x..x", ".x.x.x..xxx....x.x.xx.x.x.x..xxx.x.x..x.x.xx..x.x.x", ".xx...xxxxx.x.x.xx...x.xx.x.x..x.x.xx.x..x.x.x.x.x.x.", "xx...xx.x..x.xx.x...x.x.x.x.x.x.x.x.xx..xxxx.x.x...xx.x..x.", "x.x.x.x.x.x...x.x.x...x.x.x...x.x....", ".xxxx.xxxx.xxx.xxxx.xx....xxx.xxxx.xxxx.xxxx.xxxx.xxx.xxxx...", ".x...xxx.x.xxxx.x...x.x..xxx....xx.xxxx..", "x..xxx...x.xxxx..xx..x..xx.xx..", "..xx..x.xxx...xx...xx..xx.xx.", "xx..x..xxxx..xx.xxx....x..", "xx..xx....xxxx.x..x.x.."]
}
]
}
]);
Loaded 100 of 101 files, more files were not shown because too many files have changed in this diff. Show more