Compare commits

...
120 Commits
Author SHA1 Message Date
n1474335 83f119f7e4 9.24.2 2021-02-03 17:54:57 +00:00
n1474335 041c899a35 Comments are now treated as disabled so that they do not interfere with the Dish type. Closes #1126 and #1132. Thanks to @mt3571 for the suggestion. 2021-02-03 17:54:49 +00:00
n1474335 5412fc01b3 Merge branch 'Prinzhorn-base_64_order' 2021-02-02 17:36:23 +00:00
n1474335 76926d9252 Merge branch 'base_64_order' of https://github.com/Prinzhorn/CyberChef into Prinzhorn-base_64_order 2021-02-02 17:36:10 +00:00
n1474335 3270961574 Merge branch 'n1073645-microsoftDecoderMagic' 2021-02-02 17:29:41 +00:00
n1474335 9a1ef71aec Merge branch 'microsoftDecoderMagic' of https://github.com/n1073645/CyberChef into n1073645-microsoftDecoderMagic 2021-02-02 17:29:25 +00:00
n1474335 ba878925ad Merge branch 'Prinzhorn-boolean_args' 2021-02-02 17:23:23 +00:00
n1474335 8d6b71bfaa Merge branch 'boolean_args' of https://github.com/Prinzhorn/CyberChef into Prinzhorn-boolean_args 2021-02-02 17:23:05 +00:00
n1474335 b6845aa03c 9.24.1 2021-02-02 17:18:49 +00:00
n1474335 4a673bd92a AES Decrypt now supports Additional Authenticated Data in GCM mode. Added tests for ADD at each AES size. 2021-02-02 17:18:35 +00:00
n1474335 fdffabfdd4 Merge branch 'n1073645-AESGCMAAD' 2021-02-02 16:11:03 +00:00
n1474335 ba8591293b Merge branch 'AESGCMAAD' of https://github.com/n1073645/CyberChef into n1073645-AESGCMAAD 2021-02-02 16:10:47 +00:00
n1474335 9b3aae10cf 9.24.0 2021-02-02 16:07:57 +00:00
n1474335 5c85c4df63 Updated CHANGELOG 2021-02-02 16:07:52 +00:00
n1474335 8ece2603fb Merge branch 'n1073645-SM3' 2021-02-02 16:06:49 +00:00
n1474335 1b54584820 Tweaks to various hashing functions to improve config options 2021-02-02 16:06:37 +00:00
n1474335 3ce3866000 Merge branch 'SM3' of https://github.com/n1073645/CyberChef into n1073645-SM3 2021-02-02 11:58:36 +00:00
n1474335 becc258b6c Updated CHANGELOG 2021-02-02 11:12:52 +00:00
n1474335 16c9e7119d Updated CHANGELOG 2021-02-02 11:02:23 +00:00
n1474335 f5888fea9c 9.23.1 2021-02-01 19:29:47 +00:00
n1474335 b5162c7549 Merge branch 'maqifrnswa-master' 2021-02-01 19:27:42 +00:00
n1474335 1baea1da3d Merge branch 'master' of https://github.com/maqifrnswa/CyberChef into maqifrnswa-master 2021-02-01 19:27:24 +00:00
n1474335 40899a6fe4 9.23.0 2021-02-01 19:16:03 +00:00
n1474335 66c533431d Merge branch 'mattnotmitt-rsa' 2021-02-01 19:15:46 +00:00
n1474335 74ae77f17a Tidied up and added tests for RSA operations 2021-02-01 19:15:32 +00:00
n1474335 99eb1cced5 Merge branch 'rsa' of https://github.com/mattnotmitt/CyberChef into mattnotmitt-rsa 2021-02-01 17:30:02 +00:00
n1474335 c880ecf3c4 Merge branch 'stephengroat-nvmrc' 2021-02-01 17:01:44 +00:00
n1474335 c54c34d88e Merge branch 'nvmrc' of https://github.com/stephengroat/CyberChef into stephengroat-nvmrc 2021-02-01 17:01:31 +00:00
n1474335 60b3c597a7 9.22.4 2021-02-01 16:57:48 +00:00
n1474335 372ab32539 Updated dependencies 2021-02-01 16:57:42 +00:00
n1474335 e14745a973 9.22.3 2021-02-01 16:43:19 +00:00
n1474335 afffe584cf Added flat lib for JSON to CSV op 2021-02-01 16:41:54 +00:00
n1474335 cf532f1e30 Merge branch 'n1073645-JSONTOCSV' 2021-02-01 16:35:09 +00:00
n1474335 46425ba552 Merge branch 'JSONTOCSV' of https://github.com/n1073645/CyberChef into n1073645-JSONTOCSV 2021-02-01 16:34:57 +00:00
n1474335 9f65fac4e6 Added actions for linting and testing Pull Requests 2021-02-01 16:34:12 +00:00
n1474335 af98feff51 Improved PGP keygen test 2021-02-01 16:24:47 +00:00
n1474335 339c741a2c 9.22.2 2021-02-01 16:14:38 +00:00
n1474335 d1bde23f00 Merge branch 'n1073645-datetime' 2021-02-01 16:13:57 +00:00
n1474335 be544faf0f Merge branch 'datetime' of https://github.com/n1073645/CyberChef into n1073645-datetime 2021-02-01 16:13:43 +00:00
n1474335 eff77fd3bb 9.22.1 2021-02-01 16:11:46 +00:00
n1474335 3df57ba3dd Added big and little endian options for Windows timestamp conversion ops 2021-02-01 16:11:39 +00:00
n1474335 4bae662357 Merge branch 'n1073645-FiletimeEndianness' 2021-02-01 15:56:03 +00:00
n1474335 357c90546e Merge branch 'FiletimeEndianness' of https://github.com/n1073645/CyberChef into n1073645-FiletimeEndianness 2021-02-01 15:55:42 +00:00
n1474335 54769a90ac 9.22.0 2021-02-01 15:52:34 +00:00
n1474335 0550aedd54 Merge branch 'mattnotmitt-features/unicode-format' 2021-02-01 15:51:29 +00:00
n1474335 5947ed21fc Tidied up localisation in Wikipedia URL 2021-02-01 15:51:14 +00:00
n1474335 0a0949246f Merge branch 'features/unicode-format' of https://github.com/mattnotmitt/CyberChef into mattnotmitt-features/unicode-format 2021-02-01 15:45:21 +00:00
n1474335 09c6e181fb 9.21.6 2021-02-01 14:42:32 +00:00
n1474335 02cf394bcd ROT13 tweaks 2021-02-01 14:42:00 +00:00
n1474335 46afbf9888 Merge branch 'n1073645-numberRot' 2021-02-01 14:37:44 +00:00
n1474335 7cf19d22a8 Merge branch 'numberRot' of https://github.com/n1073645/CyberChef into n1073645-numberRot 2021-02-01 14:37:30 +00:00
n1474335 46d708360f Merge branch 'xavier630-patch-1' 2021-02-01 14:32:05 +00:00
n1474335 7ec91e2366 Merge branch 'patch-1' of https://github.com/xavier630/CyberChef into xavier630-patch-1 2021-02-01 14:31:42 +00:00
n1474335 a74ee47bf0 Updated actions config 2021-02-01 14:18:17 +00:00
n1474335 7b68b92498 Updated actions config 2021-02-01 14:14:40 +00:00
n1474335 274f3acd45 Added GH Releases and NPM actions 2021-02-01 14:10:21 +00:00
n1474335 53dff8b30f 9.21.5 2021-02-01 11:10:16 +00:00
n1474335 9892ee273e Bugfix: ECC mode now works correctly in 'Generate PGP Key Pair' 2021-02-01 11:10:04 +00:00
n1474335 7dccecb336 Moved GH Pages prep to its own step 2021-01-22 17:15:58 +00:00
n1474335 aa09da0403 GitHub Actions now pushes to GitHub Pages 2021-01-22 17:13:17 +00:00
n1474335 98d7f1481c Improved UI tests 2021-01-22 16:52:37 +00:00
n1474335 7d8bdbcf7e Improved UI tests 2021-01-22 16:39:04 +00:00
n1474335 db009d3689 Improved UI tests 2021-01-22 16:25:19 +00:00
n1474335 d7bc529a95 Improved UI tests 2021-01-22 16:16:11 +00:00
n1474335 3f035294a6 Improved UI tests 2021-01-22 16:06:44 +00:00
n1474335 36282e362f Improved UI tests 2021-01-22 15:53:56 +00:00
n1474335 223353cf4d Increased UI test operation timeout 2021-01-22 15:43:18 +00:00
n1474335 ded32da632 Back to a single job 2021-01-22 15:33:15 +00:00
n1474335 d6fc21cc34 Fixed yaml 2021-01-22 15:28:46 +00:00
n1474335 b86e960456 Actions broken out into separate jobs 2021-01-22 15:27:42 +00:00
n1474335 7747bfe0f2 Fixed prod build and Actions now creates a sitemap 2021-01-22 15:17:17 +00:00
n1474335 fabea8cc61 Fix whitespace 2021-01-22 15:00:15 +00:00
n1474335 de4cd2eebc Add production build to GitHub Actions script 2021-01-22 14:59:26 +00:00
n1474335 e16ce1d9c2 Specify node version 2021-01-22 14:53:53 +00:00
n1474335 345ad741b3 Fixed sed command in postinstall script to be platform dependent 2021-01-22 14:47:33 +00:00
n1474335 e53108c493 Merge branch 'gh-actions' 2021-01-22 14:33:48 +00:00
n1474335 6129378854 Reduced Actions script to just linting and testing 2021-01-22 14:33:35 +00:00
n1474335 11a1416dcc Merge branch 'gh-actions' of https://github.com/mattnotmitt/CyberChef into mattnotmitt-gh-actions 2021-01-22 14:17:29 +00:00
n1474335 9025538544 9.21.4 2021-01-22 13:48:30 +00:00
n1474335 46929e1844 Merge branch 'mattnotmax-haversine' 2021-01-22 13:48:19 +00:00
n1474335 bf023cad48 Merge branch 'haversine' of https://github.com/mattnotmax/CyberChef into mattnotmax-haversine 2021-01-22 13:48:04 +00:00
mattnotmax 39b7e4ff9e Correct Haversine test output 2020-12-09 21:12:26 +11:00
mattnotmax a1109c43f6 Fix for haversine distance bug 2020-12-08 21:17:43 +11:00
Xavier Downs 3e8dea73d2 Update ScanForEmbeddedFiles.mjs 2020-11-24 12:18:02 +00:00
n1073645 bbf19ee944 argument added for numbers in ROT 2020-08-24 11:24:25 +01:00
n1073645 f6c8c9e76c swap endianness argument added to Windows Filetime To Unix Timestamp 2020-08-24 10:39:18 +01:00
Matt bf14c8983f trigger travis 2020-08-19 11:04:09 +01:00
Matt 3ab95384df Add unicode tests 2020-08-19 10:55:29 +01:00
n1073645 3bfddd708c rectify week number 2020-08-17 10:40:00 +01:00
Matt 13a54ec318 Add unicode text format operation 2020-08-13 12:36:02 +01:00
n1073645 2781640a2a JSON to CSV improvements 2020-07-29 15:27:55 +01:00
n1073645 7989f119d3 Linting Modifications 2020-07-16 09:56:30 +01:00
Scott Howard 2e0aa7ae87 Don't pad rail fence decode fixes #1069 2020-07-15 22:05:15 -04:00
Matt 0b5ee7c79f Update actions 2020-07-04 15:35:49 +01:00
Matt 23cbe1c426 Merge branch 'master' into gh-actions 2020-07-04 15:29:24 +01:00
Stephen G de727bcddc use nvmrc file
avoids storing node version in travis to allow nvm tool for local dev
2020-06-13 14:51:37 -07:00
Matt d4ae241758 Merge branch 'master' into rsa 2020-06-08 15:55:37 +01:00
n1073645 fae96af17d Info for sm3 added 2020-04-24 14:13:55 +01:00
n1073645 57c1a03c4f Option structures added for hashing algorithms 2020-04-24 14:04:13 +01:00
Alexander Prinzhorn cb8fe42c66 Put Base64 after Base62 2020-04-16 10:20:38 +02:00
Alexander Prinzhorn 7f4b2574b0 Use proper booleans instead of relying on truthy/falsy values 2020-04-16 09:59:43 +02:00
Matt fad163e0eb Added tests (that can't be run) 2020-04-07 21:16:29 +01:00
Matt 7ad3992bd1 Add RSA Decrypt Operation 2020-04-07 13:31:33 +01:00
Matt e7b5c0e37c Add RSA Encrypt Operation 2020-04-07 13:31:17 +01:00
n1073645 cc35127459 AAD for AES Added 2020-04-07 13:03:24 +01:00
Matt 1c0ecd29c2 Fix RSA operations 2020-04-07 11:45:54 +01:00
n1073645 1f0fddd0e9 Added magic signature to Microsoft Script Decoder 2020-04-07 10:33:15 +01:00
Matt 18c6b9bc09 Add RSA Verify operation 2020-04-06 15:24:22 +01:00
Matt 2233b9a094 Comment and add error handling to generate and sign 2020-04-06 15:24:06 +01:00
Matt e0f000b913 Fixed RSA generation and added digest option to verify 2020-04-06 13:35:14 +01:00
Matt 73864e0809 Merge branch 'master' into features/rsa 2020-04-05 12:08:24 +01:00
Matt 123a0ccd70 Changed pages workflow 2019-09-30 14:41:14 +01:00
Matt 4c737475d4 Forgot to run prod build 2019-09-30 14:08:23 +01:00
Matt 4e0d97f2c1 Added sudo 2019-09-30 14:02:22 +01:00
Matt 85906cafbb Adjustment 2019-09-30 13:56:26 +01:00
Matt a8dc691033 Try using github actions
Gonna monch this commit once i know it works
2019-09-30 13:51:38 +01:00
Matt 4d7988b78e Fixed RSA key generation 2019-09-30 13:12:10 +01:00
Matt 841e760b04 Merge remote-tracking branch 'upstream/master' into features/rsa 2019-09-30 11:03:41 +01:00
Matt C 31e758ca45 Attempt to make RSA key generation functional 2018-08-31 11:25:05 +01:00
GCHQ 77703 f81ca3ba60 Implement RSA generation and signing of messages 2018-08-30 22:38:01 +01:00
62 changed files with 2442 additions and 1470 deletions

No files matched your search

+54
View File
@@ -0,0 +1,54 @@
name: Master
on:
push:
branches:
- master
jobs:
main:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set node version
uses: actions/setup-node@v1
with:
node-version: '10.x'
- name: Install
run: |
npm install
export NODE_OPTIONS=--max_old_space_size=2048
- name: Lint
run: npx grunt lint
- name: Unit Tests
run: |
npm test
npx grunt testnodeconsumer
- name: Production Build
if: success()
run: npx grunt prod
- name: Generate sitemap
run: npx grunt exec:sitemap
- name: UI Tests
if: success()
run: xvfb-run --server-args="-screen 0 1200x800x24" npx grunt testui
- name: Prepare for GitHub Pages
if: success()
run: npx grunt copy:ghPages
- name: Deploy to GitHub Pages
if: success() && github.ref == 'refs/heads/master'
uses: crazy-max/ghaction-github-pages@v2
with:
target_branch: gh-pages
build_dir: ./build/prod
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+37
View File
@@ -0,0 +1,37 @@
name: PRs
on:
pull_request:
types: [synchronize, opened, reopened]
jobs:
main:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set node version
uses: actions/setup-node@v1
with:
node-version: '10.x'
- name: Install
run: |
npm install
export NODE_OPTIONS=--max_old_space_size=2048
- name: Lint
run: npx grunt lint
- name: Unit Tests
run: |
npm test
npx grunt testnodeconsumer
- name: Production Build
if: success()
run: npx grunt prod
- name: UI Tests
if: success()
run: xvfb-run --server-args="-screen 0 1200x800x24" npx grunt testui
+55
View File
@@ -0,0 +1,55 @@
name: Release
on:
push:
tags:
- 'v*'
jobs:
main:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set node version
uses: actions/setup-node@v1
with:
node-version: '10.x'
- name: Install
run: |
npm install
export NODE_OPTIONS=--max_old_space_size=2048
- name: Lint
run: npx grunt lint
- name: Unit Tests
run: |
npm test
npx grunt testnodeconsumer
- name: Production Build
if: success()
run: npx grunt prod
- name: UI Tests
if: success()
run: xvfb-run --server-args="-screen 0 1200x800x24" npx grunt testui
- name: Upload Release Assets
if: success()
id: upload-release-assets
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: build/prod/*.zip
tag: ${{ github.ref }}
overwrite: true
file_glob: true
- name: Publish to NPM
if: success()
uses: JS-DevTools/npm-publish@v1
with:
token: ${{ secrets.NPM_TOKEN }}
+1
View File
@@ -0,0 +1 @@
lts/dubnium
-55
View File
@@ -1,55 +0,0 @@
language: node_js
node_js:
- lts/dubnium
cache: npm
os: linux
addons:
chrome: stable
install: npm install
before_script:
- npm install -g grunt
- export NODE_OPTIONS=--max_old_space_size=2048
script:
- grunt lint
- npm test
- grunt testnodeconsumer
- grunt prod --msg="$COMPILE_MSG"
- xvfb-run --server-args="-screen 0 1200x800x24" grunt testui
before_deploy:
- grunt exec:sitemap
- grunt copy:ghPages
deploy:
- provider: pages
edge: true
token: $GITHUB_TOKEN
local_dir: build/prod/
target_branch: gh-pages
on:
repo: gchq/CyberChef
branch: master
- provider: releases
edge: true
token:
secure: "HV1WSKv4l/0Y2bKKs1iBJocBcmLj08PCRUeEM/jTwA4jqJ8EiLHWiXtER/D5sEg2iibRVKd2OQjfrmS6bo4AiwdeVgAKmv0FtS2Jw+391N8Nd5AkEANHa5Om/IpHLTL2YRAjpJTsDpY72bMUTJIwjQA3TFJkgrpOw6KYfohOcgbxLpZ4XuNJRU3VL4Hsxdv5V9aOVmfFOmMOVPQlakXy7NgtW5POp1f2WJwgcZxylkR1CjwaqMyXmSoVl46pyH3tr5+dptsQoKSGdi6sIHGA60oDotFPcm+0ifa47wZw+vapuuDi4tdNxhrHGaDMG8xiE0WFDHwQUDlk2/+W7j9SEX0H3Em7us371JXRp56EDwEcDa34VpVkC6i8HGcHK55hnxVbMZXGf3qhOFD8wY7qMbjMRvIpucrMHBi86OfkDfv0vDj2LyvIl5APj/AX50BrE0tfH1MZbH26Jkx4NdlkcxQ14GumarmUqfmVvbX/fsoA6oUuAAE9ZgRRi3KHO4wci6KUcRfdm+XOeUkaBFsL86G3EEYIvrtBTuaypdz+Cx7nd1iPZyWMx5Y1gXnVzha4nBdV4+7l9JIsFggD8QVpw2uHXQiS1KXFjOeqA3DBD8tjMB7q26Fl2fD3jkOo4BTbQ2NrRIZUu/iL+fOmMPsyMt2qulB0yaSBCfkbEq8xrUA="
file_glob: true
file:
- build/prod/*.zip
- src/node/cjs.js
on:
repo: gchq/CyberChef
tags: true
- provider: npm
edge: true
email: "n1474335@gmail.com"
api_token:
secure: "UnDQL3Kh+GK2toL0TK3FObO0ujVssU3Eg4BBuYdjwLB81GhiGE5/DTh7THdZPOpbLo6wQeOwfZDuMeKC1OU+0Uf4NsdYFu1aq6xMO20qBQ4qUfgsyiK4Qgywj9gk0p1+OFZdGAZ/j1CNRAaF71XQIY6iV84c+SO4WoizXYrNT0Jh4sr2DA4/97G2xmJtPi0qOzYrJ09R56ZUozmqeik5G0pMRIuJRbpjS/7bZXV+N7WV0ombZc9RkUaetbabEVOLQ+Xx5YAIVq+VuEeMe9VBSnxY/FfCLmy1wJsjGzpLCyBI9nbrG4nw8Wgc2m8NfK9rcpIvBTGner9r2j60NVDkZ8kLZPrqXhq6AZMwa+oz6K5UQCqRo2RRQzSGwXxg67HY5Tcq+oNmjd+DqpPg4LZ3eGlluyP5XfG+hpSr9Ya4d8q8SrUWLxkoLHI6ZKMtoKFbTCSSQPiluW5hsZxjz3yDkkjsJw64M/EM8UyJrgaXqDklQu+7rBGKLfsK6os7RDiqjBWpQ7gwpo8HvY0O8yqEAabPz+QGkanpjcCOZCXFbSkzWxYy37RMAPu88iINVZVlZE4l+WJenCpZY95ueyy0mG9cyMSzVRPyX6A+/n4H6VMFPFjpGDLTD588ACEjY1lmHfS/eXwXJcgqPPD2gW0XdRdUheU/ssqlfCfGWQMTDXs="
on:
tags: true
branch: master
notifications:
webhooks:
urls:
- https://webhooks.gitter.im/e/83c143a6822e218d5b34
on_success: change
on_failure: always
on_start: never
+29
View File
@@ -1,7 +1,27 @@
# Changelog
## Versioning
CyberChef uses the [semver](https://semver.org/) system to manage versioning: MAJOR.MINOR.PATCH.
- MAJOR version changes represent a significant change to the fundamental architecture of CyberChef and may (but don't always) make breaking changes that are not backwards compatible.
- MINOR version changes usually mean the addition of new operations or reasonably significant new features.
- PATCH versions are used for bug fixes and any other small tweaks that modify or improve existing capabilities.
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).
## Details
### [9.24.0] - 2020-02-02
- 'SM3' hashing function added along with more configuration options for other hashing operations [@n1073645] [@n1474335] | [#1022]
### [9.23.0] - 2020-02-01
- Various RSA operations added to encrypt, decrypt, sign, verify and generate keys [@mattnotmitt] [@GCHQ77703] | [#652]
### [9.22.0] - 2021-02-01
- 'Unicode Text Format' operation added [@mattnotmitt] | [#1083]
### [9.21.0] - 2020-06-12
- Node API now exports `magic` operation [@d98762625] | [#1049]
@@ -227,6 +247,10 @@ All major and minor version changes will be documented in this file. Details of
[9.24.0]: https://github.com/gchq/CyberChef/releases/tag/v9.24.0
[9.23.0]: https://github.com/gchq/CyberChef/releases/tag/v9.23.0
[9.22.0]: https://github.com/gchq/CyberChef/releases/tag/v9.22.0
[9.21.0]: https://github.com/gchq/CyberChef/releases/tag/v9.21.0
[9.20.0]: https://github.com/gchq/CyberChef/releases/tag/v9.20.0
[9.19.0]: https://github.com/gchq/CyberChef/releases/tag/v9.19.0
[9.18.0]: https://github.com/gchq/CyberChef/releases/tag/v9.18.0
@@ -326,6 +350,7 @@ All major and minor version changes will be documented in this file. Details of
[@pointhi]: https://github.com/pointhi
[@MarvinJWendt]: https://github.com/MarvinJWendt
[@dmfj]: https://github.com/dmfj
[@mattnotmitt]: https://github.com/mattnotmitt
[#95]: https://github.com/gchq/CyberChef/pull/299
[#173]: https://github.com/gchq/CyberChef/pull/173
@@ -387,6 +412,7 @@ 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
[#652]: https://github.com/gchq/CyberChef/pull/652
[#653]: https://github.com/gchq/CyberChef/pull/653
[#674]: https://github.com/gchq/CyberChef/pull/674
[#683]: https://github.com/gchq/CyberChef/pull/683
@@ -398,3 +424,6 @@ All major and minor version changes will be documented in this file. Details of
[#965]: https://github.com/gchq/CyberChef/pull/965
[#966]: https://github.com/gchq/CyberChef/pull/966
[#987]: https://github.com/gchq/CyberChef/pull/987
[#1022]: https://github.com/gchq/CyberChef/pull/1022
[#1049]: https://github.com/gchq/CyberChef/pull/1049
[#1083]: https://github.com/gchq/CyberChef/pull/1083
-17
View File
@@ -78,7 +78,6 @@ module.exports = function (grunt) {
grunt.loadNpmTasks("grunt-contrib-watch");
grunt.loadNpmTasks("grunt-chmod");
grunt.loadNpmTasks("grunt-exec");
grunt.loadNpmTasks("grunt-accessibility");
grunt.loadNpmTasks("grunt-concurrent");
grunt.loadNpmTasks("grunt-contrib-connect");
grunt.loadNpmTasks("grunt-zip");
@@ -197,18 +196,6 @@ module.exports = function (grunt) {
node: ["src/node/**/*.{js,mjs}"],
tests: ["tests/**/*.{js,mjs}"],
},
accessibility: {
options: {
accessibilityLevel: "WCAG2A",
verbose: false,
ignore: [
"WCAG2A.Principle1.Guideline1_3.1_3_1.H42.2"
]
},
test: {
src: ["build/**/*.html"]
}
},
webpack: {
options: webpackConfig,
web: webpackProdConf(),
@@ -242,10 +229,6 @@ module.exports = function (grunt) {
entry: Object.assign({
main: "./src/web/index.js"
}, moduleEntryPoints),
output: {
publicPath: "",
globalObject: "this"
},
resolve: {
alias: {
"./config/modules/OpModules.mjs": "./config/modules/Default.mjs"
+517 -1108
View File
File diff suppressed because it is too large. Load diff
+30 -30
View File
@@ -1,6 +1,6 @@
{
"name": "cyberchef",
"version": "9.21.3",
"version": "9.24.2",
"description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.",
"author": "n1474335 <n1474335@gmail.com>",
"homepage": "https://gchq.github.io/CyberChef",
@@ -38,21 +38,20 @@
"devDependencies": {
"@babel/core": "^7.12.10",
"@babel/plugin-transform-runtime": "^7.12.10",
"@babel/preset-env": "^7.12.10",
"autoprefixer": "^10.1.0",
"@babel/preset-env": "^7.12.11",
"autoprefixer": "^10.2.4",
"babel-eslint": "^10.1.0",
"babel-loader": "^8.2.2",
"babel-plugin-dynamic-import-node": "^2.3.3",
"chromedriver": "^87.0.4",
"cli-progress": "^3.8.2",
"chromedriver": "^88.0.0",
"cli-progress": "^3.9.0",
"colors": "^1.4.0",
"copy-webpack-plugin": "^7.0.0",
"css-loader": "^5.0.1",
"eslint": "^7.15.0",
"exports-loader": "^1.1.1",
"eslint": "^7.19.0",
"exports-loader": "^2.0.0",
"file-loader": "^6.2.0",
"grunt": "^1.3.0",
"grunt-accessibility": "~6.0.0",
"grunt-chmod": "~1.1.1",
"grunt-concurrent": "^3.0.0",
"grunt-contrib-clean": "~2.0.0",
@@ -63,26 +62,26 @@
"grunt-exec": "~3.0.0",
"grunt-webpack": "^4.0.2",
"grunt-zip": "^0.18.2",
"html-webpack-plugin": "^4.5.0",
"imports-loader": "^1.2.0",
"mini-css-extract-plugin": "^1.3.3",
"html-webpack-plugin": "^4.5.1",
"imports-loader": "^2.0.0",
"mini-css-extract-plugin": "^1.3.5",
"nightwatch": "^1.5.1",
"node-sass": "^5.0.0",
"postcss": "^8.2.1",
"postcss": "^8.2.4",
"postcss-css-variables": "^0.17.0",
"postcss-import": "^13.0.0",
"postcss-loader": "^4.1.0",
"prompt": "^1.0.0",
"sass-loader": "^10.1.0",
"sitemap": "^6.3.3",
"postcss-import": "^14.0.0",
"postcss-loader": "^4.2.0",
"prompt": "^1.1.0",
"sass-loader": "^10.1.1",
"sitemap": "^6.3.5",
"style-loader": "^2.0.0",
"svg-url-loader": "^7.1.1",
"url-loader": "^4.1.1",
"webpack": "^5.10.1",
"webpack-bundle-analyzer": "^4.2.0",
"webpack-dev-server": "^3.11.0",
"webpack": "^5.19.0",
"webpack-bundle-analyzer": "^4.4.0",
"webpack-dev-server": "^3.11.2",
"webpack-node-externals": "^2.5.2",
"worker-loader": "^3.0.6"
"worker-loader": "^3.0.7"
},
"dependencies": {
"@babel/polyfill": "^7.12.1",
@@ -93,7 +92,7 @@
"bcryptjs": "^2.4.3",
"bignumber.js": "^9.0.1",
"blakejs": "^1.1.0",
"bootstrap": "4.5.3",
"bootstrap": "4.6.0",
"bootstrap-colorpicker": "^3.2.0",
"bootstrap-material-design": "^4.1.3",
"browserify-zlib": "^0.2.0",
@@ -101,12 +100,12 @@
"buffer": "^6.0.3",
"chi-squared": "^1.1.0",
"codepage": "^1.14.0",
"core-js": "^3.8.1",
"core-js": "^3.8.3",
"crypto-api": "^0.8.5",
"crypto-browserify": "^3.12.0",
"crypto-js": "^4.0.0",
"ctph.js": "0.0.5",
"d3": "^6.3.1",
"d3": "^6.5.0",
"d3-hexbin": "^0.2.2",
"diff": "^5.0.0",
"es6-promisify": "^6.1.1",
@@ -115,24 +114,25 @@
"esprima": "^4.0.1",
"exif-parser": "^0.1.12",
"file-saver": "^2.0.5",
"flat": "^5.0.2",
"geodesy": "^1.1.3",
"highlight.js": "^10.4.1",
"highlight.js": "^10.5.0",
"jimp": "^0.16.1",
"jquery": "3.5.1",
"js-crc": "^0.2.0",
"js-sha3": "^0.8.0",
"jsesc": "^3.0.2",
"jsonpath": "^1.0.2",
"jsonpath": "^1.1.0",
"jsonwebtoken": "^8.5.1",
"jsqr": "^1.3.1",
"jsrsasign": "10.1.4",
"jsrsasign": "10.1.5",
"kbpgp": "2.1.15",
"libbzip2-wasm": "0.0.4",
"libyara-wasm": "^1.1.0",
"lodash": "^4.17.20",
"loglevel": "^1.7.1",
"loglevel-message-prefix": "^3.0.0",
"markdown-it": "^12.0.3",
"markdown-it": "^12.0.4",
"moment": "^2.29.1",
"moment-timezone": "^0.5.32",
"ngeohash": "^0.6.3",
@@ -148,7 +148,7 @@
"qr-image": "^3.2.0",
"scryptsy": "^2.1.0",
"snackbarjs": "^1.1.0",
"sortablejs": "^1.12.0",
"sortablejs": "^1.13.0",
"split.js": "^1.6.2",
"ssdeep.js": "0.0.2",
"stream-browserify": "^3.0.0",
@@ -172,7 +172,7 @@
"testui": "grunt testui",
"testuidev": "npx nightwatch --env=dev",
"lint": "grunt lint",
"postinstall": "find ./node_modules/crypto-api/src/ \\( -type d -name .git -prune \\) -o -type f -print0 | xargs -0 sed -i '' -e '/\\.mjs/!s/\\(from \"\\.[^\"]*\\)\";/\\1.mjs\";/g'",
"postinstall": "bash postinstall.sh",
"newop": "node --experimental-modules src/core/config/scripts/newOperation.mjs"
}
}
Executable
+8
View File
@@ -0,0 +1,8 @@
#!/bin/bash
# Add file extensions to Crypto-Api imports
if [[ "$OSTYPE" == "darwin"* ]]; then
find ./node_modules/crypto-api/src/ \( -type d -name .git -prune \) -o -type f -print0 | xargs -0 sed -i '' -e '/\.mjs/!s/\(from "\.[^"]*\)";/\1.mjs";/g'
else
find ./node_modules/crypto-api/src/ \( -type d -name .git -prune \) -o -type f -print0 | xargs -0 sed -i -e '/\.mjs/!s/\(from "\.[^"]*\)";/\1.mjs";/g'
fi
+1 -1
View File
@@ -46,7 +46,7 @@ class Recipe {
module: OperationConfig[c.op].module,
ingValues: c.args,
breakpoint: c.breakpoint,
disabled: c.disabled,
disabled: c.disabled || c.op === "Comment",
});
});
}
+10 -3
View File
@@ -18,15 +18,15 @@
"From Binary",
"To Octal",
"From Octal",
"To Base64",
"From Base64",
"Show Base64 offsets",
"To Base32",
"From Base32",
"To Base58",
"From Base58",
"To Base62",
"From Base62",
"To Base64",
"From Base64",
"Show Base64 offsets",
"To Base85",
"From Base85",
"To Base",
@@ -134,6 +134,11 @@
"PGP Verify",
"PGP Encrypt and Sign",
"PGP Decrypt and Verify",
"Generate RSA Key Pair",
"RSA Sign",
"RSA Verify",
"RSA Encrypt",
"RSA Decrypt",
"Parse SSH Host Key"
]
},
@@ -200,6 +205,7 @@
"ops": [
"Encode text",
"Decode text",
"Unicode Text Format",
"Remove Diacritics",
"Unescape Unicode Characters",
"Convert to NATO alphabet"
@@ -313,6 +319,7 @@
"SHA1",
"SHA2",
"SHA3",
"SM3",
"Keccak",
"Shake",
"RIPEMD",
+17
View File
@@ -0,0 +1,17 @@
/**
* RSA resources.
*
* @author Matt C [me@mitt.dev]
* @copyright Crown Copyright 2021
* @license Apache-2.0
*/
import forge from "node-forge";
export const MD_ALGORITHMS = {
"SHA-1": forge.md.sha1,
"MD5": forge.md.md5,
"SHA-256": forge.md.sha256,
"SHA-384": forge.md.sha384,
"SHA-512": forge.md.sha512,
};
+36 -4
View File
@@ -41,8 +41,33 @@ class AESDecrypt extends Operation {
},
{
"name": "Mode",
"type": "option",
"value": ["CBC", "CFB", "OFB", "CTR", "GCM", "ECB"]
"type": "argSelector",
"value": [
{
name: "CBC",
off: [5, 6]
},
{
name: "CFB",
off: [5, 6]
},
{
name: "OFB",
off: [5, 6]
},
{
name: "CTR",
off: [5, 6]
},
{
name: "GCM",
on: [5, 6]
},
{
name: "ECB",
off: [5, 6]
}
]
},
{
"name": "Input",
@@ -59,6 +84,11 @@ class AESDecrypt extends Operation {
"type": "toggleString",
"value": "",
"toggleValues": ["Hex", "UTF8", "Latin1", "Base64"]
},
{
"name": "Additional Authenticated Data",
"type": "binaryString",
"value": ""
}
];
}
@@ -76,7 +106,8 @@ class AESDecrypt extends Operation {
mode = args[2],
inputType = args[3],
outputType = args[4],
gcmTag = Utils.convertToByteString(args[5].string, args[5].option);
gcmTag = Utils.convertToByteString(args[5].string, args[5].option),
aad = args[6];
if ([16, 24, 32].indexOf(key.length) < 0) {
throw new OperationError(`Invalid key length: ${key.length} bytes
@@ -92,7 +123,8 @@ The following algorithms will be used based on the size of the key:
const decipher = forge.cipher.createDecipher("AES-" + mode, key);
decipher.start({
iv: iv.length === 0 ? "" : iv,
tag: gcmTag
tag: mode === "GCM" ? gcmTag : undefined,
additionalData: mode === "GCM" ? aad : undefined
});
decipher.update(forge.util.createBuffer(input));
const result = decipher.finish();
+38 -4
View File
@@ -41,8 +41,33 @@ class AESEncrypt extends Operation {
},
{
"name": "Mode",
"type": "option",
"value": ["CBC", "CFB", "OFB", "CTR", "GCM", "ECB"]
"type": "argSelector",
"value": [
{
name: "CBC",
off: [5]
},
{
name: "CFB",
off: [5]
},
{
name: "OFB",
off: [5]
},
{
name: "CTR",
off: [5]
},
{
name: "GCM",
on: [5]
},
{
name: "ECB",
off: [5]
}
]
},
{
"name": "Input",
@@ -53,6 +78,11 @@ class AESEncrypt extends Operation {
"name": "Output",
"type": "option",
"value": ["Hex", "Raw"]
},
{
"name": "Additional Authenticated Data",
"type": "binaryString",
"value": ""
}
];
}
@@ -69,7 +99,8 @@ class AESEncrypt extends Operation {
iv = Utils.convertToByteString(args[1].string, args[1].option),
mode = args[2],
inputType = args[3],
outputType = args[4];
outputType = args[4],
aad = args[5];
if ([16, 24, 32].indexOf(key.length) < 0) {
throw new OperationError(`Invalid key length: ${key.length} bytes
@@ -83,7 +114,10 @@ The following algorithms will be used based on the size of the key:
input = Utils.convertToByteString(input, inputType);
const cipher = forge.cipher.createCipher("AES-" + mode, key);
cipher.start({iv: iv});
cipher.start({
iv: iv,
additionalData: mode === "GCM" ? aad : undefined
});
cipher.update(forge.util.createBuffer(input));
cipher.finish();
+22 -11
View File
@@ -125,7 +125,8 @@ class Colossus extends Operation {
},
{
name: "R1-Negate",
type: "boolean"
type: "boolean",
value: false
},
{
name: "R1-Counter",
@@ -164,7 +165,8 @@ class Colossus extends Operation {
},
{
name: "R2-Negate",
type: "boolean"
type: "boolean",
value: false
},
{
name: "R2-Counter",
@@ -203,7 +205,8 @@ class Colossus extends Operation {
},
{
name: "R3-Negate",
type: "boolean"
type: "boolean",
value: false
},
{
name: "R3-Counter",
@@ -212,7 +215,8 @@ class Colossus extends Operation {
},
{
name: "Negate All",
type: "boolean"
type: "boolean",
value: false
},
{
name: "K Rack: Addition",
@@ -220,23 +224,28 @@ class Colossus extends Operation {
},
{
name: "Add-Q1",
type: "boolean"
type: "boolean",
value: false
},
{
name: "Add-Q2",
type: "boolean"
type: "boolean",
value: false
},
{
name: "Add-Q3",
type: "boolean"
type: "boolean",
value: false
},
{
name: "Add-Q4",
type: "boolean"
type: "boolean",
value: false
},
{
name: "Add-Q5",
type: "boolean"
type: "boolean",
value: false
},
{
name: "Add-Equals",
@@ -246,11 +255,13 @@ class Colossus extends Operation {
},
{
name: "Add-Counter1",
type: "boolean"
type: "boolean",
value: false
},
{
name: "Add Negate All",
type: "boolean"
type: "boolean",
value: false
},
{
name: "Total Motor",
+1 -1
View File
@@ -27,7 +27,7 @@ class ExtractDomains extends Operation {
{
"name": "Display total",
"type": "boolean",
"value": "Extract.DISPLAY_TOTAL"
"value": true
}
];
}
+1 -1
View File
@@ -38,7 +38,7 @@ class ExtractFiles extends Operation {
{
name: "Ignore failed extractions",
type: "boolean",
value: "true"
value: true
}
]);
}
@@ -30,7 +30,7 @@ class FrequencyDistribution extends Operation {
{
"name": "Show 0%s",
"type": "boolean",
"value": "Entropy.FREQ_ZEROS"
"value": true
}
];
}
+7 -4
View File
@@ -25,7 +25,7 @@ class GeneratePGPKeyPair extends Operation {
this.name = "Generate PGP Key Pair";
this.module = "PGP";
this.description = "Generates a new public/private PGP key pair. Supports RSA and Eliptic Curve (EC) keys.";
this.description = "Generates a new public/private PGP key pair. Supports RSA and Eliptic Curve (EC) keys.<br><br>WARNING: Cryptographic operations in CyberChef should not be relied upon to provide security in any situation. No guarantee is offered for their correctness. We advise you not to use keys generated from CyberChef in operational contexts.";
this.infoURL = "https://wikipedia.org/wiki/Pretty_Good_Privacy";
this.inputType = "string";
this.outputType = "string";
@@ -33,7 +33,7 @@ class GeneratePGPKeyPair extends Operation {
{
"name": "Key type",
"type": "option",
"value": ["RSA-1024", "RSA-2048", "RSA-4096", "ECC-256", "ECC-384"]
"value": ["RSA-1024", "RSA-2048", "RSA-4096", "ECC-256", "ECC-384", "ECC-521"]
},
{
"name": "Password (optional)",
@@ -59,12 +59,15 @@ class GeneratePGPKeyPair extends Operation {
* @returns {string}
*/
async run(input, args) {
const [keyType, keySize] = args[0].split("-"),
password = args[1],
let [keyType, keySize] = args[0].split("-");
const password = args[1],
name = args[2],
email = args[3];
let userIdentifier = "";
keyType = keyType.toLowerCase();
keySize = parseInt(keySize, 10);
if (name) userIdentifier += name;
if (email) userIdentifier += ` <${email}>`;
@@ -0,0 +1,87 @@
/**
* @author Matt C [me@mitt.dev]
* @author gchq77703 []
* @copyright Crown Copyright 2018
* @license Apache-2.0
*/
import Operation from "../Operation.mjs";
import forge from "node-forge";
/**
* Generate RSA Key Pair operation
*/
class GenerateRSAKeyPair extends Operation {
/**
* GenerateRSAKeyPair constructor
*/
constructor() {
super();
this.name = "Generate RSA Key Pair";
this.module = "Ciphers";
this.description = "Generate an RSA key pair with a given number of bits.<br><br>WARNING: Cryptographic operations in CyberChef should not be relied upon to provide security in any situation. No guarantee is offered for their correctness. We advise you not to use keys generated from CyberChef in operational contexts.";
this.infoURL = "https://wikipedia.org/wiki/RSA_(cryptosystem)";
this.inputType = "string";
this.outputType = "string";
this.args = [
{
name: "RSA Key Length",
type: "option",
value: [
"1024",
"2048",
"4096"
]
},
{
name: "Output Format",
type: "option",
value: [
"PEM",
"JSON",
"DER"
]
}
];
}
/**
* @param {string} input
* @param {Object[]} args
* @returns {string}
*/
async run(input, args) {
const [keyLength, outputFormat] = args;
return new Promise((resolve, reject) => {
forge.pki.rsa.generateKeyPair({
bits: Number(keyLength),
workers: -1,
workerScript: "assets/forge/prime.worker.min.js"
}, (err, keypair) => {
if (err) return reject(err);
let result;
switch (outputFormat) {
case "PEM":
result = forge.pki.publicKeyToPem(keypair.publicKey) + "\n" + forge.pki.privateKeyToPem(keypair.privateKey);
break;
case "JSON":
result = JSON.stringify(keypair);
break;
case "DER":
result = forge.asn1.toDer(forge.pki.privateKeyToAsn1(keypair.privateKey)).getBytes();
break;
}
resolve(result);
});
});
}
}
export default GenerateRSAKeyPair;
+11 -3
View File
@@ -20,11 +20,19 @@ class HAS160 extends Operation {
this.name = "HAS-160";
this.module = "Crypto";
this.description = "HAS-160 is a cryptographic hash function designed for use with the Korean KCDSA digital signature algorithm. It is derived from SHA-1, with assorted changes intended to increase its security. It produces a 160-bit output.<br><br>HAS-160 is used in the same way as SHA-1. First it divides input in blocks of 512 bits each and pads the final block. A digest function updates the intermediate hash value by processing the input blocks in turn.<br><br>The message digest algorithm consists of 80 rounds.";
this.description = "HAS-160 is a cryptographic hash function designed for use with the Korean KCDSA digital signature algorithm. It is derived from SHA-1, with assorted changes intended to increase its security. It produces a 160-bit output.<br><br>HAS-160 is used in the same way as SHA-1. First it divides input in blocks of 512 bits each and pads the final block. A digest function updates the intermediate hash value by processing the input blocks in turn.<br><br>The message digest algorithm consists, by default, of 80 rounds.";
this.infoURL = "https://wikipedia.org/wiki/HAS-160";
this.inputType = "ArrayBuffer";
this.outputType = "string";
this.args = [];
this.args = [
{
name: "Rounds",
type: "number",
value: 80,
min: 1,
max: 80
}
];
}
/**
@@ -33,7 +41,7 @@ class HAS160 extends Operation {
* @returns {string}
*/
run(input, args) {
return runHash("has160", input);
return runHash("has160", input, {rounds: args[0]});
}
}
+2 -2
View File
@@ -41,8 +41,8 @@ class HaversineDistance extends Operation {
const lat1 = parseFloat(values[1]);
const lng1 = parseFloat(values[3]);
const lat2 = parseFloat(values[6]);
const lng2 = parseFloat(values[8]);
const lat2 = parseFloat(values[5]);
const lng2 = parseFloat(values[7]);
const TO_RAD = Math.PI / 180;
const dLat = (lat2-lat1) * TO_RAD;
+49 -30
View File
@@ -6,6 +6,8 @@
import Operation from "../Operation.mjs";
import OperationError from "../errors/OperationError.mjs";
import * as flat from "flat";
const flatten = flat.default ? flat.default.flatten : flat.flatten;
/**
* JSON to CSV operation
@@ -38,6 +40,40 @@ class JSONToCSV extends Operation {
];
}
/**
* Converts JSON to a CSV equivalent.
*
* @returns {string}
*/
toCSV() {
const self = this;
// If the JSON is an array of arrays, this is easy
if (this.flattened[0] instanceof Array) {
return this.flattened
.map(row => row
.map(self.escapeCellContents.bind(self))
.join(this.cellDelim)
)
.join(this.rowDelim) +
this.rowDelim;
}
// If it's an array of dictionaries...
const header = Object.keys(this.flattened[0]);
return header
.map(self.escapeCellContents.bind(self))
.join(this.cellDelim) +
this.rowDelim +
this.flattened
.map(row => header
.map(h => row[h])
.map(self.escapeCellContents.bind(self))
.join(this.cellDelim)
)
.join(this.rowDelim) +
this.rowDelim;
}
/**
* @param {JSON} input
* @param {Object[]} args
@@ -49,40 +85,23 @@ class JSONToCSV extends Operation {
// Record values so they don't have to be passed to other functions explicitly
this.cellDelim = cellDelim;
this.rowDelim = rowDelim;
const self = this;
if (!(input instanceof Array)) {
input = [input];
this.flattened = input;
if (!(this.flattened instanceof Array)) {
this.flattened = [input];
}
try {
// If the JSON is an array of arrays, this is easy
if (input[0] instanceof Array) {
return input
.map(row => row
.map(self.escapeCellContents.bind(self))
.join(cellDelim)
)
.join(rowDelim) +
rowDelim;
}
// If it's an array of dictionaries...
const header = Object.keys(input[0]);
return header
.map(self.escapeCellContents.bind(self))
.join(cellDelim) +
rowDelim +
input
.map(row => header
.map(h => row[h])
.map(self.escapeCellContents.bind(self))
.join(cellDelim)
)
.join(rowDelim) +
rowDelim;
return this.toCSV();
} catch (err) {
throw new OperationError("Unable to parse JSON to CSV: " + err.toString());
try {
this.flattened = flatten(input);
if (!(this.flattened instanceof Array)) {
this.flattened = [this.flattened];
}
return this.toCSV();
} catch (err) {
throw new OperationError("Unable to parse JSON to CSV: " + err.toString());
}
}
}
+2 -1
View File
@@ -60,7 +60,8 @@ class Lorenz extends Operation {
},
{
name: "KT-Schalter",
type: "boolean"
type: "boolean",
value: false
},
{
name: "Mode",
+10 -3
View File
@@ -20,11 +20,18 @@ class MD2 extends Operation {
this.name = "MD2";
this.module = "Crypto";
this.description = "The MD2 (Message-Digest 2) algorithm is a cryptographic hash function developed by Ronald Rivest in 1989. The algorithm is optimized for 8-bit computers.<br><br>Although MD2 is no longer considered secure, even as of 2014, it remains in use in public key infrastructures as part of certificates generated with MD2 and RSA.";
this.description = "The MD2 (Message-Digest 2) algorithm is a cryptographic hash function developed by Ronald Rivest in 1989. The algorithm is optimized for 8-bit computers.<br><br>Although MD2 is no longer considered secure, even as of 2014, it remains in use in public key infrastructures as part of certificates generated with MD2 and RSA. The message digest algorithm consists, by default, of 18 rounds.";
this.infoURL = "https://wikipedia.org/wiki/MD2_(cryptography)";
this.inputType = "ArrayBuffer";
this.outputType = "string";
this.args = [];
this.args = [
{
name: "Rounds",
type: "number",
value: 18,
min: 0
}
];
}
/**
@@ -33,7 +40,7 @@ class MD2 extends Operation {
* @returns {string}
*/
run(input, args) {
return runHash("md2", input);
return runHash("md2", input, {rounds: args[0]});
}
}
@@ -24,6 +24,13 @@ class MicrosoftScriptDecoder extends Operation {
this.inputType = "string";
this.outputType = "string";
this.args = [];
this.checks = [
{
pattern: "#@~\\^.{6}==(.+).{6}==\\^#~@",
flags: "i",
args: []
}
];
}
/**
+1 -1
View File
@@ -72,7 +72,7 @@ class ParseDateTime extends Operation {
"\nLeap year: " + date.isLeapYear() +
"\nDays in this month: " + date.daysInMonth() +
"\n\nDay of year: " + date.dayOfYear() +
"\nWeek number: " + date.weekYear() +
"\nWeek number: " + date.week() +
"\nQuarter: " + date.quarter();
return output;
+11 -2
View File
@@ -35,6 +35,11 @@ class ROT13 extends Operation {
type: "boolean",
value: true
},
{
name: "Rotate numbers",
type: "boolean",
value: false
},
{
name: "Amount",
type: "number",
@@ -51,8 +56,9 @@ class ROT13 extends Operation {
run(input, args) {
const output = input,
rot13Lowercase = args[0],
rot13Upperacse = args[1];
let amount = args[2],
rot13Upperacse = args[1],
rotNumbers = args[2];
let amount = args[3],
chr;
if (amount) {
@@ -68,6 +74,9 @@ class ROT13 extends Operation {
} else if (rot13Lowercase && chr >= 97 && chr <= 122) { // Lower case
chr = (chr - 97 + amount) % 26;
output[i] = chr + 97;
} else if (rotNumbers && chr >= 48 && chr <= 57) { // Numbers
chr = (chr - 48 + amount) % 10;
output[i] = chr + 48;
}
}
}
+86
View File
@@ -0,0 +1,86 @@
/**
* @author Matt C [me@mitt.dev]
* @copyright Crown Copyright 2020
* @license Apache-2.0
*/
import Operation from "../Operation.mjs";
import OperationError from "../errors/OperationError.mjs";
import forge from "node-forge";
import { MD_ALGORITHMS } from "../lib/RSA.mjs";
/**
* RSA Decrypt operation
*/
class RSADecrypt extends Operation {
/**
* RSADecrypt constructor
*/
constructor() {
super();
this.name = "RSA Decrypt";
this.module = "Ciphers";
this.description = "Decrypt an RSA encrypted message with a PEM encoded private key.";
this.infoURL = "https://wikipedia.org/wiki/RSA_(cryptosystem)";
this.inputType = "string";
this.outputType = "string";
this.args = [
{
name: "RSA Private Key (PEM)",
type: "text",
value: "-----BEGIN RSA PRIVATE KEY-----"
},
{
name: "Key Password",
type: "text",
value: ""
},
{
name: "Encryption Scheme",
type: "argSelector",
value: [
{
name: "RSA-OAEP",
on: [3]
},
{
name: "RSAES-PKCS1-V1_5",
off: [3]
},
{
name: "RAW",
off: [3]
}]
},
{
name: "Message Digest Algorithm",
type: "option",
value: Object.keys(MD_ALGORITHMS)
}
];
}
/**
* @param {string} input
* @param {Object[]} args
* @returns {string}
*/
run(input, args) {
const [pemKey, password, scheme, md] = args;
if (pemKey.replace("-----BEGIN RSA PRIVATE KEY-----", "").length === 0) {
throw new OperationError("Please enter a private key.");
}
try {
const privKey = forge.pki.decryptRsaPrivateKey(pemKey, password);
const dMsg = privKey.decrypt(input, scheme, {md: MD_ALGORITHMS[md].create()});
return forge.util.decodeUtf8(dMsg);
} catch (err) {
throw new OperationError(err);
}
}
}
export default RSADecrypt;
+89
View File
@@ -0,0 +1,89 @@
/**
* @author Matt C [me@mitt.dev]
* @copyright Crown Copyright 2020
* @license Apache-2.0
*/
import Operation from "../Operation.mjs";
import OperationError from "../errors/OperationError.mjs";
import forge from "node-forge";
import { MD_ALGORITHMS } from "../lib/RSA.mjs";
/**
* RSA Encrypt operation
*/
class RSAEncrypt extends Operation {
/**
* RSAEncrypt constructor
*/
constructor() {
super();
this.name = "RSA Encrypt";
this.module = "Ciphers";
this.description = "Encrypt a message with a PEM encoded RSA public key.";
this.infoURL = "https://wikipedia.org/wiki/RSA_(cryptosystem)";
this.inputType = "string";
this.outputType = "string";
this.args = [
{
name: "RSA Public Key (PEM)",
type: "text",
value: "-----BEGIN RSA PUBLIC KEY-----"
},
{
name: "Encryption Scheme",
type: "argSelector",
value: [
{
name: "RSA-OAEP",
on: [2]
},
{
name: "RSAES-PKCS1-V1_5",
off: [2]
},
{
name: "RAW",
off: [2]
}]
},
{
name: "Message Digest Algorithm",
type: "option",
value: Object.keys(MD_ALGORITHMS)
}
];
}
/**
* @param {string} input
* @param {Object[]} args
* @returns {string}
*/
run(input, args) {
const [pemKey, scheme, md] = args;
if (pemKey.replace("-----BEGIN RSA PUBLIC KEY-----", "").length === 0) {
throw new OperationError("Please enter a public key.");
}
try {
// Load public key
const pubKey = forge.pki.publicKeyFromPem(pemKey);
// https://github.com/digitalbazaar/forge/issues/465#issuecomment-271097600
const plaintextBytes = forge.util.encodeUtf8(input);
// Encrypt message
const eMsg = pubKey.encrypt(plaintextBytes, scheme, {md: MD_ALGORITHMS[md].create()});
return eMsg;
} catch (err) {
if (err.message === "RSAES-OAEP input message length is too long.") {
throw new OperationError(`RSAES-OAEP input message length (${err.length}) is longer than the maximum allowed length (${err.maxLength}).`);
}
throw new OperationError(err);
}
}
}
export default RSAEncrypt;
+74
View File
@@ -0,0 +1,74 @@
/**
* @author Matt C [me@mitt.dev]
* @author gchq77703 []
* @copyright Crown Copyright 2020
* @license Apache-2.0
*/
import Operation from "../Operation.mjs";
import OperationError from "../errors/OperationError.mjs";
import forge from "node-forge";
import { MD_ALGORITHMS } from "../lib/RSA.mjs";
/**
* RSA Sign operation
*/
class RSASign extends Operation {
/**
* RSASign constructor
*/
constructor() {
super();
this.name = "RSA Sign";
this.module = "Ciphers";
this.description = "Sign a plaintext message with a PEM encoded RSA key.";
this.infoURL = "https://wikipedia.org/wiki/RSA_(cryptosystem)";
this.inputType = "string";
this.outputType = "string";
this.args = [
{
name: "RSA Private Key (PEM)",
type: "text",
value: "-----BEGIN RSA PRIVATE KEY-----"
},
{
name: "Key Password",
type: "text",
value: ""
},
{
name: "Message Digest Algorithm",
type: "option",
value: Object.keys(MD_ALGORITHMS)
}
];
}
/**
* @param {string} input
* @param {Object[]} args
* @returns {string}
*/
run(input, args) {
const [key, password, mdAlgo] = args;
if (key.replace("-----BEGIN RSA PRIVATE KEY-----", "").length === 0) {
throw new OperationError("Please enter a private key.");
}
try {
const privateKey = forge.pki.decryptRsaPrivateKey(key, password);
// Generate message hash
const md = MD_ALGORITHMS[mdAlgo].create();
md.update(input, "utf8");
// Sign message hash
const sig = privateKey.sign(md);
return sig;
} catch (err) {
throw new OperationError(err);
}
}
}
export default RSASign;
+77
View File
@@ -0,0 +1,77 @@
/**
* @author Matt C [me@mitt.dev]
* @copyright Crown Copyright 2020
* @license Apache-2.0
*/
import Operation from "../Operation.mjs";
import OperationError from "../errors/OperationError.mjs";
import forge from "node-forge";
import { MD_ALGORITHMS } from "../lib/RSA.mjs";
/**
* RSA Verify operation
*/
class RSAVerify extends Operation {
/**
* RSAVerify constructor
*/
constructor() {
super();
this.name = "RSA Verify";
this.module = "Ciphers";
this.description = "Verify a message against a signature and a public PEM encoded RSA key.";
this.infoURL = "https://wikipedia.org/wiki/RSA_(cryptosystem)";
this.inputType = "string";
this.outputType = "string";
this.args = [
{
name: "RSA Public Key (PEM)",
type: "text",
value: "-----BEGIN RSA PUBLIC KEY-----"
},
{
name: "Message",
type: "text",
value: ""
},
{
name: "Message Digest Algorithm",
type: "option",
value: Object.keys(MD_ALGORITHMS)
}
];
}
/**
* @param {string} input
* @param {Object[]} args
* @returns {string}
*/
run(input, args) {
const [pemKey, message, mdAlgo] = args;
if (pemKey.replace("-----BEGIN RSA PUBLIC KEY-----", "").length === 0) {
throw new OperationError("Please enter a public key.");
}
try {
// Load public key
const pubKey = forge.pki.publicKeyFromPem(pemKey);
// Generate message digest
const md = MD_ALGORITHMS[mdAlgo].create();
md.update(message, "utf8");
// Compare signed message digest and generated message digest
const result = pubKey.verify(md.digest().bytes(), input);
return result ? "Verified OK" : "Verification Failure";
} catch (err) {
if (err.message === "Encrypted message length is invalid.") {
throw new OperationError(`Signature length (${err.length}) does not match expected length based on key (${err.expected}).`);
}
throw new OperationError(err);
}
}
}
export default RSAVerify;
@@ -46,7 +46,7 @@ class RailFenceCipherDecode extends Operation {
run(input, args) {
const [key, offset] = args;
let cipher = input;
const cipher = input;
if (key < 2) {
throw new OperationError("Key has to be bigger than 2");
@@ -59,13 +59,6 @@ class RailFenceCipherDecode extends Operation {
}
const cycle = (key - 1) * 2;
const rest = cipher.length % key;
if (rest !== 0) {
cipher = cipher + (" ".repeat(key - rest));
}
const plaintext = new Array(cipher.length);
let j = 0;
+1 -1
View File
@@ -19,7 +19,7 @@ class RemoveDiacritics extends Operation {
this.name = "Remove Diacritics";
this.module = "Default";
this.description = "Replaces accented characters with their latin character equivalent.";
this.description = "Replaces accented characters with their latin character equivalent. Accented characters are made up of Unicode combining characters, so unicode text formatting such as strikethroughs and underlines will also be removed.";
this.infoURL = "https://wikipedia.org/wiki/Diacritic";
this.inputType = "string";
this.outputType = "string";
+10 -3
View File
@@ -20,11 +20,18 @@ class SHA0 extends Operation {
this.name = "SHA0";
this.module = "Crypto";
this.description = "SHA-0 is a retronym applied to the original version of the 160-bit hash function published in 1993 under the name 'SHA'. It was withdrawn shortly after publication due to an undisclosed 'significant flaw' and replaced by the slightly revised version SHA-1.";
this.description = "SHA-0 is a retronym applied to the original version of the 160-bit hash function published in 1993 under the name 'SHA'. It was withdrawn shortly after publication due to an undisclosed 'significant flaw' and replaced by the slightly revised version SHA-1. The message digest algorithm consists, by default, of 80 rounds.";
this.infoURL = "https://wikipedia.org/wiki/SHA-1#SHA-0";
this.inputType = "ArrayBuffer";
this.outputType = "string";
this.args = [];
this.args = [
{
name: "Rounds",
type: "number",
value: 80,
min: 16
}
];
}
/**
@@ -33,7 +40,7 @@ class SHA0 extends Operation {
* @returns {string}
*/
run(input, args) {
return runHash("sha0", input);
return runHash("sha0", input, {rounds: args[0]});
}
}
+10 -3
View File
@@ -20,11 +20,18 @@ class SHA1 extends Operation {
this.name = "SHA1";
this.module = "Crypto";
this.description = "The SHA (Secure Hash Algorithm) hash functions were designed by the NSA. SHA-1 is the most established of the existing SHA hash functions and it is used in a variety of security applications and protocols.<br><br>However, SHA-1's collision resistance has been weakening as new attacks are discovered or improved.";
this.description = "The SHA (Secure Hash Algorithm) hash functions were designed by the NSA. SHA-1 is the most established of the existing SHA hash functions and it is used in a variety of security applications and protocols.<br><br>However, SHA-1's collision resistance has been weakening as new attacks are discovered or improved. The message digest algorithm consists, by default, of 80 rounds.";
this.infoURL = "https://wikipedia.org/wiki/SHA-1";
this.inputType = "ArrayBuffer";
this.outputType = "string";
this.args = [];
this.args = [
{
name: "Rounds",
type: "number",
value: 80,
min: 16
}
];
}
/**
@@ -33,7 +40,7 @@ class SHA1 extends Operation {
* @returns {string}
*/
run(input, args) {
return runHash("sha1", input);
return runHash("sha1", input, {rounds: args[0]});
}
}
+49 -5
View File
@@ -20,15 +20,58 @@ class SHA2 extends Operation {
this.name = "SHA2";
this.module = "Crypto";
this.description = "The SHA-2 (Secure Hash Algorithm 2) hash functions were designed by the NSA. SHA-2 includes significant changes from its predecessor, SHA-1. The SHA-2 family consists of hash functions with digests (hash values) that are 224, 256, 384 or 512 bits: SHA224, SHA256, SHA384, SHA512.<br><br><ul><li>SHA-512 operates on 64-bit words.</li><li>SHA-256 operates on 32-bit words.</li><li>SHA-384 is largely identical to SHA-512 but is truncated to 384 bytes.</li><li>SHA-224 is largely identical to SHA-256 but is truncated to 224 bytes.</li><li>SHA-512/224 and SHA-512/256 are truncated versions of SHA-512, but the initial values are generated using the method described in Federal Information Processing Standards (FIPS) PUB 180-4.</li></ul>";
this.description = "The SHA-2 (Secure Hash Algorithm 2) hash functions were designed by the NSA. SHA-2 includes significant changes from its predecessor, SHA-1. The SHA-2 family consists of hash functions with digests (hash values) that are 224, 256, 384 or 512 bits: SHA224, SHA256, SHA384, SHA512.<br><br><ul><li>SHA-512 operates on 64-bit words.</li><li>SHA-256 operates on 32-bit words.</li><li>SHA-384 is largely identical to SHA-512 but is truncated to 384 bytes.</li><li>SHA-224 is largely identical to SHA-256 but is truncated to 224 bytes.</li><li>SHA-512/224 and SHA-512/256 are truncated versions of SHA-512, but the initial values are generated using the method described in Federal Information Processing Standards (FIPS) PUB 180-4.</li></ul> The message digest algorithm for SHA256 variants consists, by default, of 64 rounds, and for SHA512 variants, it is, by default, 160.";
this.infoURL = "https://wikipedia.org/wiki/SHA-2";
this.inputType = "ArrayBuffer";
this.outputType = "string";
this.args = [
{
"name": "Size",
"type": "option",
"value": ["512", "256", "384", "224", "512/256", "512/224"]
name: "Size",
type: "argSelector",
value: [
{
name: "512",
on: [2],
off: [1]
},
{
name: "384",
on: [2],
off: [1]
},
{
name: "256",
on: [1],
off: [2]
},
{
name: "224",
on: [1],
off: [2]
},
{
name: "512/256",
on: [2],
off: [1]
},
{
name: "512/224",
on: [2],
off: [1]
}
]
},
{
name: "Rounds", // For SHA256 variants
type: "number",
value: 64,
min: 16
},
{
name: "Rounds", // For SHA512 variants
type: "number",
value: 160,
min: 32
}
];
}
@@ -40,7 +83,8 @@ class SHA2 extends Operation {
*/
run(input, args) {
const size = args[0];
return runHash("sha" + size, input);
const rounds = (size === "256" || size === "224") ? args[1] : args[2];
return runHash("sha" + size, input, {rounds: rounds});
}
}
+57
View File
@@ -0,0 +1,57 @@
/**
* @author n1073645 [n1073645@gmail.com]
* @copyright Crown Copyright 2020
* @license Apache-2.0
*/
import Operation from "../Operation.mjs";
import Utils from "../Utils.mjs";
import Sm3 from "crypto-api/src/hasher/sm3.mjs";
import {toHex} from "crypto-api/src/encoder/hex.mjs";
/**
* SM3 operation
*/
class SM3 extends Operation {
/**
* SM3 constructor
*/
constructor() {
super();
this.name = "SM3";
this.module = "Crypto";
this.description = "SM3 is a cryptographic hash function used in the Chinese National Standard. SM3 is mainly used in digital signatures, message authentication codes, and pseudorandom number generators. The message digest algorithm consists, by default, of 64 rounds and length of 256.";
this.infoURL = "https://wikipedia.org/wiki/SM3_(hash_function)";
this.inputType = "ArrayBuffer";
this.outputType = "string";
this.args = [
{
name: "Length",
type: "number",
value: 256
},
{
name: "Rounds",
type: "number",
value: 64,
min: 16
}
];
}
/**
* @param {ArrayBuffer} input
* @param {Object[]} args
* @returns {string}
*/
run(input, args) {
const msg = Utils.arrayBufferToStr(input, false);
const hasher = new Sm3({length: args[0], rounds: args[1]});
hasher.update(msg);
return toHex(hasher.finalize());
}
}
export default SM3;
+1 -1
View File
@@ -41,7 +41,7 @@ class ScanForEmbeddedFiles extends Operation {
* @returns {string}
*/
run(input, args) {
let output = "Scanning data for 'magic bytes' which may indicate embedded files. The following results may be false positives and should not be treat as reliable. Any sufficiently long file is likely to contain these magic bytes coincidentally.\n",
let output = "Scanning data for 'magic bytes' which may indicate embedded files. The following results may be false positives and should not be treated as reliable. Any sufficiently long file is likely to contain these magic bytes coincidentally.\n",
numFound = 0;
const categories = [],
data = new Uint8Array(input);
+11 -8
View File
@@ -26,14 +26,17 @@ class Snefru extends Operation {
this.outputType = "string";
this.args = [
{
"name": "Rounds",
"type": "option",
"value": ["8", "4", "2"]
name: "Size",
type: "number",
value: 128,
min: 32,
max: 480,
step: 32
},
{
"name": "Size",
"type": "option",
"value": ["256", "128"]
name: "Rounds",
type: "option",
value: ["8", "4", "2"]
}
];
}
@@ -45,8 +48,8 @@ class Snefru extends Operation {
*/
run(input, args) {
return runHash("snefru", input, {
rounds: args[0],
length: args[1]
length: args[0],
rounds: args[1]
});
}
@@ -34,7 +34,7 @@ class UNIXTimestampToWindowsFiletime extends Operation {
{
"name": "Output format",
"type": "option",
"value": ["Decimal", "Hex"]
"value": ["Decimal", "Hex (big endian)", "Hex (little endian)"]
}
];
}
@@ -65,11 +65,24 @@ class UNIXTimestampToWindowsFiletime extends Operation {
input = input.plus(new BigNumber("116444736000000000"));
if (format === "Hex") {
return input.toString(16);
let result;
if (format.startsWith("Hex")) {
result = input.toString(16);
} else {
return input.toFixed();
result = input.toFixed();
}
if (format === "Hex (little endian)") {
// Swap endianness
let flipped = "";
for (let i = result.length - 2; i >= 0; i -= 2) {
flipped += result.charAt(i);
flipped += result.charAt(i + 1);
}
result = flipped;
}
return result;
}
}
+67
View File
@@ -0,0 +1,67 @@
/**
* @author Matt C [me@mitt.dev]
* @copyright Crown Copyright 2020
* @license Apache-2.0
*/
import Operation from "../Operation.mjs";
import Utils from "../Utils.mjs";
/**
* Unicode Text Format operation
*/
class UnicodeTextFormat extends Operation {
/**
* UnicodeTextFormat constructor
*/
constructor() {
super();
this.name = "Unicode Text Format";
this.module = "Default";
this.description = "Adds Unicode combining characters to change formatting of plaintext.";
this.infoURL = "https://wikipedia.org/wiki/Combining_character";
this.inputType = "byteArray";
this.outputType = "byteArray";
this.args = [
{
name: "Underline",
type: "boolean",
value: "false"
},
{
name: "Strikethrough",
type: "boolean",
value: "false"
}
];
}
/**
* @param {byteArray} input
* @param {Object[]} args
* @returns {byteArray}
*/
run(input, args) {
const [underline, strikethrough] = args;
let output = input.map(char => [char]);
if (strikethrough) {
output = output.map(charFormat => {
charFormat.push(...Utils.strToUtf8ByteArray("\u0336"));
return charFormat;
});
}
if (underline) {
output = output.map(charFormat => {
charFormat.push(...Utils.strToUtf8ByteArray("\u0332"));
return charFormat;
});
}
// return output.flat(); - Not supported in Node 10, polyfilled
return [].concat(...output);
}
}
export default UnicodeTextFormat;
+11 -4
View File
@@ -26,9 +26,16 @@ class Whirlpool extends Operation {
this.outputType = "string";
this.args = [
{
"name": "Variant",
"type": "option",
"value": ["Whirlpool", "Whirlpool-T", "Whirlpool-0"]
name: "Variant",
type: "option",
value: ["Whirlpool", "Whirlpool-T", "Whirlpool-0"]
},
{
name: "Rounds",
type: "number",
value: 10,
min: 1,
max: 10
}
];
}
@@ -40,7 +47,7 @@ class Whirlpool extends Operation {
*/
run(input, args) {
const variant = args[0].toLowerCase();
return runHash(variant, input);
return runHash(variant, input, {rounds: args[1]});
}
}
@@ -34,7 +34,7 @@ class WindowsFiletimeToUNIXTimestamp extends Operation {
{
"name": "Input format",
"type": "option",
"value": ["Decimal", "Hex"]
"value": ["Decimal", "Hex (big endian)", "Hex (little endian)"]
}
];
}
@@ -49,7 +49,17 @@ class WindowsFiletimeToUNIXTimestamp extends Operation {
if (!input) return "";
if (format === "Hex") {
if (format === "Hex (little endian)") {
// Swap endianness
let result = "";
for (let i = input.length - 2; i >= 0; i -= 2) {
result += input.charAt(i);
result += input.charAt(i + 1);
}
input = result;
}
if (format.startsWith("Hex")) {
input = new BigNumber(input, 16);
} else {
input = new BigNumber(input);
+12 -1
View File
@@ -392,11 +392,22 @@ function testOp(browser, opName, input, output, args=[]) {
.useCss()
.click("#clr-recipe")
.click("#clr-io")
.waitForElementNotPresent("#rec-list li.operation")
.expect.element("#input-text").to.have.value.that.equals("");
browser
.urlHash("recipe=" + recipeConfig)
.setValue("#input-text", input)
.waitForElementPresent("#rec-list li.operation")
.expect.element("#input-text").to.have.value.that.equals(input);
browser
.waitForElementVisible("#stale-indicator", 5000)
.pause(100)
.click("#bake")
.waitForElementPresent("#stale-indicator.hidden", 1000);
.pause(100)
.waitForElementPresent("#stale-indicator.hidden", 5000)
.waitForElementNotVisible("#output-loader", 5000);
if (typeof output === "string") {
browser.expect.element("#output-text").to.have.value.that.equals(output);
+3 -3
View File
@@ -588,7 +588,7 @@ Password: 034148`;
const result = await chef.generatePGPKeyPair("Back To the Drawing Board", {
keyType: "ECC-256",
});
assert.strictEqual(result.toString().length, 2007);
assert.strictEqual(result.toString().substr(0, 37), "-----BEGIN PGP PRIVATE KEY BLOCK-----");
}),
it("Generate UUID", () => {
@@ -656,7 +656,7 @@ Leap year: false
Days in this month: 31
Day of year: 187
Week number: 2001
Week number: 27
Quarter: 3`;
assert.strictEqual(result.toString(), expected);
}),
@@ -854,7 +854,7 @@ pCGTErs=
it("Snefru", () => {
assert.strictEqual(
chef.snefru("demeaning milestone").toString(),
chef.snefru("demeaning milestone", {size: 256, rounds: 8}).toString(),
"a671b48770fe073ce49e9259cc2f47d345a53712639f8ae23c5ad3fec19540a5");
}),
+2 -2
View File
@@ -69,7 +69,6 @@ import "./tests/ParseQRCode.mjs";
import "./tests/PowerSet.mjs";
import "./tests/Regex.mjs";
import "./tests/Register.mjs";
import "./tests/RemoveDiacritics.mjs";
import "./tests/Rotate.mjs";
import "./tests/SeqUtils.mjs";
import "./tests/SetDifference.mjs";
@@ -101,7 +100,8 @@ import "./tests/LuhnChecksum.mjs";
import "./tests/CipherSaber2.mjs";
import "./tests/Colossus.mjs";
import "./tests/ParseObjectIDTimestamp.mjs";
import "./tests/Unicode.mjs";
import "./tests/RSA.mjs";
// Cannot test operations that use the File type yet
// import "./tests/SplitColourChannels.mjs";
+31
View File
@@ -0,0 +1,31 @@
/**
* Various types of input data for use in tests
*
* @author n1474335 [n1474335@gmail.com]
* @author Matt C [me@mitt.dev]
* @copyright Crown Copyright 2020
* @license Apache-2.0
*/
export const ASCII_TEXT = "A common mistake that people make when trying to design something completely foolproof is to underestimate the ingenuity of complete fools.";
export const UTF8_TEXT = "Шанцы на высвятленне таго, што адбываецца на самай справе ў сусвеце настолькі выдаленыя, адзінае, што трэба зрабіць, гэта павесіць пачуццё яго і трымаць сябе занятымі.";
export const ALL_BYTES = [
"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
"\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f",
"\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f",
"\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f",
"\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f",
"\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f",
"\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f",
"\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f",
"\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f",
"\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf",
"\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf",
"\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf",
"\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf",
"\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef",
"\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
].join("");
+20 -20
View File
@@ -104,26 +104,26 @@ TestRegister.addTests([
}
]
},
// This test is a bit slow - it takes about 12s on my test hardware
{
name: "Bombe: 4 rotor",
input: "LUOXGJSHGEDSRDOQQX",
expectedMatch: /<td>LHSC<\/td> {2}<td>SS<\/td> {2}<td>HHHSSSGQUUQPKSEKWK<\/td>/,
recipeConfig: [
{
"op": "Bombe",
"args": [
"4-rotor",
"LEYJVCNIXWPBQMDRTAKZGFUHOS", // Beta
"EKMFLGDQVZNTOWYHXUSPAIBRCJ<R", // I
"AJDKSIRUXBLHWTMCQGZNPYFVOE<F", // II
"BDFHJLCPRTXVZNYEIWGAKMUSQO<W", // III
"AE BN CK DQ FU GY HW IJ LO MP RX SZ TV", // B thin
"THISISATESTMESSAGE", 0, false
]
}
]
},
// Takes a while to run, so disabling for general purpose testing. Re-enable if modifying this operation.
// {
// name: "Bombe: 4 rotor",
// input: "LUOXGJSHGEDSRDOQQX",
// expectedMatch: /<td>LHSC<\/td> {2}<td>SS<\/td> {2}<td>HHHSSSGQUUQPKSEKWK<\/td>/,
// recipeConfig: [
// {
// "op": "Bombe",
// "args": [
// "4-rotor",
// "LEYJVCNIXWPBQMDRTAKZGFUHOS", // Beta
// "EKMFLGDQVZNTOWYHXUSPAIBRCJ<R", // I
// "AJDKSIRUXBLHWTMCQGZNPYFVOE<F", // II
// "BDFHJLCPRTXVZNYEIWGAKMUSQO<W", // III
// "AE BN CK DQ FU GY HW IJ LO MP RX SZ TV", // B thin
// "THISISATESTMESSAGE", 0, false
// ]
// }
// ]
// },
{
name: "Bombe: no crib",
input: "JBYALIHDYNUAAVKBYM",
+55 -54
View File
@@ -34,58 +34,59 @@ TestRegister.addTests([
}
]
},
{
name: "Colossus 1+2=.",
input: "CTBKJUVXHZ-H3L4QV+YEZUK+SXOZ/NNLH+WBFSBMJM-E3LMTPYJ.ZJDYI3TZZFVRP+REWQYOQMU3FNW.T4WB3IEPCJ-A3LWVRSZZECNGQVUFHO.R/3VZRF.Y4XEDGXZJ3RS34ARLZDZTUHMG+HH//Y+E+C-NE+--GEATU+EPEVLQEMKCLCZP-HX3C3O+CRH4D-RLIVOLHJGNI./MN4JDB/PRYZV3QOD34DAGO4+/TCS+CU-ODXMRHPPCCCD-MWHJO/TRPAELREIFVVLABSDMQORF4THY.UQTITEPYXAZ3DPNI/I+.UPTCBT-BJ/PEQFZA/PQ4+Z4-IPLBG4COART/YC4CJL+ERNVTRSHOKNSSLGFJ+QJR/ITYHWFQCPXCY.Z.X/VKTAR.LBXQK4JI/P+YDEM/LPBLK.CX/..QHBSOAO-FHJORYVBHQEYTF3/I-WZ4J.EYCYTEMG3DY3W/4VSE3/XAR3JEX4/3/LI4V/IAVLTODE-4HPLWUWMC.YEJOVFZ+/4EAIJXUT+G/.KYQF4DSVSIPLWZE.XTZWD4E.EYI/.MBJ+SVX/GBW/4RTNSGT-TF-+-JO3UE/3ZVEQKYVCUR+-3OMC+YU+UGMBCOO4.GRHVG.3+ZFB4C3J+QWCR+DHKQ3XFTUKTBGVXEQ.PCU4XLW-G+RJODDYLIJVSXOJUGKTVNBGMPH4DI+--+DKJ.MYBDX4LUWAXD-+P3.FCBWGDZQSQMPNBAODZMMM/CS3AJHEGDNZT4+.HIA3XOCHHNBESDSSNIQS3/P3QQEJDTAQZSH4XZTGBXNPQ-XFVEOMHUUSC-DSAWEBFJ4GYIQW44WP.W-IMGHZCJY/TLBWZVMNU/CETWAF3TBPIRLWDR+.WJBBYEQ.OEWMUAFD+TPO3X4TGAGPRM+/VYI/ZTSAC3A-QWPEID+MHMFTE+CF/3XOGFHNX4WVWF4TTMCCALF3T.VY4PYBCMLQ.MZRVPSA+YQL+XCY.-SEN-CZUCRCZ/PNBE4.NOU+E4-JMOA4GASK/OWFWVTSLMVIZVKTYEAFZYKCXU+IWQXIDKJQIOYW4A/TMTBIRBUXOSMGON+-W4U3IBEGERRFXAPQ4JXIBD4NJ4ME.DDRSQU+KJPHZ/+3TPKV-OKD3SBRDE4WZIVVZLXJWWL/SK/.JXF.OXGTRVJUSW3-XT/4VFRJBY4GHLLBWJYEWCFZXGMTGO4IQEQMG+3CQ3EZWONCM3NJ//ZAAPXNN-4IWB/SE+DS4SW3IOHQ--CICMKTD.AM/K-ABSCPD+VWXKKVN/3PUA+NEOZA.WWUKW+ZDTUAR/BI.PGVRFUS-/US.RSDTHGKESVB.GWGGVDHKFW4/FWPN.SDRL+GRZ/KM+.R-DHP+QC//EE/OGG+YVJ.GHDFFIXUEEOLIMC.C-4X4M-GT3DBBXANM/FER+QL3ZS/4IFSI-L.Y+KXMMR-HMCRUTZQ-LCLERSQLBMYXK.FUVKY-IA+-DDNQEE-TEDWUIB3CJYE4DMT3YPPA..AKQWSX.YT/JHFIJS/+/./+GNIRKAN/USYL4SW/BL.BNTRCFJPT.FMBZLEREFYJ/OXXQIXT-/T+IBMUNWL-JG-+ORJYJLOVZBJDKO4QJFFE.TPJGLY/.VTU-4IZBKGVBSAGWIN/N.-EK.JOWD/GYY3/SJFCYEKY/HW.O.VXTPSZVSHUA3N3QIX-+APJR43WQ+I.A/L+3/GOL.MW//KS.3Q4+3LEDVY+VDPOG+DJXHJFXBRK3SV.MPZE+/NLIA4NFEJPXYWYUUKX/UYWGU-4VF4OV4RZL.HKMRTQ/MHB/ND/VWO4ZIN/4D+ZX.PZZ.+WOCNENNZVI-IENILU.ZSHUJKIOFY3YJJA3IVRMNWENA3FQLQ4U+RKXR.IFKWEFX/VZGOUO4MYT/.PS3..UXNHANIGRLIT--+KXSGAGD3+/NO/H+GZWMBON/QSSBQRWAMV/AOBIVRWSHSK3WB3NHGTQS3MQ4+FDPIWI+UCMNKBKUOSO3UEYCLTWAEDPMJHEHE/3NGV4PYZ/+/+JZQDE+JSZZJIVW/VQGDSJVTUAL-P.K+VJRZ3NFPXUCZYA3.LNAOTBW3ATPUAUYN-J4MM3OAQTMUYICXNF-ON-L++K3RMPSX.CESSNUNJIZANHFSYTJ.XIFPJAYQMNC/QTIB.WWJ/.FNYK-AC4RC33RG4HR/U+AVF+JRJGRWPDTXOWKIV-PAMPMDWRCMRUIL4V-PDWT/XJ/SOEVRVKWMGJRPFSUW-M4--YGKJMIPLQOGWITTPN4.W+L.IVWRTY.-.FIPG4WNJFRHYOVW3OAYPJP/DJJIAMRZOU+Z/CIHUCPVT3BCLCJVACJLLQL.L4VL.Z+PSVNE-IUK.OJKNOWHKGCNZ3REIWHKEO/I.-3ZSJMN-WGPADSAAJ.-I/WKMSHGVTHI+ITSIIHZBSPUW-EIYDKT4ABEC.IMDTVET+SC.PEH4JOWDLPKPZV+UXKT/FJK+UACWJCMY+YSRYKREN/PAB+SSATQBYQ/T.Z..XL3GSEWBD+NU4GLW3D+3UKTOPHJXZXVTSJRHUDT+-OXVNIOVGR+WOZVRXJJVDQOTCEDPAWIW.VEB/-4HLHBBHCFZ+HKXA.-FJCIIHVBXRGTHEDQHCAF-/-IX3LFEM-U+QN.F3OW+IHFPM43MZ.AYMYLWUANNDOICHUJD/PKA/T-U.LACC.OFVPGYCTWO-L4PSQCWZCTOVO3JNQOY/C/4JSZZTKA4DOSH.HLQ3CGVVF4R+YURIHX4.+KMMGO-TQWVHB/P4.ZMDJZGOFAESJNWKWLV3VQROPQMZ3Q.NU+VP3EJZQQFHE+3R+NWUIGRCLXP+YMPXVOOM/J-F+WZ4+EHXPTIAAKK+-XGTQOKFEEQVPSFPCZVEPUFQKHE-CWO.BJ-.APVNMYPEA-+EQERVDPT4HDGNGCI-K-+/QOFDLSANMCRLACCRVIJBTKJG.BXNACOLKYELBL.XO+UG+CEPNLVQKR+IEYX4M/DI.RK//RAEGPMDQM/RYKF.ZULT3DLX+QW/NLZWOFFIJ3DUP+UXTSMQZZEOOYEDD+Q4KLQRE.4+FRUMDLGRXIKAD3HPEOL.QBPIHYMCSS.KMMBRSKDKK4CLH4GBSZBGHBGG/QGOT-QDI/JTED-KT+AVI-AGOXTS+I-HSG/4UYS/F.V3GC.MKCVMNLOY.MJXN/B+DRHD.KQ.RSJKIN3U.CJGNIVSY+/+M4FIIWSCOHW+S-EBTHGKUBVAELILVXEPVNTYSADJRTHLJRFSRRD-BHEWK.DWPQFQMVO.EPIV+4CBHCUNEUESRFLMTEWAEVMVEEQYSXGAHZCTTQRE.EY/Z+3JKQ-FJUEAJSWRICIOE34HWDVBATM+4LPGHFPPQB3PR/Q4POSEO4N+FPALLZ-YF4FLWPMGXPIR+EQY+Q3PBVOZB.CDNDP3-.ZVPS4ITTUDUFSZD4-CO/EEIZFIE.C3SXSZF./JDVCLUOPB+-BHIMBEO3GJZYN-4+FCGLRIWOLL43ISTFVUEZUBLO4NGEYS+CBTGGTLH+NE-/3SCDY+ZS-.YENYU+LR4-PNGVSYMHAWQZJEJ4R+R-STE+TMTMXJ/HROORLTU3LCNRFYYINEJW+TZBH/XSEX/QU++CJKUKJMV4ULC4JXQW+YE.Y-YDJHHF.ATHTN+/BZP-B/AZPFHSSWVNWI/LDUHVHUWU.KPAR-.A-TM3.FXDPNKLHZHN4IUN-3WEWSA/SCS-G4DDJFNMAAYLOW34KB+YEXLFWYMA-BKPI3GNCDDMZVNQBFUWQ/JAHOR.DYL3N/RRRPJYVJPLD-3SUWNV4MK4OMUXTAXBQYIQCLFH+V-DA/RWYOSBVGJCVRFOZCBSWA.XW-OLXJBNHTSPHSCYH+.4+RXBWCFVF3O.+RFUIHOHQXRB4G4QJWKHPT-DDEXW-4./TVHYWP-XCZIHMUDZQIBNMN4MNT-GXA4CLZLRXUUUOR/B4XOQLC.IZOM.PAUEXRJ.GRNBQGRZUQ.ISWES/YMK+AWCTQ4+-WKKA4HZ-/..XTPDBWOA3EQEDVPMN4BXHBGCGWBPOCHIYWE4NP3ILIQP.GCZA/FEKTEOML+COOF/TVMQ3WSDKG//EEXOI-/SGFTWKOG+D.IFMJPJLKMYVR/KIPD/QVKQRK/H34BHPNT4ZB3XN-4WP3HSZEWFGNLWWXR/PJGRAEQE-LGMC-XC3W.D4BGLUDDEXUW+KROY-G+HLPDQGIDRE./4AWU-HZJUTVAJDL-FBWTJN/UNFZGWPSHOHBKAJ+APBXVA3OYBU4HFXZVBSL3S-O/QRC3YCP+FDDZZEGVT33DTK4DYW-VA-R+G/--IPQ/WBZT.SLOCHE3PHQNTIIYA.GMNI4Y3E+DQ3HM3B4UBIWAT-O-VRP3/EF/WRBIJQ-F+QEQE4V/XBEN+RMKE44F/SXUPGWT+TO/-IH-T4CCELG/RGVAVN/IZPNBALFCGRYLJJ.QYAJHPBNCBBHOALK4RSQEFVA4I.VG.WFW-MGH.3RHDXFJMIMRPK-RK/X3T4TLKPUAOCIYRH/LNBEI.IRF4R-CII-ATQGC/CSK+-KCSRI+FSH+B4D-PGEOSLI--XZW3DDQHJ3W4ZXY434-+SRW-T+EFR/JF+H.SO33REUDV+--4ZETOYTXFZS4AZDFTJNIUK.P+AYDAWLHGUC3E.I/NORSMWLZQEFQUGI3A+.WA.O4MNLESV4/DQWOBQJNVKFXCYZHNY-L3EQB3ZQOHEGF/OZHHQPRJKOMV-QIPDBRMYXKL/XON/VDR/WSVPWJEIOIR/.PJZPYIK+JQOZY-XXOCIPLRHBZL.CGJWBQ+MWXKNOFXMS.RUK+A4NFJAFYEKE.AZWXJNCP3BTFOA+ZUL.RHTX-SV4LPY+VOCHEPQDFWQFIAKYG+U4YDK.EPZPTQGHGTJZTBGW4GVFSYG4XJ-C.WWPGRKXHTUFWR/VSCEZO.ZQKVJCDMFMXG+NG-BFVK.-+THEUAHA.UDPW Line truncated
expectedMatch: /31 05 : a3108/,
recipeConfig: [
{
"op": "Colossus",
"args": [
"",
"KH Pattern",
"ΔZ", "ΔΧ", "",
"None", "Select Program", "1+2=. (1+2 Break In, Find X1,X2)",
"",
"", "", "", "", "", false, "",
"", "", "", "", "", false, "",
"", "", "", "", "", false, "",
false,
"",
false, false, false, false, false,
"", false, false, "",
"",
3100, "X1", "X2",
"1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1"
]
}
]
},
{
name: "Colossus 4=5=/1=2",
input: "CTBKJUVXHZ-H3L4QV+YEZUK+SXOZ/NNLH+WBFSBMJM-E3LMTPYJ.ZJDYI3TZZFVRP+REWQYOQMU3FNW.T4WB3IEPCJ-A3LWVRSZZECNGQVUFHO.R/3VZRF.Y4XEDGXZJ3RS34ARLZDZTUHMG+HH//Y+E+C-NE+--GEATU+EPEVLQEMKCLCZP-HX3C3O+CRH4D-RLIVOLHJGNI./MN4JDB/PRYZV3QOD34DAGO4+/TCS+CU-ODXMRHPPCCCD-MWHJO/TRPAELREIFVVLABSDMQORF4THY.UQTITEPYXAZ3DPNI/I+.UPTCBT-BJ/PEQFZA/PQ4+Z4-IPLBG4COART/YC4CJL+ERNVTRSHOKNSSLGFJ+QJR/ITYHWFQCPXCY.Z.X/VKTAR.LBXQK4JI/P+YDEM/LPBLK.CX/..QHBSOAO-FHJORYVBHQEYTF3/I-WZ4J.EYCYTEMG3DY3W/4VSE3/XAR3JEX4/3/LI4V/IAVLTODE-4HPLWUWMC.YEJOVFZ+/4EAIJXUT+G/.KYQF4DSVSIPLWZE.XTZWD4E.EYI/.MBJ+SVX/GBW/4RTNSGT-TF-+-JO3UE/3ZVEQKYVCUR+-3OMC+YU+UGMBCOO4.GRHVG.3+ZFB4C3J+QWCR+DHKQ3XFTUKTBGVXEQ.PCU4XLW-G+RJODDYLIJVSXOJUGKTVNBGMPH4DI+--+DKJ.MYBDX4LUWAXD-+P3.FCBWGDZQSQMPNBAODZMMM/CS3AJHEGDNZT4+.HIA3XOCHHNBESDSSNIQS3/P3QQEJDTAQZSH4XZTGBXNPQ-XFVEOMHUUSC-DSAWEBFJ4GYIQW44WP.W-IMGHZCJY/TLBWZVMNU/CETWAF3TBPIRLWDR+.WJBBYEQ.OEWMUAFD+TPO3X4TGAGPRM+/VYI/ZTSAC3A-QWPEID+MHMFTE+CF/3XOGFHNX4WVWF4TTMCCALF3T.VY4PYBCMLQ.MZRVPSA+YQL+XCY.-SEN-CZUCRCZ/PNBE4.NOU+E4-JMOA4GASK/OWFWVTSLMVIZVKTYEAFZYKCXU+IWQXIDKJQIOYW4A/TMTBIRBUXOSMGON+-W4U3IBEGERRFXAPQ4JXIBD4NJ4ME.DDRSQU+KJPHZ/+3TPKV-OKD3SBRDE4WZIVVZLXJWWL/SK/.JXF.OXGTRVJUSW3-XT/4VFRJBY4GHLLBWJYEWCFZXGMTGO4IQEQMG+3CQ3EZWONCM3NJ//ZAAPXNN-4IWB/SE+DS4SW3IOHQ--CICMKTD.AM/K-ABSCPD+VWXKKVN/3PUA+NEOZA.WWUKW+ZDTUAR/BI.PGVRFUS-/US.RSDTHGKESVB.GWGGVDHKFW4/FWPN.SDRL+GRZ/KM+.R-DHP+QC//EE/OGG+YVJ.GHDFFIXUEEOLIMC.C-4X4M-GT3DBBXANM/FER+QL3ZS/4IFSI-L.Y+KXMMR-HMCRUTZQ-LCLERSQLBMYXK.FUVKY-IA+-DDNQEE-TEDWUIB3CJYE4DMT3YPPA..AKQWSX.YT/JHFIJS/+/./+GNIRKAN/USYL4SW/BL.BNTRCFJPT.FMBZLEREFYJ/OXXQIXT-/T+IBMUNWL-JG-+ORJYJLOVZBJDKO4QJFFE.TPJGLY/.VTU-4IZBKGVBSAGWIN/N.-EK.JOWD/GYY3/SJFCYEKY/HW.O.VXTPSZVSHUA3N3QIX-+APJR43WQ+I.A/L+3/GOL.MW//KS.3Q4+3LEDVY+VDPOG+DJXHJFXBRK3SV.MPZE+/NLIA4NFEJPXYWYUUKX/UYWGU-4VF4OV4RZL.HKMRTQ/MHB/ND/VWO4ZIN/4D+ZX.PZZ.+WOCNENNZVI-IENILU.ZSHUJKIOFY3YJJA3IVRMNWENA3FQLQ4U+RKXR.IFKWEFX/VZGOUO4MYT/.PS3..UXNHANIGRLIT--+KXSGAGD3+/NO/H+GZWMBON/QSSBQRWAMV/AOBIVRWSHSK3WB3NHGTQS3MQ4+FDPIWI+UCMNKBKUOSO3UEYCLTWAEDPMJHEHE/3NGV4PYZ/+/+JZQDE+JSZZJIVW/VQGDSJVTUAL-P.K+VJRZ3NFPXUCZYA3.LNAOTBW3ATPUAUYN-J4MM3OAQTMUYICXNF-ON-L++K3RMPSX.CESSNUNJIZANHFSYTJ.XIFPJAYQMNC/QTIB.WWJ/.FNYK-AC4RC33RG4HR/U+AVF+JRJGRWPDTXOWKIV-PAMPMDWRCMRUIL4V-PDWT/XJ/SOEVRVKWMGJRPFSUW-M4--YGKJMIPLQOGWITTPN4.W+L.IVWRTY.-.FIPG4WNJFRHYOVW3OAYPJP/DJJIAMRZOU+Z/CIHUCPVT3BCLCJVACJLLQL.L4VL.Z+PSVNE-IUK.OJKNOWHKGCNZ3REIWHKEO/I.-3ZSJMN-WGPADSAAJ.-I/WKMSHGVTHI+ITSIIHZBSPUW-EIYDKT4ABEC.IMDTVET+SC.PEH4JOWDLPKPZV+UXKT/FJK+UACWJCMY+YSRYKREN/PAB+SSATQBYQ/T.Z..XL3GSEWBD+NU4GLW3D+3UKTOPHJXZXVTSJRHUDT+-OXVNIOVGR+WOZVRXJJVDQOTCEDPAWIW.VEB/-4HLHBBHCFZ+HKXA.-FJCIIHVBXRGTHEDQHCAF-/-IX3LFEM-U+QN.F3OW+IHFPM43MZ.AYMYLWUANNDOICHUJD/PKA/T-U.LACC.OFVPGYCTWO-L4PSQCWZCTOVO3JNQOY/C/4JSZZTKA4DOSH.HLQ3CGVVF4R+YURIHX4.+KMMGO-TQWVHB/P4.ZMDJZGOFAESJNWKWLV3VQROPQMZ3Q.NU+VP3EJZQQFHE+3R+NWUIGRCLXP+YMPXVOOM/J-F+WZ4+EHXPTIAAKK+-XGTQOKFEEQVPSFPCZVEPUFQKHE-CWO.BJ-.APVNMYPEA-+EQERVDPT4HDGNGCI-K-+/QOFDLSANMCRLACCRVIJBTKJG.BXNACOLKYELBL.XO+UG+CEPNLVQKR+IEYX4M/DI.RK//RAEGPMDQM/RYKF.ZULT3DLX+QW/NLZWOFFIJ3DUP+UXTSMQZZEOOYEDD+Q4KLQRE.4+FRUMDLGRXIKAD3HPEOL.QBPIHYMCSS.KMMBRSKDKK4CLH4GBSZBGHBGG/QGOT-QDI/JTED-KT+AVI-AGOXTS+I-HSG/4UYS/F.V3GC.MKCVMNLOY.MJXN/B+DRHD.KQ.RSJKIN3U.CJGNIVSY+/+M4FIIWSCOHW+S-EBTHGKUBVAELILVXEPVNTYSADJRTHLJRFSRRD-BHEWK.DWPQFQMVO.EPIV+4CBHCUNEUESRFLMTEWAEVMVEEQYSXGAHZCTTQRE.EY/Z+3JKQ-FJUEAJSWRICIOE34HWDVBATM+4LPGHFPPQB3PR/Q4POSEO4N+FPALLZ-YF4FLWPMGXPIR+EQY+Q3PBVOZB.CDNDP3-.ZVPS4ITTUDUFSZD4-CO/EEIZFIE.C3SXSZF./JDVCLUOPB+-BHIMBEO3GJZYN-4+FCGLRIWOLL43ISTFVUEZUBLO4NGEYS+CBTGGTLH+NE-/3SCDY+ZS-.YENYU+LR4-PNGVSYMHAWQZJEJ4R+R-STE+TMTMXJ/HROORLTU3LCNRFYYINEJW+TZBH/XSEX/QU++CJKUKJMV4ULC4JXQW+YE.Y-YDJHHF.ATHTN+/BZP-B/AZPFHSSWVNWI/LDUHVHUWU.KPAR-.A-TM3.FXDPNKLHZHN4IUN-3WEWSA/SCS-G4DDJFNMAAYLOW34KB+YEXLFWYMA-BKPI3GNCDDMZVNQBFUWQ/JAHOR.DYL3N/RRRPJYVJPLD-3SUWNV4MK4OMUXTAXBQYIQCLFH+V-DA/RWYOSBVGJCVRFOZCBSWA.XW-OLXJBNHTSPHSCYH+.4+RXBWCFVF3O.+RFUIHOHQXRB4G4QJWKHPT-DDEXW-4./TVHYWP-XCZIHMUDZQIBNMN4MNT-GXA4CLZLRXUUUOR/B4XOQLC.IZOM.PAUEXRJ.GRNBQGRZUQ.ISWES/YMK+AWCTQ4+-WKKA4HZ-/..XTPDBWOA3EQEDVPMN4BXHBGCGWBPOCHIYWE4NP3ILIQP.GCZA/FEKTEOML+COOF/TVMQ3WSDKG//EEXOI-/SGFTWKOG+D.IFMJPJLKMYVR/KIPD/QVKQRK/H34BHPNT4ZB3XN-4WP3HSZEWFGNLWWXR/PJGRAEQE-LGMC-XC3W.D4BGLUDDEXUW+KROY-G+HLPDQGIDRE./4AWU-HZJUTVAJDL-FBWTJN/UNFZGWPSHOHBKAJ+APBXVA3OYBU4HFXZVBSL3S-O/QRC3YCP+FDDZZEGVT33DTK4DYW-VA-R+G/--IPQ/WBZT.SLOCHE3PHQNTIIYA.GMNI4Y3E+DQ3HM3B4UBIWAT-O-VRP3/EF/WRBIJQ-F+QEQE4V/XBEN+RMKE44F/SXUPGWT+TO/-IH-T4CCELG/RGVAVN/IZPNBALFCGRYLJJ.QYAJHPBNCBBHOALK4RSQEFVA4I.VG.WFW-MGH.3RHDXFJMIMRPK-RK/X3T4TLKPUAOCIYRH/LNBEI.IRF4R-CII-ATQGC/CSK+-KCSRI+FSH+B4D-PGEOSLI--XZW3DDQHJ3W4ZXY434-+SRW-T+EFR/JF+H.SO33REUDV+--4ZETOYTXFZS4AZDFTJNIUK.P+AYDAWLHGUC3E.I/NORSMWLZQEFQUGI3A+.WA.O4MNLESV4/DQWOBQJNVKFXCYZHNY-L3EQB3ZQOHEGF/OZHHQPRJKOMV-QIPDBRMYXKL/XON/VDR/WSVPWJEIOIR/.PJZPYIK+JQOZY-XXOCIPLRHBZL.CGJWBQ+MWXKNOFXMS.RUK+A4NFJAFYEKE.AZWXJNCP3BTFOA+ZUL.RHTX-SV4LPY+VOCHEPQDFWQFIAKYG+U4YDK.EPZPTQGHGTJZTBGW4GVFSYG4XJ-C.WWPGRKXHTUFWR/VSCEZO.ZQKVJCDMFMXG+NG-BFVK.-+THEUAHA.UDPW Line truncated
expectedMatch: /15 08 : a969/,
recipeConfig: [
{
"op": "Colossus",
"args": [
"",
"KH Pattern",
"ΔZ", "ΔΧ", "",
"None", "Select Program", "4=5=/1=2 (Given X1,X2 find X4,X5)",
"",
"", "", "", "", "", false, "",
"", "", "", "", "", false, "",
"", "", "", "", "", false, "",
false,
"",
false, false, false, false, false,
"", false, false, "",
"",
960, "X4", "X5",
"31", "5", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1"
]
}
]
},
// Takes a while to run, so disabling for general purpose testing. Re-enable if modifying this operation.
// {
// name: "Colossus 1+2=.",
// input: "CTBKJUVXHZ-H3L4QV+YEZUK+SXOZ/NNLH+WBFSBMJM-E3LMTPYJ.ZJDYI3TZZFVRP+REWQYOQMU3FNW.T4WB3IEPCJ-A3LWVRSZZECNGQVUFHO.R/3VZRF.Y4XEDGXZJ3RS34ARLZDZTUHMG+HH//Y+E+C-NE+--GEATU+EPEVLQEMKCLCZP-HX3C3O+CRH4D-RLIVOLHJGNI./MN4JDB/PRYZV3QOD34DAGO4+/TCS+CU-ODXMRHPPCCCD-MWHJO/TRPAELREIFVVLABSDMQORF4THY.UQTITEPYXAZ3DPNI/I+.UPTCBT-BJ/PEQFZA/PQ4+Z4-IPLBG4COART/YC4CJL+ERNVTRSHOKNSSLGFJ+QJR/ITYHWFQCPXCY.Z.X/VKTAR.LBXQK4JI/P+YDEM/LPBLK.CX/..QHBSOAO-FHJORYVBHQEYTF3/I-WZ4J.EYCYTEMG3DY3W/4VSE3/XAR3JEX4/3/LI4V/IAVLTODE-4HPLWUWMC.YEJOVFZ+/4EAIJXUT+G/.KYQF4DSVSIPLWZE.XTZWD4E.EYI/.MBJ+SVX/GBW/4RTNSGT-TF-+-JO3UE/3ZVEQKYVCUR+-3OMC+YU+UGMBCOO4.GRHVG.3+ZFB4C3J+QWCR+DHKQ3XFTUKTBGVXEQ.PCU4XLW-G+RJODDYLIJVSXOJUGKTVNBGMPH4DI+--+DKJ.MYBDX4LUWAXD-+P3.FCBWGDZQSQMPNBAODZMMM/CS3AJHEGDNZT4+.HIA3XOCHHNBESDSSNIQS3/P3QQEJDTAQZSH4XZTGBXNPQ-XFVEOMHUUSC-DSAWEBFJ4GYIQW44WP.W-IMGHZCJY/TLBWZVMNU/CETWAF3TBPIRLWDR+.WJBBYEQ.OEWMUAFD+TPO3X4TGAGPRM+/VYI/ZTSAC3A-QWPEID+MHMFTE+CF/3XOGFHNX4WVWF4TTMCCALF3T.VY4PYBCMLQ.MZRVPSA+YQL+XCY.-SEN-CZUCRCZ/PNBE4.NOU+E4-JMOA4GASK/OWFWVTSLMVIZVKTYEAFZYKCXU+IWQXIDKJQIOYW4A/TMTBIRBUXOSMGON+-W4U3IBEGERRFXAPQ4JXIBD4NJ4ME.DDRSQU+KJPHZ/+3TPKV-OKD3SBRDE4WZIVVZLXJWWL/SK/.JXF.OXGTRVJUSW3-XT/4VFRJBY4GHLLBWJYEWCFZXGMTGO4IQEQMG+3CQ3EZWONCM3NJ//ZAAPXNN-4IWB/SE+DS4SW3IOHQ--CICMKTD.AM/K-ABSCPD+VWXKKVN/3PUA+NEOZA.WWUKW+ZDTUAR/BI.PGVRFUS-/US.RSDTHGKESVB.GWGGVDHKFW4/FWPN.SDRL+GRZ/KM+.R-DHP+QC//EE/OGG+YVJ.GHDFFIXUEEOLIMC.C-4X4M-GT3DBBXANM/FER+QL3ZS/4IFSI-L.Y+KXMMR-HMCRUTZQ-LCLERSQLBMYXK.FUVKY-IA+-DDNQEE-TEDWUIB3CJYE4DMT3YPPA..AKQWSX.YT/JHFIJS/+/./+GNIRKAN/USYL4SW/BL.BNTRCFJPT.FMBZLEREFYJ/OXXQIXT-/T+IBMUNWL-JG-+ORJYJLOVZBJDKO4QJFFE.TPJGLY/.VTU-4IZBKGVBSAGWIN/N.-EK.JOWD/GYY3/SJFCYEKY/HW.O.VXTPSZVSHUA3N3QIX-+APJR43WQ+I.A/L+3/GOL.MW//KS.3Q4+3LEDVY+VDPOG+DJXHJFXBRK3SV.MPZE+/NLIA4NFEJPXYWYUUKX/UYWGU-4VF4OV4RZL.HKMRTQ/MHB/ND/VWO4ZIN/4D+ZX.PZZ.+WOCNENNZVI-IENILU.ZSHUJKIOFY3YJJA3IVRMNWENA3FQLQ4U+RKXR.IFKWEFX/VZGOUO4MYT/.PS3..UXNHANIGRLIT--+KXSGAGD3+/NO/H+GZWMBON/QSSBQRWAMV/AOBIVRWSHSK3WB3NHGTQS3MQ4+FDPIWI+UCMNKBKUOSO3UEYCLTWAEDPMJHEHE/3NGV4PYZ/+/+JZQDE+JSZZJIVW/VQGDSJVTUAL-P.K+VJRZ3NFPXUCZYA3.LNAOTBW3ATPUAUYN-J4MM3OAQTMUYICXNF-ON-L++K3RMPSX.CESSNUNJIZANHFSYTJ.XIFPJAYQMNC/QTIB.WWJ/.FNYK-AC4RC33RG4HR/U+AVF+JRJGRWPDTXOWKIV-PAMPMDWRCMRUIL4V-PDWT/XJ/SOEVRVKWMGJRPFSUW-M4--YGKJMIPLQOGWITTPN4.W+L.IVWRTY.-.FIPG4WNJFRHYOVW3OAYPJP/DJJIAMRZOU+Z/CIHUCPVT3BCLCJVACJLLQL.L4VL.Z+PSVNE-IUK.OJKNOWHKGCNZ3REIWHKEO/I.-3ZSJMN-WGPADSAAJ.-I/WKMSHGVTHI+ITSIIHZBSPUW-EIYDKT4ABEC.IMDTVET+SC.PEH4JOWDLPKPZV+UXKT/FJK+UACWJCMY+YSRYKREN/PAB+SSATQBYQ/T.Z..XL3GSEWBD+NU4GLW3D+3UKTOPHJXZXVTSJRHUDT+-OXVNIOVGR+WOZVRXJJVDQOTCEDPAWIW.VEB/-4HLHBBHCFZ+HKXA.-FJCIIHVBXRGTHEDQHCAF-/-IX3LFEM-U+QN.F3OW+IHFPM43MZ.AYMYLWUANNDOICHUJD/PKA/T-U.LACC.OFVPGYCTWO-L4PSQCWZCTOVO3JNQOY/C/4JSZZTKA4DOSH.HLQ3CGVVF4R+YURIHX4.+KMMGO-TQWVHB/P4.ZMDJZGOFAESJNWKWLV3VQROPQMZ3Q.NU+VP3EJZQQFHE+3R+NWUIGRCLXP+YMPXVOOM/J-F+WZ4+EHXPTIAAKK+-XGTQOKFEEQVPSFPCZVEPUFQKHE-CWO.BJ-.APVNMYPEA-+EQERVDPT4HDGNGCI-K-+/QOFDLSANMCRLACCRVIJBTKJG.BXNACOLKYELBL.XO+UG+CEPNLVQKR+IEYX4M/DI.RK//RAEGPMDQM/RYKF.ZULT3DLX+QW/NLZWOFFIJ3DUP+UXTSMQZZEOOYEDD+Q4KLQRE.4+FRUMDLGRXIKAD3HPEOL.QBPIHYMCSS.KMMBRSKDKK4CLH4GBSZBGHBGG/QGOT-QDI/JTED-KT+AVI-AGOXTS+I-HSG/4UYS/F.V3GC.MKCVMNLOY.MJXN/B+DRHD.KQ.RSJKIN3U.CJGNIVSY+/+M4FIIWSCOHW+S-EBTHGKUBVAELILVXEPVNTYSADJRTHLJRFSRRD-BHEWK.DWPQFQMVO.EPIV+4CBHCUNEUESRFLMTEWAEVMVEEQYSXGAHZCTTQRE.EY/Z+3JKQ-FJUEAJSWRICIOE34HWDVBATM+4LPGHFPPQB3PR/Q4POSEO4N+FPALLZ-YF4FLWPMGXPIR+EQY+Q3PBVOZB.CDNDP3-.ZVPS4ITTUDUFSZD4-CO/EEIZFIE.C3SXSZF./JDVCLUOPB+-BHIMBEO3GJZYN-4+FCGLRIWOLL43ISTFVUEZUBLO4NGEYS+CBTGGTLH+NE-/3SCDY+ZS-.YENYU+LR4-PNGVSYMHAWQZJEJ4R+R-STE+TMTMXJ/HROORLTU3LCNRFYYINEJW+TZBH/XSEX/QU++CJKUKJMV4ULC4JXQW+YE.Y-YDJHHF.ATHTN+/BZP-B/AZPFHSSWVNWI/LDUHVHUWU.KPAR-.A-TM3.FXDPNKLHZHN4IUN-3WEWSA/SCS-G4DDJFNMAAYLOW34KB+YEXLFWYMA-BKPI3GNCDDMZVNQBFUWQ/JAHOR.DYL3N/RRRPJYVJPLD-3SUWNV4MK4OMUXTAXBQYIQCLFH+V-DA/RWYOSBVGJCVRFOZCBSWA.XW-OLXJBNHTSPHSCYH+.4+RXBWCFVF3O.+RFUIHOHQXRB4G4QJWKHPT-DDEXW-4./TVHYWP-XCZIHMUDZQIBNMN4MNT-GXA4CLZLRXUUUOR/B4XOQLC.IZOM.PAUEXRJ.GRNBQGRZUQ.ISWES/YMK+AWCTQ4+-WKKA4HZ-/..XTPDBWOA3EQEDVPMN4BXHBGCGWBPOCHIYWE4NP3ILIQP.GCZA/FEKTEOML+COOF/TVMQ3WSDKG//EEXOI-/SGFTWKOG+D.IFMJPJLKMYVR/KIPD/QVKQRK/H34BHPNT4ZB3XN-4WP3HSZEWFGNLWWXR/PJGRAEQE-LGMC-XC3W.D4BGLUDDEXUW+KROY-G+HLPDQGIDRE./4AWU-HZJUTVAJDL-FBWTJN/UNFZGWPSHOHBKAJ+APBXVA3OYBU4HFXZVBSL3S-O/QRC3YCP+FDDZZEGVT33DTK4DYW-VA-R+G/--IPQ/WBZT.SLOCHE3PHQNTIIYA.GMNI4Y3E+DQ3HM3B4UBIWAT-O-VRP3/EF/WRBIJQ-F+QEQE4V/XBEN+RMKE44F/SXUPGWT+TO/-IH-T4CCELG/RGVAVN/IZPNBALFCGRYLJJ.QYAJHPBNCBBHOALK4RSQEFVA4I.VG.WFW-MGH.3RHDXFJMIMRPK-RK/X3T4TLKPUAOCIYRH/LNBEI.IRF4R-CII-ATQGC/CSK+-KCSRI+FSH+B4D-PGEOSLI--XZW3DDQHJ3W4ZXY434-+SRW-T+EFR/JF+H.SO33REUDV+--4ZETOYTXFZS4AZDFTJNIUK.P+AYDAWLHGUC3E.I/NORSMWLZQEFQUGI3A+.WA.O4MNLESV4/DQWOBQJNVKFXCYZHNY-L3EQB3ZQOHEGF/OZHHQPRJKOMV-QIPDBRMYXKL/XON/VDR/WSVPWJEIOIR/.PJZPYIK+JQOZY-XXOCIPLRHBZL.CGJWBQ+MWXKNOFXMS.RUK+A4NFJAFYEKE.AZWXJNCP3BTFOA+ZUL.RHTX-SV4LPY+VOCHEPQDFWQFIAKYG+U4YDK.EPZPTQGHGTJZTBGW4GVFSYG4XJ-C.WWPGRKXHTUFWR/VSCEZO.ZQKVJCDMFMXG+NG-BFVK.-+THEUAHA.U Line truncated
// expectedMatch: /31 05 : a3108/,
// recipeConfig: [
// {
// "op": "Colossus",
// "args": [
// "",
// "KH Pattern",
// "ΔZ", "ΔΧ", "",
// "None", "Select Program", "1+2=. (1+2 Break In, Find X1,X2)",
// "",
// "", "", "", "", "", false, "",
// "", "", "", "", "", false, "",
// "", "", "", "", "", false, "",
// false,
// "",
// false, false, false, false, false,
// "", false, false, "",
// "",
// 3100, "X1", "X2",
// "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1"
// ]
// }
// ]
// },
// {
// name: "Colossus 4=5=/1=2",
// input: "CTBKJUVXHZ-H3L4QV+YEZUK+SXOZ/NNLH+WBFSBMJM-E3LMTPYJ.ZJDYI3TZZFVRP+REWQYOQMU3FNW.T4WB3IEPCJ-A3LWVRSZZECNGQVUFHO.R/3VZRF.Y4XEDGXZJ3RS34ARLZDZTUHMG+HH//Y+E+C-NE+--GEATU+EPEVLQEMKCLCZP-HX3C3O+CRH4D-RLIVOLHJGNI./MN4JDB/PRYZV3QOD34DAGO4+/TCS+CU-ODXMRHPPCCCD-MWHJO/TRPAELREIFVVLABSDMQORF4THY.UQTITEPYXAZ3DPNI/I+.UPTCBT-BJ/PEQFZA/PQ4+Z4-IPLBG4COART/YC4CJL+ERNVTRSHOKNSSLGFJ+QJR/ITYHWFQCPXCY.Z.X/VKTAR.LBXQK4JI/P+YDEM/LPBLK.CX/..QHBSOAO-FHJORYVBHQEYTF3/I-WZ4J.EYCYTEMG3DY3W/4VSE3/XAR3JEX4/3/LI4V/IAVLTODE-4HPLWUWMC.YEJOVFZ+/4EAIJXUT+G/.KYQF4DSVSIPLWZE.XTZWD4E.EYI/.MBJ+SVX/GBW/4RTNSGT-TF-+-JO3UE/3ZVEQKYVCUR+-3OMC+YU+UGMBCOO4.GRHVG.3+ZFB4C3J+QWCR+DHKQ3XFTUKTBGVXEQ.PCU4XLW-G+RJODDYLIJVSXOJUGKTVNBGMPH4DI+--+DKJ.MYBDX4LUWAXD-+P3.FCBWGDZQSQMPNBAODZMMM/CS3AJHEGDNZT4+.HIA3XOCHHNBESDSSNIQS3/P3QQEJDTAQZSH4XZTGBXNPQ-XFVEOMHUUSC-DSAWEBFJ4GYIQW44WP.W-IMGHZCJY/TLBWZVMNU/CETWAF3TBPIRLWDR+.WJBBYEQ.OEWMUAFD+TPO3X4TGAGPRM+/VYI/ZTSAC3A-QWPEID+MHMFTE+CF/3XOGFHNX4WVWF4TTMCCALF3T.VY4PYBCMLQ.MZRVPSA+YQL+XCY.-SEN-CZUCRCZ/PNBE4.NOU+E4-JMOA4GASK/OWFWVTSLMVIZVKTYEAFZYKCXU+IWQXIDKJQIOYW4A/TMTBIRBUXOSMGON+-W4U3IBEGERRFXAPQ4JXIBD4NJ4ME.DDRSQU+KJPHZ/+3TPKV-OKD3SBRDE4WZIVVZLXJWWL/SK/.JXF.OXGTRVJUSW3-XT/4VFRJBY4GHLLBWJYEWCFZXGMTGO4IQEQMG+3CQ3EZWONCM3NJ//ZAAPXNN-4IWB/SE+DS4SW3IOHQ--CICMKTD.AM/K-ABSCPD+VWXKKVN/3PUA+NEOZA.WWUKW+ZDTUAR/BI.PGVRFUS-/US.RSDTHGKESVB.GWGGVDHKFW4/FWPN.SDRL+GRZ/KM+.R-DHP+QC//EE/OGG+YVJ.GHDFFIXUEEOLIMC.C-4X4M-GT3DBBXANM/FER+QL3ZS/4IFSI-L.Y+KXMMR-HMCRUTZQ-LCLERSQLBMYXK.FUVKY-IA+-DDNQEE-TEDWUIB3CJYE4DMT3YPPA..AKQWSX.YT/JHFIJS/+/./+GNIRKAN/USYL4SW/BL.BNTRCFJPT.FMBZLEREFYJ/OXXQIXT-/T+IBMUNWL-JG-+ORJYJLOVZBJDKO4QJFFE.TPJGLY/.VTU-4IZBKGVBSAGWIN/N.-EK.JOWD/GYY3/SJFCYEKY/HW.O.VXTPSZVSHUA3N3QIX-+APJR43WQ+I.A/L+3/GOL.MW//KS.3Q4+3LEDVY+VDPOG+DJXHJFXBRK3SV.MPZE+/NLIA4NFEJPXYWYUUKX/UYWGU-4VF4OV4RZL.HKMRTQ/MHB/ND/VWO4ZIN/4D+ZX.PZZ.+WOCNENNZVI-IENILU.ZSHUJKIOFY3YJJA3IVRMNWENA3FQLQ4U+RKXR.IFKWEFX/VZGOUO4MYT/.PS3..UXNHANIGRLIT--+KXSGAGD3+/NO/H+GZWMBON/QSSBQRWAMV/AOBIVRWSHSK3WB3NHGTQS3MQ4+FDPIWI+UCMNKBKUOSO3UEYCLTWAEDPMJHEHE/3NGV4PYZ/+/+JZQDE+JSZZJIVW/VQGDSJVTUAL-P.K+VJRZ3NFPXUCZYA3.LNAOTBW3ATPUAUYN-J4MM3OAQTMUYICXNF-ON-L++K3RMPSX.CESSNUNJIZANHFSYTJ.XIFPJAYQMNC/QTIB.WWJ/.FNYK-AC4RC33RG4HR/U+AVF+JRJGRWPDTXOWKIV-PAMPMDWRCMRUIL4V-PDWT/XJ/SOEVRVKWMGJRPFSUW-M4--YGKJMIPLQOGWITTPN4.W+L.IVWRTY.-.FIPG4WNJFRHYOVW3OAYPJP/DJJIAMRZOU+Z/CIHUCPVT3BCLCJVACJLLQL.L4VL.Z+PSVNE-IUK.OJKNOWHKGCNZ3REIWHKEO/I.-3ZSJMN-WGPADSAAJ.-I/WKMSHGVTHI+ITSIIHZBSPUW-EIYDKT4ABEC.IMDTVET+SC.PEH4JOWDLPKPZV+UXKT/FJK+UACWJCMY+YSRYKREN/PAB+SSATQBYQ/T.Z..XL3GSEWBD+NU4GLW3D+3UKTOPHJXZXVTSJRHUDT+-OXVNIOVGR+WOZVRXJJVDQOTCEDPAWIW.VEB/-4HLHBBHCFZ+HKXA.-FJCIIHVBXRGTHEDQHCAF-/-IX3LFEM-U+QN.F3OW+IHFPM43MZ.AYMYLWUANNDOICHUJD/PKA/T-U.LACC.OFVPGYCTWO-L4PSQCWZCTOVO3JNQOY/C/4JSZZTKA4DOSH.HLQ3CGVVF4R+YURIHX4.+KMMGO-TQWVHB/P4.ZMDJZGOFAESJNWKWLV3VQROPQMZ3Q.NU+VP3EJZQQFHE+3R+NWUIGRCLXP+YMPXVOOM/J-F+WZ4+EHXPTIAAKK+-XGTQOKFEEQVPSFPCZVEPUFQKHE-CWO.BJ-.APVNMYPEA-+EQERVDPT4HDGNGCI-K-+/QOFDLSANMCRLACCRVIJBTKJG.BXNACOLKYELBL.XO+UG+CEPNLVQKR+IEYX4M/DI.RK//RAEGPMDQM/RYKF.ZULT3DLX+QW/NLZWOFFIJ3DUP+UXTSMQZZEOOYEDD+Q4KLQRE.4+FRUMDLGRXIKAD3HPEOL.QBPIHYMCSS.KMMBRSKDKK4CLH4GBSZBGHBGG/QGOT-QDI/JTED-KT+AVI-AGOXTS+I-HSG/4UYS/F.V3GC.MKCVMNLOY.MJXN/B+DRHD.KQ.RSJKIN3U.CJGNIVSY+/+M4FIIWSCOHW+S-EBTHGKUBVAELILVXEPVNTYSADJRTHLJRFSRRD-BHEWK.DWPQFQMVO.EPIV+4CBHCUNEUESRFLMTEWAEVMVEEQYSXGAHZCTTQRE.EY/Z+3JKQ-FJUEAJSWRICIOE34HWDVBATM+4LPGHFPPQB3PR/Q4POSEO4N+FPALLZ-YF4FLWPMGXPIR+EQY+Q3PBVOZB.CDNDP3-.ZVPS4ITTUDUFSZD4-CO/EEIZFIE.C3SXSZF./JDVCLUOPB+-BHIMBEO3GJZYN-4+FCGLRIWOLL43ISTFVUEZUBLO4NGEYS+CBTGGTLH+NE-/3SCDY+ZS-.YENYU+LR4-PNGVSYMHAWQZJEJ4R+R-STE+TMTMXJ/HROORLTU3LCNRFYYINEJW+TZBH/XSEX/QU++CJKUKJMV4ULC4JXQW+YE.Y-YDJHHF.ATHTN+/BZP-B/AZPFHSSWVNWI/LDUHVHUWU.KPAR-.A-TM3.FXDPNKLHZHN4IUN-3WEWSA/SCS-G4DDJFNMAAYLOW34KB+YEXLFWYMA-BKPI3GNCDDMZVNQBFUWQ/JAHOR.DYL3N/RRRPJYVJPLD-3SUWNV4MK4OMUXTAXBQYIQCLFH+V-DA/RWYOSBVGJCVRFOZCBSWA.XW-OLXJBNHTSPHSCYH+.4+RXBWCFVF3O.+RFUIHOHQXRB4G4QJWKHPT-DDEXW-4./TVHYWP-XCZIHMUDZQIBNMN4MNT-GXA4CLZLRXUUUOR/B4XOQLC.IZOM.PAUEXRJ.GRNBQGRZUQ.ISWES/YMK+AWCTQ4+-WKKA4HZ-/..XTPDBWOA3EQEDVPMN4BXHBGCGWBPOCHIYWE4NP3ILIQP.GCZA/FEKTEOML+COOF/TVMQ3WSDKG//EEXOI-/SGFTWKOG+D.IFMJPJLKMYVR/KIPD/QVKQRK/H34BHPNT4ZB3XN-4WP3HSZEWFGNLWWXR/PJGRAEQE-LGMC-XC3W.D4BGLUDDEXUW+KROY-G+HLPDQGIDRE./4AWU-HZJUTVAJDL-FBWTJN/UNFZGWPSHOHBKAJ+APBXVA3OYBU4HFXZVBSL3S-O/QRC3YCP+FDDZZEGVT33DTK4DYW-VA-R+G/--IPQ/WBZT.SLOCHE3PHQNTIIYA.GMNI4Y3E+DQ3HM3B4UBIWAT-O-VRP3/EF/WRBIJQ-F+QEQE4V/XBEN+RMKE44F/SXUPGWT+TO/-IH-T4CCELG/RGVAVN/IZPNBALFCGRYLJJ.QYAJHPBNCBBHOALK4RSQEFVA4I.VG.WFW-MGH.3RHDXFJMIMRPK-RK/X3T4TLKPUAOCIYRH/LNBEI.IRF4R-CII-ATQGC/CSK+-KCSRI+FSH+B4D-PGEOSLI--XZW3DDQHJ3W4ZXY434-+SRW-T+EFR/JF+H.SO33REUDV+--4ZETOYTXFZS4AZDFTJNIUK.P+AYDAWLHGUC3E.I/NORSMWLZQEFQUGI3A+.WA.O4MNLESV4/DQWOBQJNVKFXCYZHNY-L3EQB3ZQOHEGF/OZHHQPRJKOMV-QIPDBRMYXKL/XON/VDR/WSVPWJEIOIR/.PJZPYIK+JQOZY-XXOCIPLRHBZL.CGJWBQ+MWXKNOFXMS.RUK+A4NFJAFYEKE.AZWXJNCP3BTFOA+ZUL.RHTX-SV4LPY+VOCHEPQDFWQFIAKYG+U4YDK.EPZPTQGHGTJZTBGW4GVFSYG4XJ-C.WWPGRKXHTUFWR/VSCEZO.ZQKVJCDMFMXG+NG-BFVK.-+THEUAHA.U Line truncated
// expectedMatch: /15 08 : a969/,
// recipeConfig: [
// {
// "op": "Colossus",
// "args": [
// "",
// "KH Pattern",
// "ΔZ", "ΔΧ", "",
// "None", "Select Program", "4=5=/1=2 (Given X1,X2 find X4,X5)",
// "",
// "", "", "", "", "", false, "",
// "", "", "", "", "", false, "",
// "", "", "", "", "", false, "",
// false,
// "",
// false, false, false, false, false,
// "", false, false, "",
// "",
// 960, "X4", "X5",
// "31", "5", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1"
// ]
// }
// ]
// },
]);
+153 -10
View File
@@ -25,15 +25,18 @@ TestRegister.addTests([
*
* from Crypto.Cipher import AES
* import binascii
*
* input_data = "0123456789ABCDEF"
* key = binascii.unhexlify("00112233445566778899aabbccddeeff")
* iv = binascii.unhexlify("ffeeddccbbaa99887766554433221100")
* aad = b'additional data'
*
* cipher = AES.new(key, AES.MODE_GCM, nonce=iv)
* cipher.update(aad)
* cipher_text, tag = cipher.encrypt_and_digest(binascii.unhexlify(input_data))
*
* cipher = AES.new(key, AES.MODE_GCM, nonce=iv)
* cipher.update(aad)
* decrypted = cipher.decrypt_and_verify(cipher_text, tag)
*
* key = binascii.hexlify(key).decode("UTF-8")
@@ -42,7 +45,7 @@ TestRegister.addTests([
* tag = binascii.hexlify(tag).decode("UTF-8")
* decrypted = binascii.hexlify(decrypted).decode("UTF-8")
*
* print("Key: {}\nIV : {}\nInput data: {}\n\nEncrypted ciphertext: {}\nGCM tag: {}\n\nDecrypted plaintext : {}".format(key, iv, input_data, cipher_text, tag, decrypted))
* print("Key: {}\nIV : {}\nInput data: {}\nAAD: {}\n\nEncrypted ciphertext: {}\nGCM tag: {}\n\nDecrypted plaintext : {}".format(key, iv, input_data, aad, cipher_text, tag, decrypted))
*
*
* Outputs:
@@ -192,7 +195,24 @@ Tag: 16a3e732a605cc9ca29108f742ca0743`,
"args": [
{"option": "Hex", "string": "00112233445566778899aabbccddeeff"},
{"option": "Hex", "string": ""},
"GCM", "Raw", "Hex"
"GCM", "Raw", "Hex", ""
]
}
],
},
{
name: "AES Encrypt: AES-128-GCM, ASCII, AAD",
input: "The quick brown fox jumps over the lazy dog.",
expectedOutput: `daa58faa056c52756aa488aeafbd265b6effcf4eca58220a97b0005b1a9b1e1c9e7a6725d35f5f79b9493de7
Tag: 3b5378917f67b0aade9891fc6c291646`,
recipeConfig: [
{
"op": "AES Encrypt",
"args": [
{"option": "Hex", "string": "00112233445566778899aabbccddeeff"},
{"option": "Hex", "string": "ffeeddccbbaa99887766554433221100"},
"GCM", "Raw", "Hex", "additional data"
]
}
],
@@ -269,7 +289,24 @@ Tag: 70fad2ca19412c20f40fd06918736e56`,
"args": [
{"option": "Hex", "string": "51e201d463698ef5f717f71f5b4712af"},
{"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
"GCM", "Hex", "Hex"
"GCM", "Hex", "Hex", ""
]
}
],
},
{
name: "AES Encrypt: AES-128-GCM, Binary, AAD",
input: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
expectedOutput: `5a29debb5c5f38cdf8aee421bd94dbbf3399947faddf205f88b3ad8ecb0c51214ec0e28bf78942dfa212d7eb15259bbdcac677b4c05f473eeb9331d74f31d441d97d56eb5c73b586342d72128ca528813543dc0fc7eddb7477172cc9194c18b2e1383e4e
Tag: 61cc4b70809452b0b3e38f913fa0a109`,
recipeConfig: [
{
"op": "AES Encrypt",
"args": [
{"option": "Hex", "string": "51e201d463698ef5f717f71f5b4712af"},
{"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
"GCM", "Hex", "Hex", "additional data"
]
}
],
@@ -361,7 +398,24 @@ Tag: 86db597d5302595223cadbd990f1309b`,
"args": [
{"option": "Hex", "string": "6801ed503c9d96ee5f9d78b07ab1b295dba3c2adf81c7816"},
{"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
"GCM", "Hex", "Hex"
"GCM", "Hex", "Hex", ""
]
}
],
},
{
name: "AES Encrypt: AES-192-GCM, Binary, AAD",
input: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
expectedOutput: `318b479d919d506f0cd904f2676fab263a7921b6d7e0514f36e03ae2333b77fa66ef5600babcb2ee9718aeb71fc357412343c1f2cb351d8715bb0aedae4a6468124f9c4aaf6a721b306beddbe63a978bec8baeeba4b663be33ee5bc982746bd4aed1c38b
Tag: aeedf3e6ca4201577c0cf3e9ce58159d`,
recipeConfig: [
{
"op": "AES Encrypt",
"args": [
{"option": "Hex", "string": "6801ed503c9d96ee5f9d78b07ab1b295dba3c2adf81c7816"},
{"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
"GCM", "Hex", "Hex", "additional data"
]
}
],
@@ -453,7 +507,24 @@ Tag: 821b1e5f32dad052e502775a523d957a`,
"args": [
{"option": "Hex", "string": "2d767f6e9333d1c77581946e160b2b7368c2cdd5e2b80f04ca09d64e02afbfe1"},
{"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
"GCM", "Hex", "Hex"
"GCM", "Hex", "Hex", ""
]
}
],
},
{
name: "AES Encrypt: AES-256-GCM, Binary, AAD",
input: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
expectedOutput: `1287f188ad4d7ab0d9ff69b3c29cb11f861389532d8cb9337181da2e8cfc74a84927e8c0dd7a28a32fd485afe694259a63c199b199b95edd87c7aa95329feac340f2b78b72956a85f367044d821766b1b7135815571df44900695f1518cf3ae38ecb650f
Tag: a8f04c4d93bbef82bef61a103371aef9`,
recipeConfig: [
{
"op": "AES Encrypt",
"args": [
{"option": "Hex", "string": "2d767f6e9333d1c77581946e160b2b7368c2cdd5e2b80f04ca09d64e02afbfe1"},
{"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
"GCM", "Hex", "Hex", "additional data"
]
}
],
@@ -805,7 +876,25 @@ The following algorithms will be used based on the size of the key:
{"option": "Hex", "string": "00112233445566778899aabbccddeeff"},
{"option": "Hex", "string": ""},
"GCM", "Hex", "Raw",
{"option": "Hex", "string": "16a3e732a605cc9ca29108f742ca0743"}
{"option": "Hex", "string": "16a3e732a605cc9ca29108f742ca0743"},
""
]
}
],
},
{
name: "AES Decrypt: AES-128-GCM, ASCII, AAD",
input: "daa58faa056c52756aa488aeafbd265b6effcf4eca58220a97b0005b1a9b1e1c9e7a6725d35f5f79b9493de7",
expectedOutput: "The quick brown fox jumps over the lazy dog.",
recipeConfig: [
{
"op": "AES Decrypt",
"args": [
{"option": "Hex", "string": "00112233445566778899aabbccddeeff"},
{"option": "Hex", "string": "ffeeddccbbaa99887766554433221100"},
"GCM", "Hex", "Raw",
{"option": "Hex", "string": "3b5378917f67b0aade9891fc6c291646"},
"additional data"
]
}
],
@@ -885,7 +974,25 @@ The following algorithms will be used based on the size of the key:
{"option": "Hex", "string": "51e201d463698ef5f717f71f5b4712af"},
{"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
"GCM", "Hex", "Hex",
{"option": "Hex", "string": "70fad2ca19412c20f40fd06918736e56"}
{"option": "Hex", "string": "70fad2ca19412c20f40fd06918736e56"},
""
]
}
],
},
{
name: "AES Decrypt: AES-128-GCM, Binary, AAD",
input: "5a29debb5c5f38cdf8aee421bd94dbbf3399947faddf205f88b3ad8ecb0c51214ec0e28bf78942dfa212d7eb15259bbdcac677b4c05f473eeb9331d74f31d441d97d56eb5c73b586342d72128ca528813543dc0fc7eddb7477172cc9194c18b2e1383e4e",
expectedOutput: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
recipeConfig: [
{
"op": "AES Decrypt",
"args": [
{"option": "Hex", "string": "51e201d463698ef5f717f71f5b4712af"},
{"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
"GCM", "Hex", "Hex",
{"option": "Hex", "string": "61cc4b70809452b0b3e38f913fa0a109"},
"additional data"
]
}
],
@@ -981,7 +1088,25 @@ The following algorithms will be used based on the size of the key:
{"option": "Hex", "string": "6801ed503c9d96ee5f9d78b07ab1b295dba3c2adf81c7816"},
{"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
"GCM", "Hex", "Hex",
{"option": "Hex", "string": "86db597d5302595223cadbd990f1309b"}
{"option": "Hex", "string": "86db597d5302595223cadbd990f1309b"},
""
]
}
],
},
{
name: "AES Decrypt: AES-192-GCM, Binary, AAD",
input: "318b479d919d506f0cd904f2676fab263a7921b6d7e0514f36e03ae2333b77fa66ef5600babcb2ee9718aeb71fc357412343c1f2cb351d8715bb0aedae4a6468124f9c4aaf6a721b306beddbe63a978bec8baeeba4b663be33ee5bc982746bd4aed1c38b",
expectedOutput: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
recipeConfig: [
{
"op": "AES Decrypt",
"args": [
{"option": "Hex", "string": "6801ed503c9d96ee5f9d78b07ab1b295dba3c2adf81c7816"},
{"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
"GCM", "Hex", "Hex",
{"option": "Hex", "string": "aeedf3e6ca4201577c0cf3e9ce58159d"},
"additional data"
]
}
],
@@ -1077,7 +1202,25 @@ The following algorithms will be used based on the size of the key:
{"option": "Hex", "string": "2d767f6e9333d1c77581946e160b2b7368c2cdd5e2b80f04ca09d64e02afbfe1"},
{"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
"GCM", "Hex", "Hex",
{"option": "Hex", "string": "821b1e5f32dad052e502775a523d957a"}
{"option": "Hex", "string": "821b1e5f32dad052e502775a523d957a"},
""
]
}
],
},
{
name: "AES Decrypt: AES-256-GCM, Binary, AAD",
input: "1287f188ad4d7ab0d9ff69b3c29cb11f861389532d8cb9337181da2e8cfc74a84927e8c0dd7a28a32fd485afe694259a63c199b199b95edd87c7aa95329feac340f2b78b72956a85f367044d821766b1b7135815571df44900695f1518cf3ae38ecb650f",
expectedOutput: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
recipeConfig: [
{
"op": "AES Decrypt",
"args": [
{"option": "Hex", "string": "2d767f6e9333d1c77581946e160b2b7368c2cdd5e2b80f04ca09d64e02afbfe1"},
{"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
"GCM", "Hex", "Hex",
{"option": "Hex", "string": "a8f04c4d93bbef82bef61a103371aef9"},
"additional data"
]
}
],
+17 -6
View File
@@ -345,7 +345,7 @@ TestRegister.addTests([
recipeConfig: [
{
"op": "Snefru",
"args": ["2", "128"]
"args": ["128", "2"]
}
]
},
@@ -356,7 +356,7 @@ TestRegister.addTests([
recipeConfig: [
{
"op": "Snefru",
"args": ["4", "128"]
"args": ["128", "4"]
}
]
},
@@ -367,7 +367,7 @@ TestRegister.addTests([
recipeConfig: [
{
"op": "Snefru",
"args": ["8", "128"]
"args": ["128", "8"]
}
]
},
@@ -378,7 +378,7 @@ TestRegister.addTests([
recipeConfig: [
{
"op": "Snefru",
"args": ["2", "256"]
"args": ["256", "2"]
}
]
},
@@ -389,7 +389,7 @@ TestRegister.addTests([
recipeConfig: [
{
"op": "Snefru",
"args": ["4", "256"]
"args": ["256", "4"]
}
]
},
@@ -400,7 +400,18 @@ TestRegister.addTests([
recipeConfig: [
{
"op": "Snefru",
"args": ["8", "256"]
"args": ["256", "8"]
}
]
},
{
name: "SM3 256 64",
input: "Hello, World!",
expectedOutput: "7ed26cbf0bee4ca7d55c1e64714c4aa7d1f163089ef5ceb603cd102c81fbcbc5",
recipeConfig: [
{
"op": "SM3",
"args": ["256", "64"]
}
]
},
+12 -1
View File
@@ -11,7 +11,18 @@ TestRegister.addTests([
{
name: "Haversine distance",
input: "51.487263,-0.124323, 38.9517,-77.1467",
expectedOutput: "5619355.701829259",
expectedOutput: "5902542.836307819",
recipeConfig: [
{
"op": "Haversine distance",
"args": []
}
],
},
{
name: "Haversine distance, zero distance",
input: "51.487263,-0.124323, 51.487263,-0.124323",
expectedOutput: "0",
recipeConfig: [
{
"op": "Haversine distance",
+66
View File
@@ -89,5 +89,71 @@ TestRegister.addTests([
args: [",", "\\r\\n"]
},
],
},
{
name: "JSON to CSV: nested JSON",
input: JSON.stringify({a: 1, b: {c: 2, d: 3}}),
expectedOutput: "a,b.c,b.d\r\n1,2,3\r\n",
recipeConfig: [
{
op: "JSON to CSV",
args: [",", "\\r\\n"]
},
],
},
{
name: "JSON to CSV: nested array",
input: JSON.stringify({a: 1, b: [2, 3]}),
expectedOutput: "a,b.0,b.1\r\n1,2,3\r\n",
recipeConfig: [
{
op: "JSON to CSV",
args: [",", "\\r\\n"]
},
],
},
{
name: "JSON to CSV: nested JSON, nested array",
input: JSON.stringify({a: 1, b: {c: [2, 3], d: 4}}),
expectedOutput: "a,b.c.0,b.c.1,b.d\r\n1,2,3,4\r\n",
recipeConfig: [
{
op: "JSON to CSV",
args: [",", "\\r\\n"]
},
],
},
{
name: "JSON to CSV: nested array, nested JSON",
input: JSON.stringify({a: 1, b: [{c: 3, d: 4}]}),
expectedOutput: "a,b.0.c,b.0.d\r\n1,3,4\r\n",
recipeConfig: [
{
op: "JSON to CSV",
args: [",", "\\r\\n"]
},
],
},
{
name: "JSON to CSV: nested array, nested array",
input: JSON.stringify({a: 1, b: [[2, 3]]}),
expectedOutput: "a,b.0.0,b.0.1\r\n1,2,3\r\n",
recipeConfig: [
{
op: "JSON to CSV",
args: [",", "\\r\\n"]
},
],
},
{
name: "JSON to CSV: nested JSON, nested JSON",
input: JSON.stringify({a: 1, b: { c: { d: 2, e: 3}}}),
expectedOutput: "a,b.c.d,b.c.e\r\n1,2,3\r\n",
recipeConfig: [
{
op: "JSON to CSV",
args: [",", "\\r\\n"]
},
],
}
]);
+1 -24
View File
@@ -6,30 +6,7 @@
* @license Apache-2.0
*/
import TestRegister from "../../lib/TestRegister.mjs";
const ASCII_TEXT = "A common mistake that people make when trying to design something completely foolproof is to underestimate the ingenuity of complete fools.";
const UTF8_TEXT = "Шанцы на высвятленне таго, што адбываецца на самай справе ў сусвеце настолькі выдаленыя, адзінае, што трэба зрабіць, гэта павесіць пачуццё яго і трымаць сябе занятымі.";
const ALL_BYTES = [
"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
"\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f",
"\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f",
"\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f",
"\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f",
"\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f",
"\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f",
"\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f",
"\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f",
"\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf",
"\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf",
"\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf",
"\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf",
"\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef",
"\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
].join("");
import {ASCII_TEXT, UTF8_TEXT, ALL_BYTES} from "../samples/Ciphers.mjs";
// RSA-1024
const ALICE_PRIVATE = `-----BEGIN PGP PRIVATE KEY BLOCK-----
+350
View File
@@ -0,0 +1,350 @@
/**
* RSA tests.
*
* @author Matt C [me@mitt.dev]
* @copyright Crown Copyright 2020
* @license Apache-2.0
*/
import TestRegister from "../../lib/TestRegister.mjs";
import {ASCII_TEXT, UTF8_TEXT, ALL_BYTES} from "../samples/Ciphers.mjs";
const PEM_PRIV_2048 = `-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAwfaUOpUEutKyU3wkCv6kYunz4MqxzSuTSckRz1IxwZtwIiqq
+ejkM6ioXPyGadfFNvG0JVOgr1q4KQglq0vXaYG57HZ8iinXnHgy1vr8i+fWYITB
RMrEDySaQh3sxVj8NudPDoTIxZwUcIUu/N53pUmI08ADxXPA+ZymPyZhZyxrj5Jq
2O2QuRu+R7K44NDweP/rETbGo5+QAPydm6UqBzTky/ohv6EGhjyqnaskTWwLWK6P
dKva8rEMb8nNJvhoTJDLYUfNjB7DFnWxgWuR/KVkXGAHX99J/wh6QTS+bsyJ2/Mw
Df6NWdh3iP7msLNl/GqL+HunhHjrthvvWlODDwIDAQABAoIBAApKwLvJC3q0UmUO
qcTxlRxwiJHNf5jA7qxUIH9NP7mju1P8ypy/KFi7Ys+oUKOOIPdU5Pe0E8sqN6pp
tcH8oL4G9awf72TPapLxZ9UzdTIhR6VQdgbl8XhSO2M1vkoMejmZlX7SOesOaKE9
1+vwDA43tCx0PF7+UOeN0d549WMphvw3VkSInO/MYpobCGra4YdrhYOhFMyLEGgA
zCyVUOxi538tyyFtK2EEQdcMtvVA6SECjF4xD/qrme0LelIj/L1Uhiu+SOzYt4y+
QLHL6zhJVfOejWxjeI7BhodkTV2D53n4svfizRgyYEb6iLPW3nlMYIlAksYaxxB9
nR3sMHECgYEA9RU+8J5A8RnBcwnlc2X1xEW2PN7+A1MeWPQwFqRwIokgvGbCtwjG
PwwNUYJCTBhfGhsISeCBOSYrDGTHsNH+tqFW2zlq61BolYl56jb1KgWzMOX8dak4
sgXIuBbvyuFNk08VMIzwcA76ka/Iuu/nN9ZOM2UYpdpGG+CTOoIFULECgYEAyppm
I+yAtrUn/BFmwmC8va4vqXlBFjvdkfX/71ywCpHIouLucMV7bILJu0nSCpmL1A7R
DT6qo0p5g+Dxl/+O2VyC5D89PBvcuT1+HtEZGLOoKZnojbSrwDApGbzQi57GoQR6
/SRjsdAmoelY8PFz2s2ZLJ4NkrZXYvkT1Tu8/78CgYEA4MAvC/HUlEWORbTZmk3y
Z5+WU5QbVWkv91tXjiwWOVWPk7aY8ck2JDMlM45ExgvDiuknXLhpSMNbzu3MwraQ
42JpiHjLOChxAFEmYEct5O99OGZwcmZQ+9CaFVfTZzXeMizfvbpB9EGIP3n4lpXS
cD4zUKZxSAc3K/FyksERpsECgYEAhQPXeVBltQ68oKaAE6/VWqcIjbiY/dLyBkk+
7dSpk1bhJefdadaN0NERRtARgXoLrn7Hy21QNILJwsaldwiGrbgqC1Zlipg0Ur3H
ls3rLyeMiTuNzbNHa5dy9H3dYT0t5Tr+0EHa3jvtkTGVfiLX0FhZb0yZVrA2MTmc
RsvAqxsCgYAgXy4qytgfzo5/bBt306NbtMEW3dWBWF77HAz4N1LynKZRUrAAK4rz
BVmXFUaNQOg0q8WJG+iFF79u2UnL8iZ5GoPMcpvifsZgef1OHnQnFrfyXSr0fXIm
xq8eZS0DpLvKGffCW03B9VDRHanE37Tng8lbgOtaufuVzFa1bCuLUA==
-----END RSA PRIVATE KEY-----`;
const PEM_PUB_2048 = `-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwfaUOpUEutKyU3wkCv6k
Yunz4MqxzSuTSckRz1IxwZtwIiqq+ejkM6ioXPyGadfFNvG0JVOgr1q4KQglq0vX
aYG57HZ8iinXnHgy1vr8i+fWYITBRMrEDySaQh3sxVj8NudPDoTIxZwUcIUu/N53
pUmI08ADxXPA+ZymPyZhZyxrj5Jq2O2QuRu+R7K44NDweP/rETbGo5+QAPydm6Uq
BzTky/ohv6EGhjyqnaskTWwLWK6PdKva8rEMb8nNJvhoTJDLYUfNjB7DFnWxgWuR
/KVkXGAHX99J/wh6QTS+bsyJ2/MwDf6NWdh3iP7msLNl/GqL+HunhHjrthvvWlOD
DwIDAQAB
-----END PUBLIC KEY-----`;
TestRegister.addTests([
{
name: "RSA Encrypt/Decrypt: RSA-OAEP/SHA-1, nothing",
input: "",
expectedOutput: "",
recipeConfig: [
{
"op": "RSA Encrypt",
"args": [PEM_PUB_2048, "RSA-OAEP", "SHA-1"]
},
{
"op": "RSA Decrypt",
"args": [PEM_PRIV_2048, "", "RSA-OAEP", "SHA-1"]
}
]
},
{
name: "RSA Encrypt/Decrypt: RSA-OAEP/SHA-1, ASCII",
input: ASCII_TEXT,
expectedOutput: ASCII_TEXT,
recipeConfig: [
{
"op": "RSA Encrypt",
"args": [PEM_PUB_2048, "RSA-OAEP", "SHA-1"]
},
{
"op": "RSA Decrypt",
"args": [PEM_PRIV_2048, "", "RSA-OAEP", "SHA-1"]
}
]
},
{
name: "RSA Encrypt/Decrypt: RSA-OAEP/SHA-1, UTF-8",
input: UTF8_TEXT.substr(0, 100),
expectedOutput: UTF8_TEXT.substr(0, 100),
recipeConfig: [
{
"op": "RSA Encrypt",
"args": [PEM_PUB_2048, "RSA-OAEP", "SHA-1"]
},
{
"op": "RSA Decrypt",
"args": [PEM_PRIV_2048, "", "RSA-OAEP", "SHA-1"]
}
]
},
{
name: "RSA Encrypt/Decrypt: RSA-OAEP/SHA-1, All bytes",
input: ALL_BYTES.substr(0, 100),
expectedOutput: ALL_BYTES.substr(0, 100),
recipeConfig: [
{
"op": "RSA Encrypt",
"args": [PEM_PUB_2048, "RSA-OAEP", "SHA-1"]
},
{
"op": "RSA Decrypt",
"args": [PEM_PRIV_2048, "", "RSA-OAEP", "SHA-1"]
}
]
},
{
name: "RSA Encrypt/Decrypt: RSA-OAEP/MD5, nothing",
input: "",
expectedOutput: "",
recipeConfig: [
{
"op": "RSA Encrypt",
"args": [PEM_PUB_2048, "RSA-OAEP", "MD5"]
},
{
"op": "RSA Decrypt",
"args": [PEM_PRIV_2048, "", "RSA-OAEP", "MD5"]
}
]
},
{
name: "RSA Encrypt/Decrypt: RSA-OAEP/MD5, ASCII",
input: ASCII_TEXT,
expectedOutput: ASCII_TEXT,
recipeConfig: [
{
"op": "RSA Encrypt",
"args": [PEM_PUB_2048, "RSA-OAEP", "MD5"]
},
{
"op": "RSA Decrypt",
"args": [PEM_PRIV_2048, "", "RSA-OAEP", "MD5"]
}
]
},
{
name: "RSA Encrypt/Decrypt: RSA-OAEP/MD5, UTF-8",
input: UTF8_TEXT.substr(0, 100),
expectedOutput: UTF8_TEXT.substr(0, 100),
recipeConfig: [
{
"op": "RSA Encrypt",
"args": [PEM_PUB_2048, "RSA-OAEP", "MD5"]
},
{
"op": "RSA Decrypt",
"args": [PEM_PRIV_2048, "", "RSA-OAEP", "MD5"]
}
]
},
{
name: "RSA Encrypt/Decrypt: RSA-OAEP/MD5, All bytes",
input: ALL_BYTES.substr(0, 100),
expectedOutput: ALL_BYTES.substr(0, 100),
recipeConfig: [
{
"op": "RSA Encrypt",
"args": [PEM_PUB_2048, "RSA-OAEP", "MD5"]
},
{
"op": "RSA Decrypt",
"args": [PEM_PRIV_2048, "", "RSA-OAEP", "MD5"]
}
]
},
{
name: "RSA Encrypt/Decrypt: RSA-OAEP/SHA-256, nothing",
input: "",
expectedOutput: "",
recipeConfig: [
{
"op": "RSA Encrypt",
"args": [PEM_PUB_2048, "RSA-OAEP", "SHA-256"]
},
{
"op": "RSA Decrypt",
"args": [PEM_PRIV_2048, "", "RSA-OAEP", "SHA-256"]
}
]
},
{
name: "RSA Encrypt/Decrypt: RSA-OAEP/SHA-256, ASCII",
input: ASCII_TEXT,
expectedOutput: ASCII_TEXT,
recipeConfig: [
{
"op": "RSA Encrypt",
"args": [PEM_PUB_2048, "RSA-OAEP", "SHA-256"]
},
{
"op": "RSA Decrypt",
"args": [PEM_PRIV_2048, "", "RSA-OAEP", "SHA-256"]
}
]
},
{
name: "RSA Encrypt/Decrypt: RSA-OAEP/SHA-256, UTF-8",
input: UTF8_TEXT.substr(0, 100),
expectedOutput: UTF8_TEXT.substr(0, 100),
recipeConfig: [
{
"op": "RSA Encrypt",
"args": [PEM_PUB_2048, "RSA-OAEP", "SHA-256"]
},
{
"op": "RSA Decrypt",
"args": [PEM_PRIV_2048, "", "RSA-OAEP", "SHA-256"]
}
]
},
{
name: "RSA Encrypt/Decrypt: RSA-OAEP/SHA-256, All bytes",
input: ALL_BYTES.substr(0, 100),
expectedOutput: ALL_BYTES.substr(0, 100),
recipeConfig: [
{
"op": "RSA Encrypt",
"args": [PEM_PUB_2048, "RSA-OAEP", "SHA-256"]
},
{
"op": "RSA Decrypt",
"args": [PEM_PRIV_2048, "", "RSA-OAEP", "SHA-256"]
}
]
},
{
name: "RSA Encrypt/Decrypt: RSA-OAEP/SHA-384, nothing",
input: "",
expectedOutput: "",
recipeConfig: [
{
"op": "RSA Encrypt",
"args": [PEM_PUB_2048, "RSA-OAEP", "SHA-384"]
},
{
"op": "RSA Decrypt",
"args": [PEM_PRIV_2048, "", "RSA-OAEP", "SHA-384"]
}
]
},
{
name: "RSA Encrypt/Decrypt: RSA-OAEP/SHA-384, ASCII",
input: ASCII_TEXT,
expectedOutput: ASCII_TEXT,
recipeConfig: [
{
"op": "RSA Encrypt",
"args": [PEM_PUB_2048, "RSA-OAEP", "SHA-384"]
},
{
"op": "RSA Decrypt",
"args": [PEM_PRIV_2048, "", "RSA-OAEP", "SHA-384"]
}
]
},
{
name: "RSA Encrypt/Decrypt: RSA-OAEP/SHA-384, UTF-8",
input: UTF8_TEXT.substr(0, 80),
expectedOutput: UTF8_TEXT.substr(0, 80),
recipeConfig: [
{
"op": "RSA Encrypt",
"args": [PEM_PUB_2048, "RSA-OAEP", "SHA-384"]
},
{
"op": "RSA Decrypt",
"args": [PEM_PRIV_2048, "", "RSA-OAEP", "SHA-384"]
}
]
},
{
name: "RSA Encrypt/Decrypt: RSA-OAEP/SHA-384, All bytes",
input: ALL_BYTES.substr(0, 100),
expectedOutput: ALL_BYTES.substr(0, 100),
recipeConfig: [
{
"op": "RSA Encrypt",
"args": [PEM_PUB_2048, "RSA-OAEP", "SHA-384"]
},
{
"op": "RSA Decrypt",
"args": [PEM_PRIV_2048, "", "RSA-OAEP", "SHA-384"]
}
]
},
{
name: "RSA Encrypt/Decrypt: RSA-OAEP/SHA-512, nothing",
input: "",
expectedOutput: "",
recipeConfig: [
{
"op": "RSA Encrypt",
"args": [PEM_PUB_2048, "RSA-OAEP", "SHA-512"]
},
{
"op": "RSA Decrypt",
"args": [PEM_PRIV_2048, "", "RSA-OAEP", "SHA-512"]
}
]
},
{
name: "RSA Encrypt/Decrypt: RSA-OAEP/SHA-512, ASCII",
input: ASCII_TEXT.substr(0, 100),
expectedOutput: ASCII_TEXT.substr(0, 100),
recipeConfig: [
{
"op": "RSA Encrypt",
"args": [PEM_PUB_2048, "RSA-OAEP", "SHA-512"]
},
{
"op": "RSA Decrypt",
"args": [PEM_PRIV_2048, "", "RSA-OAEP", "SHA-512"]
}
]
},
{
name: "RSA Encrypt/Decrypt: RSA-OAEP/SHA-512, UTF-8",
input: UTF8_TEXT.substr(0, 60),
expectedOutput: UTF8_TEXT.substr(0, 60),
recipeConfig: [
{
"op": "RSA Encrypt",
"args": [PEM_PUB_2048, "RSA-OAEP", "SHA-512"]
},
{
"op": "RSA Decrypt",
"args": [PEM_PRIV_2048, "", "RSA-OAEP", "SHA-512"]
}
]
},
{
name: "RSA Encrypt/Decrypt: RSA-OAEP/SHA-512, All bytes",
input: ALL_BYTES.substr(0, 100),
expectedOutput: ALL_BYTES.substr(0, 100),
recipeConfig: [
{
"op": "RSA Encrypt",
"args": [PEM_PUB_2048, "RSA-OAEP", "SHA-512"]
},
{
"op": "RSA Decrypt",
"args": [PEM_PRIV_2048, "", "RSA-OAEP", "SHA-512"]
}
]
},
]);
+2 -1
View File
@@ -63,7 +63,8 @@ TestRegister.addTests([
{
"option": "Hex",
"string": ""
}
},
""
]
}
]
@@ -1,22 +0,0 @@
/**
* Remove Diacritics tests.
*
* @author Klaxon [klaxon@veyr.com]
* @copyright Crown Copyright 2017
* @license Apache-2.0
*/
import TestRegister from "../../lib/TestRegister.mjs";
TestRegister.addTests([
{
name: "Remove Diacritics",
input: "\xe0, \xe8, \xec, \xf2, \xf9 \xc0, \xc8, \xcc, \xd2, \xd9\n\xe1, \xe9, \xed, \xf3, \xfa, \xfd \xc1, \xc9, \xcd, \xd3, \xda, \xdd\n\xe2, \xea, \xee, \xf4, \xfb \xc2, \xca, \xce, \xd4, \xdb\n\xe3, \xf1, \xf5 \xc3, \xd1, \xd5\n\xe4, \xeb, \xef, \xf6, \xfc, \xff \xc4, \xcb, \xcf, \xd6, \xdc, \u0178\n\xe5, \xc5",
expectedOutput: "a, e, i, o, u A, E, I, O, U\na, e, i, o, u, y A, E, I, O, U, Y\na, e, i, o, u A, E, I, O, U\na, n, o A, N, O\na, e, i, o, u, y A, E, I, O, U, Y\na, A",
recipeConfig: [
{
"op": "Remove Diacritics",
"args": []
},
],
},
]);
+5 -5
View File
@@ -131,7 +131,7 @@ TestRegister.addTests([
recipeConfig: [
{
op: "ROT13",
args: [true, true, 13]
args: [true, true, true, 13]
},
],
},
@@ -142,7 +142,7 @@ TestRegister.addTests([
recipeConfig: [
{
op: "ROT13",
args: [true, true, 13]
args: [true, true, true, 13]
},
],
},
@@ -153,7 +153,7 @@ TestRegister.addTests([
recipeConfig: [
{
op: "ROT13",
args: [true, true, 26]
args: [true, true, true, 26]
},
],
},
@@ -164,7 +164,7 @@ TestRegister.addTests([
recipeConfig: [
{
op: "ROT13",
args: [true, false, 13]
args: [true, false, false, 13]
},
],
},
@@ -175,7 +175,7 @@ TestRegister.addTests([
recipeConfig: [
{
op: "ROT13",
args: [false, true, 13]
args: [false, true, false, 13]
},
],
},
+83
View File
@@ -0,0 +1,83 @@
/**
* Unicode operation tests.
*
* @author Matt C [me@mitt.dev]
* @author Klaxon [klaxon@veyr.com]
*
* @copyright Crown Copyright 2020
* @license Apache-2.0
*/
import TestRegister from "../../lib/TestRegister.mjs";
TestRegister.addTests([
{
name: "Unicode Text Format: underline",
input: "a",
expectedOutput: "a\u0332",
recipeConfig: [
{
"op": "Unicode Text Format",
"args": [true, false],
}
],
},
{
name: "Unicode Text Format: strikethrough",
input: "a",
expectedOutput: "a\u0336",
recipeConfig: [
{
"op": "Unicode Text Format",
"args": [false, true],
}
],
},
{
name: "Unicode Text Format: both",
input: "a",
expectedOutput: "a\u0336\u0332",
recipeConfig: [
{
"op": "Unicode Text Format",
"args": [true, true],
}
],
},
{
name: "Remove Diacritics: text formatting",
input: "a",
expectedOutput: "a",
recipeConfig: [
{
"op": "Unicode Text Format",
"args": [true, true],
},
{
"op": "Remove Diacritics",
"args": []
}
],
},
{
name: "Remove Diacritics: all diacritical marks one char",
input: "à̴̵̶̷̸̡̢̧̨̛̖̗̘̙̜̝̞̟̠̣̤̥̦̩̪̫̬̭̮̯̰̱̲̳̹̺̻̼́̂̃̄̅̆̇̈̉̊̋̌̍̎̏̐̑̒̓̔̽̾̿̀́͂̓̈́̕̚͠͡ͅ", // sorry about this line lol
expectedOutput: "a",
recipeConfig: [
{
"op": "Remove Diacritics",
"args": []
}
],
},
{
name: "Remove Diacritics: default",
input: "\xe0, \xe8, \xec, \xf2, \xf9 \xc0, \xc8, \xcc, \xd2, \xd9\n\xe1, \xe9, \xed, \xf3, \xfa, \xfd \xc1, \xc9, \xcd, \xd3, \xda, \xdd\n\xe2, \xea, \xee, \xf4, \xfb \xc2, \xca, \xce, \xd4, \xdb\n\xe3, \xf1, \xf5 \xc3, \xd1, \xd5\n\xe4, \xeb, \xef, \xf6, \xfc, \xff \xc4, \xcb, \xcf, \xd6, \xdc, \u0178\n\xe5, \xc5",
expectedOutput: "a, e, i, o, u A, E, I, O, U\na, e, i, o, u, y A, E, I, O, U, Y\na, e, i, o, u A, E, I, O, U\na, n, o A, N, O\na, e, i, o, u, y A, E, I, O, U, Y\na, A",
recipeConfig: [
{
"op": "Remove Diacritics",
"args": []
},
],
},
]);
+12
View File
@@ -34,6 +34,10 @@ const banner = `/**
module.exports = {
output: {
publicPath: "",
globalObject: "this"
},
plugins: [
new webpack.ProvidePlugin({
$: "jquery",
@@ -71,6 +75,10 @@ module.exports = {
context: "node_modules/tesseract.js-core/",
from: "tesseract-core.wasm.js",
to: "assets/tesseract"
}, {
context: "node_modules/node-forge/dist",
from: "prime.worker.min.js",
to: "assets/forge/"
}
]
})
@@ -112,6 +120,10 @@ module.exports = {
additionalCode: "var jQuery = false;"
}
},
{
test: /prime.worker.min.js$/,
use: "raw-loader"
},
{
test: /bootstrap-material-design/,
loader: "imports-loader",