mirror of
https://github.com/gchq/CyberChef
synced 2026-01-29 15:53:36 +00:00
Compare commits
113 Commits
a3957273-p
...
v10.20.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2092e5b20c | ||
|
|
621331b03e | ||
|
|
2a1294f1c0 | ||
|
|
fb968da64f | ||
|
|
314a14a45b | ||
|
|
dc8121e7fc | ||
|
|
554a3b071e | ||
|
|
9fc91b3fc6 | ||
|
|
6dd651a4df | ||
|
|
c57556f49f | ||
|
|
18e5b9f6ec | ||
|
|
411f78d27a | ||
|
|
7ed7fca3ad | ||
|
|
5d3353189b | ||
|
|
f92238bf04 | ||
|
|
2b1ceef6a3 | ||
|
|
f4e73eef54 | ||
|
|
d751117219 | ||
|
|
a55075fdb6 | ||
|
|
288cd8f063 | ||
|
|
a7443778b8 | ||
|
|
e9b182d33b | ||
|
|
0c01c6a7c3 | ||
|
|
06f1982acf | ||
|
|
761173bce7 | ||
|
|
bfec582aee | ||
|
|
3a55b34214 | ||
|
|
95d5fd1789 | ||
|
|
159b80e853 | ||
|
|
f24bd92e34 | ||
|
|
e4f4d9c1c5 | ||
|
|
7ecf8dfdaa | ||
|
|
1bc3105002 | ||
|
|
66d445c5ef | ||
|
|
b2045e5bd8 | ||
|
|
64a4bfeadf | ||
|
|
46762a2af7 | ||
|
|
bd9e0142bc | ||
|
|
da922a45cf | ||
|
|
9538320928 | ||
|
|
b156fc9929 | ||
|
|
dda5814c30 | ||
|
|
7ca472279c | ||
|
|
670721f1f6 | ||
|
|
3c5eea5dfb | ||
|
|
497e2a9d45 | ||
|
|
e4a59c6990 | ||
|
|
85a3a18570 | ||
|
|
a150137c4b | ||
|
|
c6ece4292b | ||
|
|
c475a24854 | ||
|
|
1089c6bfb8 | ||
|
|
4085a4c219 | ||
|
|
a2665ba213 | ||
|
|
0a94c4a7c9 | ||
|
|
64355c9dde | ||
|
|
bd8906f46b | ||
|
|
26d8fa51b0 | ||
|
|
ad91099d5e | ||
|
|
361a3b2929 | ||
|
|
b9ed1fde62 | ||
|
|
a0ade26505 | ||
|
|
575eade84d | ||
|
|
2cf3642493 | ||
|
|
7c8be12d52 | ||
|
|
e849569b10 | ||
|
|
fa559fdbed | ||
|
|
74d631c71e | ||
|
|
305a02c8a2 | ||
|
|
5a3b7bc4c0 | ||
|
|
c83e1ac4fb | ||
|
|
857576dbe4 | ||
|
|
e00a636fc0 | ||
|
|
6f4cbd8688 | ||
|
|
de5b03f854 | ||
|
|
457d28fc55 | ||
|
|
e0bdde89c4 | ||
|
|
68db8e93b7 | ||
|
|
9069d8e3ec | ||
|
|
e146636250 | ||
|
|
c0af2a9eb5 | ||
|
|
ae5648ede1 | ||
|
|
197d6735d2 | ||
|
|
75b52bef6d | ||
|
|
23de98f892 | ||
|
|
a42c7de112 | ||
|
|
b85036b78f | ||
|
|
3b75e13287 | ||
|
|
f4988328be | ||
|
|
7710c5ef49 | ||
|
|
3057a20791 | ||
|
|
b2981d3cc7 | ||
|
|
2c32a64bfe | ||
|
|
91125f00e7 | ||
|
|
4c6b4cd4e7 | ||
|
|
c4574ff042 | ||
|
|
2b2435210b | ||
|
|
4a428e802e | ||
|
|
5b15e75479 | ||
|
|
a40aed2b47 | ||
|
|
54a63b37bd | ||
|
|
324560aeae | ||
|
|
f8b613b4e7 | ||
|
|
3aed784ce2 | ||
|
|
77a43b4f78 | ||
|
|
95f6c4c5d5 | ||
|
|
d58e162bfa | ||
|
|
77c2b7923d | ||
|
|
c0e84dcd50 | ||
|
|
15b426ebb6 | ||
|
|
bf1e708a4c | ||
|
|
73a39fa3ce | ||
|
|
3e8c5d945c |
21
.github/workflows/releases.yml
vendored
21
.github/workflows/releases.yml
vendored
@@ -25,6 +25,7 @@ jobs:
|
||||
|
||||
- name: Install
|
||||
run: |
|
||||
export DETECT_CHROMEDRIVER_VERSION=true
|
||||
npm ci
|
||||
npm run setheapsize
|
||||
|
||||
@@ -61,12 +62,22 @@ jobs:
|
||||
tags: ${{ steps.image-metadata.outputs.tags }}
|
||||
labels: ${{ steps.image-metadata.outputs.labels }}
|
||||
containerfiles: ./Dockerfile
|
||||
platforms: linux/amd64
|
||||
platforms: linux/amd64,linux/arm64
|
||||
oci: true
|
||||
# enable build layer caching between platforms
|
||||
layers: true
|
||||
# Webpack seems to use a lot of open files, increase the max open file limit to accomodate.
|
||||
extra-args: |
|
||||
--ulimit nofile=10000
|
||||
|
||||
- name: Publish to GHCR
|
||||
uses: redhat-actions/push-to-registry@v2
|
||||
with:
|
||||
image: ${{ steps.build-image.outputs.image }}
|
||||
tags: ${{ steps.build-image.outputs.tags }}
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ env.REGISTRY_USER }}
|
||||
password: ${{ env.REGISTRY_PASSWORD }}
|
||||
|
||||
- name: Upload Release Assets
|
||||
id: upload-release-assets
|
||||
@@ -83,11 +94,3 @@ jobs:
|
||||
uses: JS-DevTools/npm-publish@v1
|
||||
with:
|
||||
token: ${{ secrets.NPM_TOKEN }}
|
||||
|
||||
- name: Publish to GHCR
|
||||
uses: redhat-actions/push-to-registry@v2
|
||||
with:
|
||||
tags: ${{ steps.build-image.outputs.tags }}
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ env.REGISTRY_USER }}
|
||||
password: ${{ env.REGISTRY_PASSWORD }}
|
||||
|
||||
165
CHANGELOG.md
165
CHANGELOG.md
@@ -13,6 +13,75 @@ All major and minor version changes will be documented in this file. Details of
|
||||
|
||||
## Details
|
||||
|
||||
### [10.20.0] - 2026-01-28
|
||||
- Fixed Optical Character Recognition and added tests [@n1474335] | [ab37c1e]
|
||||
- Fixed JA4 version fallback value [@n1474335] | [7a5225c]
|
||||
- Updated chromedriver [@n1474335] | [0e82e4b]
|
||||
- Fixed RSA Sign and Verify character encodings [@n1474335] | [895a929]
|
||||
- Updated chromedriver [@n1474335] | [d3adfc7]
|
||||
- Added message format arg to RSA Verify operation [@n1474335] | [47c85a1]
|
||||
- Add operation for parsing X.509 CRLs [@robinsandhu] | [#1887]
|
||||
- Fix typo in description of JWT Sign recipe [@GuilhermoReadonly] | [#1961]
|
||||
- Corrected path to generateNodeIndex.mjs [@simonarnell] | [#1959]
|
||||
- Add 'header' ingredient to JWT Sign operation [@RandomByte] | [#1957]
|
||||
- Add Parse TLS record operation [@c65722] | [#1936]
|
||||
- Automatically detect chrome driver version [@gchq] | [#1972]
|
||||
- Add Strip UDP header operation [@c65722] | [#1900]
|
||||
- Add Strip TCP header operation [@c65722] | [#1898]
|
||||
- Webpack compress with gzip and brotli [@max0x53] | [#1955]
|
||||
- add offset field to 'Add Line Numbers' operation [@Adamkadaban] | [#1866]
|
||||
- Disable flakey URL test [@a3957273] | [#1973]
|
||||
- Add Strip IPv4 header operation [@c65722] | [#1899]
|
||||
- IPv6 Transition Operation [@jb30795] | [#1780]
|
||||
- fix: Blowfish - ignore IV length in ECB mode [@FranciscoPombal] | [#1902]
|
||||
- Add 'Drop nth bytes' operation [@Oshawk] | [#1914]
|
||||
- Add 'Take nth bytes' operation [@Oshawk] | [#1915]
|
||||
- Add Leet Speak [@bartblaze] | [#1971]
|
||||
- Fix Generate TOTP & HOPT [@exactlyaron] | [#1966]
|
||||
- Updated luhn checksum operation to work with different bases [@k3ach] | [#1933]
|
||||
- automatically theme mode based on user preference [@vs4vijay] | [#1921]
|
||||
- fix: DES/Triple DES - misleading error messages [@FranciscoPombal] | [#1904]
|
||||
- fix: ROT13 - shifting numbers by negative amounts [@FranciscoPombal] | [#1903]
|
||||
- Introduce Yubico's Modhex for Conversion [@linuxgemini] | [#1105]
|
||||
- Feature: MIME RFC2047 Decoding [@MShwed] | [#630]
|
||||
- CC-1889 add _ option [@depperm] | [#1977]
|
||||
- chore(root): add cspell [@evenstensberg] | [#1976]
|
||||
- Preserve uppercase for Leet Speak [@bartblaze] | [#1981]
|
||||
- Load the user's preferred color scheme if the URL contains an invalid theme [@0xh3xa] | [#2007]
|
||||
- Add SM2 Encrypt and Decrypt Operations [@flakjacket95] | [#1909]
|
||||
- Support jq as an operation. [@zhzy0077] | [#1604]
|
||||
- Add fingerprints to the 'Parse X.509 certificate' operation [@JSCU-CNI] | [#1863]
|
||||
- Added a JSON to YAML and a YAML to JSON operation [@ccarpo] | [#1286]
|
||||
- Add CRC Operation [@r4mos] | [#1993]
|
||||
- Bug Fix: selected theme not loading when refreshing [@0xh3xa] | [#2006]
|
||||
- Fix(RecipeWaiter): sanitize user input in addOperation to prevent XSS [@0xh3xa] | [#2014]
|
||||
- Docker multiplatform build support [@PathToLife] | [#1974]
|
||||
- Add Base32 Hex Extended Alphabet and Base32 Tests. [@peterc-s] | [#1991]
|
||||
- Add ECB/NoPadding and CBC/NoPadding support to AES encryption [@plvie] | [#2013]
|
||||
- Add new operation: PHP Serialize [@brun0ne] | [#1548]
|
||||
- Push input through postmessage [@kenduguay1] | [#1992]
|
||||
- Add jsonata query operation [@jonking-ajar] | [#1587]
|
||||
- Re-enable Npm Release in github workflows [@PathToLife] | [#2031]
|
||||
- Add to ECDSA Verify the message format [@r4mos] | [#2027]
|
||||
- Added alternating caps functionality [@sw5678] | [#1897]
|
||||
- XOR Checksum operation added [@jg42526] | [#2035]
|
||||
- Add GenerateAllChecksums operation * Remove checksums from GenerateAllHashes operation [@es45411] | [66d445c]
|
||||
- Update GenerateAllChecksums infoURL [@es45411] | [#2037]
|
||||
- Add toggle "+" character to URLDecode operation [@es45411] | [#2040]
|
||||
- Workaround for Safari load bug [@GCHQDeveloper94872] | [#2038]
|
||||
- Updated Dockerfile to correctly build on ARM64 platforms [@Sma-Das] | [#2042]
|
||||
- Addresses bug report #2008 Added explicit support for octal IP addresses. Changed approach to IPv4 regex to be string manipulation generated. Added some unit tests for IP address parsing - probably not full coverage. Added lookahead and lookbehind tricks to resolve warned issue that 1.2.3.256 would still be extracted as 1.2.3.25. Now only accepts valid IP addresses. Warning replaced with clause about infinite length dotted decimal forms. [@gchqdev364] | [#2041]
|
||||
- Remove trim from rail fence [@Odyhibit] | [#1986]
|
||||
- Fix email regex [@ericli-splunk] | [#2025]
|
||||
- Add Blake3 hashing [@xumptex] | [#2023]
|
||||
- Use defaultIndex instead of 0 in transformArgs [@bartvanandel] | [#2015]
|
||||
- Add "Generate UUID" and "Analyse UUID" operations [@bartvanandel] | [#2011]
|
||||
- Add new operation: Template [@kendallgoto] | [#2021]
|
||||
- Add more clear build instructions [@remingtr] | [#1873]
|
||||
- Show On Map updated to use leaflet over WikiMedia [@0xff1ce] | [#1884]
|
||||
- Fixed ToDecimal signed logic [@starplanet] | [#1545]
|
||||
- Use BigInt for encoding/decoding VarInt [@mikecat] | [#1978]
|
||||
|
||||
### [10.19.0] - 2024-06-21
|
||||
- Add support for ECDSA and DSA in 'Parse CSR' [@robinsandhu] | [#1828]
|
||||
- Fix typos in SIGABA.mjs [@eltociear] | [#1834]
|
||||
@@ -440,6 +509,7 @@ All major and minor version changes will be documented in this file. Details of
|
||||
## [4.0.0] - 2016-11-28
|
||||
- Initial open source commit [@n1474335] | [b1d73a72](https://github.com/gchq/CyberChef/commit/b1d73a725dc7ab9fb7eb789296efd2b7e4b08306)
|
||||
|
||||
[10.20.0]: https://github.com/gchq/CyberChef/releases/tag/v10.20.0
|
||||
[10.19.0]: https://github.com/gchq/CyberChef/releases/tag/v10.19.0
|
||||
[10.18.0]: https://github.com/gchq/CyberChef/releases/tag/v10.18.0
|
||||
[10.17.0]: https://github.com/gchq/CyberChef/releases/tag/v10.17.0
|
||||
@@ -630,6 +700,60 @@ All major and minor version changes will be documented in this file. Details of
|
||||
[@cplussharp]: https://github.com/cplussharp
|
||||
[@robinsandhu]: https://github.com/robinsandhu
|
||||
[@eltociear]: https://github.com/eltociear
|
||||
[@GuilhermoReadonly]: https://github.com/GuilhermoReadonly
|
||||
[@simonarnell]: https://github.com/simonarnell
|
||||
[@RandomByte]: https://github.com/RandomByte
|
||||
[@c65722]: https://github.com/c65722
|
||||
[@c65722]: https://github.com/c65722
|
||||
[@c65722]: https://github.com/c65722
|
||||
[@max0x53]: https://github.com/max0x53
|
||||
[@Adamkadaban]: https://github.com/Adamkadaban
|
||||
[@c65722]: https://github.com/c65722
|
||||
[@jb30795]: https://github.com/jb30795
|
||||
[@FranciscoPombal]: https://github.com/FranciscoPombal
|
||||
[@Oshawk]: https://github.com/Oshawk
|
||||
[@Oshawk]: https://github.com/Oshawk
|
||||
[@bartblaze]: https://github.com/bartblaze
|
||||
[@exactlyaron]: https://github.com/exactlyaron
|
||||
[@k3ach]: https://github.com/k3ach
|
||||
[@vs4vijay]: https://github.com/vs4vijay
|
||||
[@FranciscoPombal]: https://github.com/FranciscoPombal
|
||||
[@FranciscoPombal]: https://github.com/FranciscoPombal
|
||||
[@linuxgemini]: https://github.com/linuxgemini
|
||||
[@depperm]: https://github.com/depperm
|
||||
[@evenstensberg]: https://github.com/evenstensberg
|
||||
[@bartblaze]: https://github.com/bartblaze
|
||||
[@0xh3xa]: https://github.com/0xh3xa
|
||||
[@flakjacket95]: https://github.com/flakjacket95
|
||||
[@zhzy0077]: https://github.com/zhzy0077
|
||||
[@JSCU-CNI]: https://github.com/JSCU-CNI
|
||||
[@ccarpo]: https://github.com/ccarpo
|
||||
[@r4mos]: https://github.com/r4mos
|
||||
[@0xh3xa]: https://github.com/0xh3xa
|
||||
[@0xh3xa]: https://github.com/0xh3xa
|
||||
[@PathToLife]: https://github.com/PathToLife
|
||||
[@peterc-s]: https://github.com/peterc-s
|
||||
[@plvie]: https://github.com/plvie
|
||||
[@kenduguay1]: https://github.com/kenduguay1
|
||||
[@jonking-ajar]: https://github.com/jonking-ajar
|
||||
[@PathToLife]: https://github.com/PathToLife
|
||||
[@r4mos]: https://github.com/r4mos
|
||||
[@jg42526]: https://github.com/jg42526
|
||||
[@es45411]: https://github.com/es45411
|
||||
[@gchq]: https://github.com/gchq
|
||||
[@gchqdev364]: https://github.com/gchqdev364
|
||||
[@GCHQDeveloper94872]: https://github.com/GCHQDeveloper94872
|
||||
[@Sma-Das]: https://github.com/Sma-Das
|
||||
[@gchq]: https://github.com/gchq
|
||||
[@Odyhibit]: https://github.com/Odyhibit
|
||||
[@ericli-splunk]: https://github.com/ericli-splunk
|
||||
[@xumptex]: https://github.com/xumptex
|
||||
[@bartvanandel]: https://github.com/bartvanandel
|
||||
[@bartvanandel]: https://github.com/bartvanandel
|
||||
[@kendallgoto]: https://github.com/kendallgoto
|
||||
[@remingtr]: https://github.com/remingtr
|
||||
[@0xff1ce]: https://github.com/0xff1ce
|
||||
[@starplanet]: https://github.com/starplanet
|
||||
|
||||
|
||||
[8ad18b]: https://github.com/gchq/CyberChef/commit/8ad18bc7db6d9ff184ba3518686293a7685bf7b7
|
||||
@@ -642,6 +766,46 @@ All major and minor version changes will be documented in this file. Details of
|
||||
[760eff4]: https://github.com/gchq/CyberChef/commit/760eff49b5307aaa3104c5e5b437ffe62299acd1
|
||||
[65ffd8d]: https://github.com/gchq/CyberChef/commit/65ffd8d65d88eb369f6f61a5d1d0f807179bffb7
|
||||
[0a353ee]: https://github.com/gchq/CyberChef/commit/0a353eeb378b9ca5d49e23c7dfc175ae07107b08
|
||||
[66d445c]: https://github.com/gchq/CyberChef/commit/66d445c5ef4e8bd896fd15396e3ce2d660d8ace1
|
||||
[ab37c1e]: https://github.com/gchq/CyberChef/commit/ab37c1e562dbee0495ed32876ecbb8225282af25
|
||||
[965570d]: https://github.com/gchq/CyberChef/commit/965570d2504c17ee1f96211a1dc10ed40cd2b332
|
||||
[a477f47]: https://github.com/gchq/CyberChef/commit/a477f47aecd01d78b11fe186ed4b20d9c487cfac
|
||||
[7a5225c]: https://github.com/gchq/CyberChef/commit/7a5225c961a5e0d192b03152117cd10a761f73d6
|
||||
[5f88ae4]: https://github.com/gchq/CyberChef/commit/5f88ae44ec77228d9bed8f11e8cc8e7dcfb36914
|
||||
[0e82e4b]: https://github.com/gchq/CyberChef/commit/0e82e4b7c6c77cadb8be61cb145e081d6ecfdc88
|
||||
[d635cca]: https://github.com/gchq/CyberChef/commit/d635cca2106aae2a59caf0e5d7e3633ee1ea3155
|
||||
[895a929]: https://github.com/gchq/CyberChef/commit/895a9299255525cb57886deb9d9fd4ba17ae9548
|
||||
[270a333]: https://github.com/gchq/CyberChef/commit/270a33317944612d27ea1cc15275ad6b0ed097e5
|
||||
[d3adfc7]: https://github.com/gchq/CyberChef/commit/d3adfc7c3e5719279524356bce5261bd8350c0f8
|
||||
[47c85a1]: https://github.com/gchq/CyberChef/commit/47c85a105ddbdd4cabfa44ddddbc56e3907a8c33
|
||||
[3822c6c]: https://github.com/gchq/CyberChef/commit/3822c6c520a0b4200abc675c33f46082f5b9efc6
|
||||
[66d445c]: https://github.com/gchq/CyberChef/commit/66d445c5ef4e8bd896fd15396e3ce2d660d8ace1
|
||||
[ab37c1e]: https://github.com/gchq/CyberChef/commit/ab37c1e562dbee0495ed32876ecbb8225282af25
|
||||
[965570d]: https://github.com/gchq/CyberChef/commit/965570d2504c17ee1f96211a1dc10ed40cd2b332
|
||||
[a477f47]: https://github.com/gchq/CyberChef/commit/a477f47aecd01d78b11fe186ed4b20d9c487cfac
|
||||
[7a5225c]: https://github.com/gchq/CyberChef/commit/7a5225c961a5e0d192b03152117cd10a761f73d6
|
||||
[5f88ae4]: https://github.com/gchq/CyberChef/commit/5f88ae44ec77228d9bed8f11e8cc8e7dcfb36914
|
||||
[0e82e4b]: https://github.com/gchq/CyberChef/commit/0e82e4b7c6c77cadb8be61cb145e081d6ecfdc88
|
||||
[d635cca]: https://github.com/gchq/CyberChef/commit/d635cca2106aae2a59caf0e5d7e3633ee1ea3155
|
||||
[895a929]: https://github.com/gchq/CyberChef/commit/895a9299255525cb57886deb9d9fd4ba17ae9548
|
||||
[270a333]: https://github.com/gchq/CyberChef/commit/270a33317944612d27ea1cc15275ad6b0ed097e5
|
||||
[d3adfc7]: https://github.com/gchq/CyberChef/commit/d3adfc7c3e5719279524356bce5261bd8350c0f8
|
||||
[47c85a1]: https://github.com/gchq/CyberChef/commit/47c85a105ddbdd4cabfa44ddddbc56e3907a8c33
|
||||
[3822c6c]: https://github.com/gchq/CyberChef/commit/3822c6c520a0b4200abc675c33f46082f5b9efc6
|
||||
[66d445c]: https://github.com/gchq/CyberChef/commit/66d445c5ef4e8bd896fd15396e3ce2d660d8ace1
|
||||
[ab37c1e]: https://github.com/gchq/CyberChef/commit/ab37c1e562dbee0495ed32876ecbb8225282af25
|
||||
[965570d]: https://github.com/gchq/CyberChef/commit/965570d2504c17ee1f96211a1dc10ed40cd2b332
|
||||
[a477f47]: https://github.com/gchq/CyberChef/commit/a477f47aecd01d78b11fe186ed4b20d9c487cfac
|
||||
[7a5225c]: https://github.com/gchq/CyberChef/commit/7a5225c961a5e0d192b03152117cd10a761f73d6
|
||||
[5f88ae4]: https://github.com/gchq/CyberChef/commit/5f88ae44ec77228d9bed8f11e8cc8e7dcfb36914
|
||||
[0e82e4b]: https://github.com/gchq/CyberChef/commit/0e82e4b7c6c77cadb8be61cb145e081d6ecfdc88
|
||||
[d635cca]: https://github.com/gchq/CyberChef/commit/d635cca2106aae2a59caf0e5d7e3633ee1ea3155
|
||||
[895a929]: https://github.com/gchq/CyberChef/commit/895a9299255525cb57886deb9d9fd4ba17ae9548
|
||||
[270a333]: https://github.com/gchq/CyberChef/commit/270a33317944612d27ea1cc15275ad6b0ed097e5
|
||||
[d3adfc7]: https://github.com/gchq/CyberChef/commit/d3adfc7c3e5719279524356bce5261bd8350c0f8
|
||||
[47c85a1]: https://github.com/gchq/CyberChef/commit/47c85a105ddbdd4cabfa44ddddbc56e3907a8c33
|
||||
[3822c6c]: https://github.com/gchq/CyberChef/commit/3822c6c520a0b4200abc675c33f46082f5b9efc6
|
||||
[66d445c]: https://github.com/gchq/CyberChef/commit/66d445c5ef4e8bd896fd15396e3ce2d660d8ace1
|
||||
|
||||
[#95]: https://github.com/gchq/CyberChef/pull/299
|
||||
[#173]: https://github.com/gchq/CyberChef/pull/173
|
||||
@@ -778,4 +942,3 @@ All major and minor version changes will be documented in this file. Details of
|
||||
[#512]: https://github.com/gchq/CyberChef/issues/512
|
||||
[#1732]: https://github.com/gchq/CyberChef/issues/1732
|
||||
[#1789]: https://github.com/gchq/CyberChef/issues/1789
|
||||
|
||||
|
||||
34
Dockerfile
34
Dockerfile
@@ -1,9 +1,35 @@
|
||||
FROM node:18-alpine AS build
|
||||
#####################################
|
||||
# Build the app to a static website #
|
||||
#####################################
|
||||
# Modifier --platform=$BUILDPLATFORM limits the platform to "BUILDPLATFORM" during buildx multi-platform builds
|
||||
# This is because npm "chromedriver" package is not compatiable with all platforms
|
||||
# For more info see: https://docs.docker.com/build/building/multi-platform/#cross-compilation
|
||||
FROM --platform=$BUILDPLATFORM node:18-alpine AS builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY package.json .
|
||||
COPY package-lock.json .
|
||||
|
||||
# Install dependencies
|
||||
# --ignore-scripts prevents postinstall script (which runs grunt) as it depends on files other than package.json
|
||||
RUN npm ci --ignore-scripts
|
||||
|
||||
# Copy files needed for postinstall and build
|
||||
COPY . .
|
||||
RUN npm ci
|
||||
|
||||
# npm postinstall runs grunt, which depends on files other than package.json
|
||||
RUN npm run postinstall
|
||||
|
||||
# Build the app
|
||||
RUN npm run build
|
||||
|
||||
FROM nginx:1.25-alpine3.18 AS cyberchef
|
||||
#########################################
|
||||
# Package static build files into nginx #
|
||||
#########################################
|
||||
# We are using Github Actions: redhat-actions/buildah-build@v2 which needs manual selection of arch in base image
|
||||
# Remove TARGETARCH if docker buildx is supported in the CI release as --platform=$TARGETPLATFORM will be automatically set
|
||||
ARG TARGETPLATFORM
|
||||
FROM --platform=${TARGETPLATFORM} nginx:stable-alpine AS cyberchef
|
||||
|
||||
COPY --from=build ./build/prod /usr/share/nginx/html/
|
||||
COPY --from=builder /app/build/prod /usr/share/nginx/html/
|
||||
|
||||
21
README.md
21
README.md
@@ -20,21 +20,36 @@ Cryptographic operations in CyberChef should not be relied upon to provide secur
|
||||
|
||||
[A live demo can be found here][1] - have fun!
|
||||
|
||||
## Containers
|
||||
## Running Locally with Docker
|
||||
|
||||
If you would like to try out CyberChef locally you can either build it yourself:
|
||||
**Prerequisites**
|
||||
|
||||
- [Docker](hhttps://www.docker.com/products/docker-desktop/)
|
||||
- Docker Desktop must be open and running on your machine
|
||||
|
||||
|
||||
#### Option 1: Build the Docker Image Yourself
|
||||
|
||||
1. Build the docker image
|
||||
```bash
|
||||
docker build --tag cyberchef --ulimit nofile=10000 .
|
||||
```
|
||||
2. Run the docker container
|
||||
```bash
|
||||
docker run -it -p 8080:80 cyberchef
|
||||
```
|
||||
3. Navigate to `http://localhost:8080` in your browser
|
||||
|
||||
Or you can use our image directly:
|
||||
#### Option 2: Use the pre-built Docker Image
|
||||
|
||||
If you prefer to skip the build process, you can use the pre-built image
|
||||
|
||||
```bash
|
||||
docker run -it -p 8080:80 ghcr.io/gchq/cyberchef:latest
|
||||
```
|
||||
|
||||
Just like before, navigate to `http://localhost:8080` in your browser.
|
||||
|
||||
This image is built and published through our [GitHub Workflows](.github/workflows/releases.yml)
|
||||
|
||||
## How it works
|
||||
|
||||
106
package-lock.json
generated
106
package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "cyberchef",
|
||||
"version": "10.19.4",
|
||||
"version": "10.20.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "cyberchef",
|
||||
"version": "10.19.4",
|
||||
"version": "10.20.0",
|
||||
"hasInstallScript": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
@@ -37,6 +37,7 @@
|
||||
"d3": "7.9.0",
|
||||
"d3-hexbin": "^0.2.2",
|
||||
"diff": "^5.2.0",
|
||||
"dompurify": "^3.2.5",
|
||||
"es6-promisify": "^7.0.0",
|
||||
"escodegen": "^2.1.0",
|
||||
"esprima": "^4.0.1",
|
||||
@@ -45,15 +46,17 @@
|
||||
"file-saver": "^2.0.5",
|
||||
"flat": "^6.0.1",
|
||||
"geodesy": "1.1.3",
|
||||
"handlebars": "^4.7.8",
|
||||
"hash-wasm": "^4.12.0",
|
||||
"highlight.js": "^11.9.0",
|
||||
"ieee754": "^1.2.1",
|
||||
"jimp": "^0.22.12",
|
||||
"jq-web": "^0.5.1",
|
||||
"jquery": "3.7.1",
|
||||
"js-crc": "^0.2.0",
|
||||
"js-sha3": "^0.9.3",
|
||||
"jsesc": "^3.0.2",
|
||||
"json5": "^2.2.3",
|
||||
"jsonata": "^2.0.3",
|
||||
"jsonpath-plus": "^9.0.0",
|
||||
"jsonwebtoken": "8.5.1",
|
||||
"jsqr": "^1.4.0",
|
||||
@@ -94,6 +97,7 @@
|
||||
"ua-parser-js": "^1.0.38",
|
||||
"unorm": "^1.6.0",
|
||||
"utf8": "^3.0.0",
|
||||
"uuid": "^11.1.0",
|
||||
"vkbeautify": "^0.99.3",
|
||||
"xpath": "0.0.34",
|
||||
"xregexp": "^5.1.1",
|
||||
@@ -4365,6 +4369,13 @@
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/trusted-types": {
|
||||
"version": "2.0.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz",
|
||||
"integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==",
|
||||
"license": "MIT",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/@types/ws": {
|
||||
"version": "8.5.13",
|
||||
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.13.tgz",
|
||||
@@ -8411,6 +8422,15 @@
|
||||
"url": "https://github.com/fb55/domhandler?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/dompurify": {
|
||||
"version": "3.2.5",
|
||||
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.5.tgz",
|
||||
"integrity": "sha512-mLPd29uoRe9HpvwP2TxClGQBzGXeEC/we/q+bFlmPPmj2p2Ugl3r6ATu/UU1v77DXNcehiBg9zsr1dREyA/dJQ==",
|
||||
"license": "(MPL-2.0 OR Apache-2.0)",
|
||||
"optionalDependencies": {
|
||||
"@types/trusted-types": "^2.0.7"
|
||||
}
|
||||
},
|
||||
"node_modules/domutils": {
|
||||
"version": "2.8.0",
|
||||
"resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz",
|
||||
@@ -10826,6 +10846,27 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/handlebars": {
|
||||
"version": "4.7.8",
|
||||
"resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz",
|
||||
"integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"minimist": "^1.2.5",
|
||||
"neo-async": "^2.6.2",
|
||||
"source-map": "^0.6.1",
|
||||
"wordwrap": "^1.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"handlebars": "bin/handlebars"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.4.7"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"uglify-js": "^3.1.4"
|
||||
}
|
||||
},
|
||||
"node_modules/has-ansi": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
|
||||
@@ -10924,6 +10965,11 @@
|
||||
"node": ">= 0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/hash-wasm": {
|
||||
"version": "4.12.0",
|
||||
"resolved": "https://registry.npmjs.org/hash-wasm/-/hash-wasm-4.12.0.tgz",
|
||||
"integrity": "sha512-+/2B2rYLb48I/evdOIhP+K/DD2ca2fgBjp6O+GBEnCDk2e4rpeXIK8GvIyRPjTezgmWn9gmKwkQjjx6BtqDHVQ=="
|
||||
},
|
||||
"node_modules/hash.js": {
|
||||
"version": "1.1.7",
|
||||
"resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz",
|
||||
@@ -12303,12 +12349,6 @@
|
||||
"integrity": "sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/js-crc": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/js-crc/-/js-crc-0.2.0.tgz",
|
||||
"integrity": "sha512-8DdCSAOACpF8WDAjyDFBC2rj8OS4HUP9mNZBDfl8jCiPCnJG+2bkuycalxwZh6heFy6PrMvoWTp47lp6gzT65A==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/js-sha3": {
|
||||
"version": "0.9.3",
|
||||
"resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.9.3.tgz",
|
||||
@@ -12454,6 +12494,14 @@
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/jsonata": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/jsonata/-/jsonata-2.0.6.tgz",
|
||||
"integrity": "sha512-WhQB5tXQ32qjkx2GYHFw2XbL90u+LLzjofAYwi+86g6SyZeXHz9F1Q0amy3dWRYczshOC3Haok9J4pOCgHtwyQ==",
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/jsonpath-plus": {
|
||||
"version": "9.0.0",
|
||||
"resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-9.0.0.tgz",
|
||||
@@ -13644,7 +13692,6 @@
|
||||
"version": "2.6.2",
|
||||
"resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
|
||||
"integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/netmask": {
|
||||
@@ -13866,6 +13913,15 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/nightwatch/node_modules/uuid": {
|
||||
"version": "8.3.2",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
|
||||
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"uuid": "dist/bin/uuid"
|
||||
}
|
||||
},
|
||||
"node_modules/nightwatch/node_modules/yallist": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||
@@ -16809,6 +16865,15 @@
|
||||
"node": ">=0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/sockjs/node_modules/uuid": {
|
||||
"version": "8.3.2",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
|
||||
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"uuid": "dist/bin/uuid"
|
||||
}
|
||||
},
|
||||
"node_modules/socks": {
|
||||
"version": "2.8.3",
|
||||
"resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz",
|
||||
@@ -16849,7 +16914,6 @@
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
|
||||
"devOptional": true,
|
||||
"license": "BSD-3-Clause",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
@@ -18096,13 +18160,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/uuid": {
|
||||
"version": "8.3.2",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
|
||||
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"version": "11.1.0",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz",
|
||||
"integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==",
|
||||
"funding": [
|
||||
"https://github.com/sponsors/broofa",
|
||||
"https://github.com/sponsors/ctavan"
|
||||
],
|
||||
"bin": {
|
||||
"uuid": "dist/bin/uuid"
|
||||
"uuid": "dist/esm/bin/uuid"
|
||||
}
|
||||
},
|
||||
"node_modules/v8flags": {
|
||||
@@ -18867,6 +18933,12 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/wordwrap": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
|
||||
"integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/worker-loader": {
|
||||
"version": "3.0.8",
|
||||
"resolved": "https://registry.npmjs.org/worker-loader/-/worker-loader-3.0.8.tgz",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "cyberchef",
|
||||
"version": "10.19.4",
|
||||
"version": "10.20.0",
|
||||
"description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.",
|
||||
"author": "n1474335 <n1474335@gmail.com>",
|
||||
"homepage": "https://gchq.github.io/CyberChef",
|
||||
@@ -123,6 +123,7 @@
|
||||
"d3": "7.9.0",
|
||||
"d3-hexbin": "^0.2.2",
|
||||
"diff": "^5.2.0",
|
||||
"dompurify": "^3.2.5",
|
||||
"es6-promisify": "^7.0.0",
|
||||
"escodegen": "^2.1.0",
|
||||
"esprima": "^4.0.1",
|
||||
@@ -131,6 +132,8 @@
|
||||
"file-saver": "^2.0.5",
|
||||
"flat": "^6.0.1",
|
||||
"geodesy": "1.1.3",
|
||||
"handlebars": "^4.7.8",
|
||||
"hash-wasm": "^4.12.0",
|
||||
"highlight.js": "^11.9.0",
|
||||
"ieee754": "^1.2.1",
|
||||
"jimp": "^0.22.12",
|
||||
@@ -139,6 +142,7 @@
|
||||
"js-sha3": "^0.9.3",
|
||||
"jsesc": "^3.0.2",
|
||||
"json5": "^2.2.3",
|
||||
"jsonata": "^2.0.3",
|
||||
"jsonpath-plus": "^9.0.0",
|
||||
"jsonwebtoken": "8.5.1",
|
||||
"jsqr": "^1.4.0",
|
||||
@@ -179,6 +183,7 @@
|
||||
"ua-parser-js": "^1.0.38",
|
||||
"unorm": "^1.6.0",
|
||||
"utf8": "^3.0.0",
|
||||
"uuid": "^11.1.0",
|
||||
"vkbeautify": "^0.99.3",
|
||||
"xpath": "0.0.34",
|
||||
"xregexp": "^5.1.1",
|
||||
|
||||
@@ -294,6 +294,7 @@
|
||||
"To Upper case",
|
||||
"To Lower case",
|
||||
"Swap case",
|
||||
"Alternating Caps",
|
||||
"To Case Insensitive Regex",
|
||||
"From Case Insensitive Regex",
|
||||
"Add line numbers",
|
||||
@@ -369,11 +370,13 @@
|
||||
"Regular expression",
|
||||
"XPath expression",
|
||||
"JPath expression",
|
||||
"Jsonata Query",
|
||||
"CSS selector",
|
||||
"Extract EXIF",
|
||||
"Extract ID3",
|
||||
"Extract Files",
|
||||
"RAKE"
|
||||
"RAKE",
|
||||
"Template"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -404,6 +407,7 @@
|
||||
"name": "Hashing",
|
||||
"ops": [
|
||||
"Analyse hash",
|
||||
"Generate all checksums",
|
||||
"Generate all hashes",
|
||||
"MD2",
|
||||
"MD4",
|
||||
@@ -422,6 +426,7 @@
|
||||
"Snefru",
|
||||
"BLAKE2b",
|
||||
"BLAKE2s",
|
||||
"BLAKE3",
|
||||
"GOST Hash",
|
||||
"Streebog",
|
||||
"SSDEEP",
|
||||
@@ -446,7 +451,8 @@
|
||||
"Adler-32 Checksum",
|
||||
"Luhn Checksum",
|
||||
"CRC Checksum",
|
||||
"TCP/IP Checksum"
|
||||
"TCP/IP Checksum",
|
||||
"XOR Checksum"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -470,6 +476,7 @@
|
||||
"Jq",
|
||||
"CSS selector",
|
||||
"PHP Deserialize",
|
||||
"PHP Serialize",
|
||||
"Microsoft Script Decoder",
|
||||
"Strip HTML tags",
|
||||
"Diff",
|
||||
@@ -544,6 +551,7 @@
|
||||
"Pseudo-Random Number Generator",
|
||||
"Generate De Bruijn Sequence",
|
||||
"Generate UUID",
|
||||
"Analyse UUID",
|
||||
"Generate TOTP",
|
||||
"Generate HOTP",
|
||||
"Generate QR Code",
|
||||
|
||||
23
src/core/lib/Base32.mjs
Normal file
23
src/core/lib/Base32.mjs
Normal file
@@ -0,0 +1,23 @@
|
||||
// import Utils from "../Utils.mjs";
|
||||
|
||||
/**
|
||||
* Base32 resources.
|
||||
*
|
||||
* @author Peter C-S [petercs@purelymail.com]
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Base32 alphabets.
|
||||
*/
|
||||
export const ALPHABET_OPTIONS = [
|
||||
{
|
||||
name: "Standard", // https://www.rfc-editor.org/rfc/rfc4648#section-6
|
||||
value: "A-Z2-7=",
|
||||
},
|
||||
{
|
||||
name: "Hex Extended", // https://www.rfc-editor.org/rfc/rfc4648#section-7
|
||||
value: "0-9A-V=",
|
||||
},
|
||||
];
|
||||
|
||||
@@ -112,7 +112,7 @@ class AESDecrypt extends Operation {
|
||||
run(input, args) {
|
||||
const key = Utils.convertToByteString(args[0].string, args[0].option),
|
||||
iv = Utils.convertToByteString(args[1].string, args[1].option),
|
||||
mode = args[2].substring(0, 3),
|
||||
mode = args[2].split("/")[0],
|
||||
noPadding = args[2].endsWith("NoPadding"),
|
||||
inputType = args[3],
|
||||
outputType = args[4],
|
||||
|
||||
@@ -66,6 +66,14 @@ class AESEncrypt extends Operation {
|
||||
{
|
||||
name: "ECB",
|
||||
off: [5]
|
||||
},
|
||||
{
|
||||
name: "CBC/NoPadding",
|
||||
off: [5]
|
||||
},
|
||||
{
|
||||
name: "ECB/NoPadding",
|
||||
off: [5]
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -98,7 +106,8 @@ class AESEncrypt extends Operation {
|
||||
run(input, args) {
|
||||
const key = Utils.convertToByteString(args[0].string, args[0].option),
|
||||
iv = Utils.convertToByteString(args[1].string, args[1].option),
|
||||
mode = args[2],
|
||||
mode = args[2].split("/")[0],
|
||||
noPadding = args[2].endsWith("NoPadding"),
|
||||
inputType = args[3],
|
||||
outputType = args[4],
|
||||
aad = Utils.convertToByteString(args[5].string, args[5].option);
|
||||
@@ -114,11 +123,20 @@ The following algorithms will be used based on the size of the key:
|
||||
|
||||
input = Utils.convertToByteString(input, inputType);
|
||||
|
||||
// Handle NoPadding modes
|
||||
if (noPadding && input.length % 16 !== 0) {
|
||||
throw new OperationError("Input length must be a multiple of 16 bytes for NoPadding modes.");
|
||||
}
|
||||
const cipher = forge.cipher.createCipher("AES-" + mode, key);
|
||||
cipher.start({
|
||||
iv: iv,
|
||||
additionalData: mode === "GCM" ? aad : undefined
|
||||
});
|
||||
if (noPadding) {
|
||||
cipher.mode.pad = function(output, options) {
|
||||
return true;
|
||||
};
|
||||
}
|
||||
cipher.update(forge.util.createBuffer(input));
|
||||
cipher.finish();
|
||||
|
||||
|
||||
53
src/core/operations/AlternatingCaps.mjs
Normal file
53
src/core/operations/AlternatingCaps.mjs
Normal file
@@ -0,0 +1,53 @@
|
||||
/**
|
||||
* @author sw5678
|
||||
* @copyright Crown Copyright 2023
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation.mjs";
|
||||
|
||||
/**
|
||||
* Alternating caps operation
|
||||
*/
|
||||
class AlternatingCaps extends Operation {
|
||||
|
||||
/**
|
||||
* AlternatingCaps constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "Alternating Caps";
|
||||
this.module = "Default";
|
||||
this.description = "Alternating caps, also known as studly caps, sticky caps, or spongecase is a form of text notation in which the capitalization of letters varies by some pattern, or arbitrarily. An example of this would be spelling 'alternative caps' as 'aLtErNaTiNg CaPs'.";
|
||||
this.infoURL = "https://en.wikipedia.org/wiki/Alternating_caps";
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
this.args= [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
let output = "";
|
||||
let previousCaps = true;
|
||||
for (let i = 0; i < input.length; i++) {
|
||||
// Check if the element is a letter
|
||||
if (!RegExp(/^\p{L}/, "u").test(input[i])) {
|
||||
output += input[i];
|
||||
} else if (previousCaps) {
|
||||
output += input[i].toLowerCase();
|
||||
previousCaps = false;
|
||||
} else {
|
||||
output += input[i].toUpperCase();
|
||||
previousCaps = true;
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
}
|
||||
|
||||
export default AlternatingCaps;
|
||||
48
src/core/operations/AnalyseUUID.mjs
Normal file
48
src/core/operations/AnalyseUUID.mjs
Normal file
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
* @copyright Crown Copyright 2023
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import * as uuid from "uuid";
|
||||
|
||||
import Operation from "../Operation.mjs";
|
||||
import OperationError from "../errors/OperationError.mjs";
|
||||
|
||||
/**
|
||||
* Analyse UUID operation
|
||||
*/
|
||||
class AnalyseUUID extends Operation {
|
||||
|
||||
/**
|
||||
* AnalyseUUID constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "Analyse UUID";
|
||||
this.module = "Crypto";
|
||||
this.description = "Tries to determine information about a given UUID and suggests which version may have been used to generate it";
|
||||
this.infoURL = "https://wikipedia.org/wiki/Universally_unique_identifier";
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
this.args = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
try {
|
||||
const uuidVersion = uuid.version(input);
|
||||
return "UUID version: " + uuidVersion;
|
||||
} catch (error) {
|
||||
throw new OperationError("Invalid UUID");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default AnalyseUUID;
|
||||
58
src/core/operations/BLAKE3.mjs
Normal file
58
src/core/operations/BLAKE3.mjs
Normal file
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
* @author xumptex [xumptex@outlook.fr]
|
||||
* @copyright Crown Copyright 2025
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation.mjs";
|
||||
import OperationError from "../errors/OperationError.mjs";
|
||||
import { blake3 } from "hash-wasm";
|
||||
/**
|
||||
* BLAKE3 operation
|
||||
*/
|
||||
class BLAKE3 extends Operation {
|
||||
|
||||
/**
|
||||
* BLAKE3 constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "BLAKE3";
|
||||
this.module = "Hashing";
|
||||
this.description = "Hashes the input using BLAKE3 (UTF-8 encoded), with an optional key (also UTF-8), and outputs the result in hexadecimal format.";
|
||||
this.infoURL = "https://en.wikipedia.org/wiki/BLAKE_(hash_function)#BLAKE3";
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
this.args = [
|
||||
{
|
||||
"name": "Size (bytes)",
|
||||
"type": "number"
|
||||
}, {
|
||||
"name": "Key",
|
||||
"type": "string",
|
||||
"value": ""
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
const key = args[1];
|
||||
const size = args[0];
|
||||
// Check if the user want a key hash or not
|
||||
if (key === "") {
|
||||
return blake3(input, size*8);
|
||||
} if (key.length !== 32) {
|
||||
throw new OperationError("The key must be exactly 32 bytes long");
|
||||
}
|
||||
return blake3(input, size*8, key);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default BLAKE3;
|
||||
@@ -9,6 +9,7 @@ import OperationError from "../errors/OperationError.mjs";
|
||||
import { fromBase64 } from "../lib/Base64.mjs";
|
||||
import { toHexFast } from "../lib/Hex.mjs";
|
||||
import r from "jsrsasign";
|
||||
import Utils from "../Utils.mjs";
|
||||
|
||||
/**
|
||||
* ECDSA Verify operation
|
||||
@@ -59,6 +60,11 @@ class ECDSAVerify extends Operation {
|
||||
name: "Message",
|
||||
type: "text",
|
||||
value: ""
|
||||
},
|
||||
{
|
||||
name: "Message format",
|
||||
type: "option",
|
||||
value: ["Raw", "Hex", "Base64"]
|
||||
}
|
||||
];
|
||||
}
|
||||
@@ -70,7 +76,7 @@ class ECDSAVerify extends Operation {
|
||||
*/
|
||||
run(input, args) {
|
||||
let inputFormat = args[0];
|
||||
const [, mdAlgo, keyPem, msg] = args;
|
||||
const [, mdAlgo, keyPem, msg, msgFormat] = args;
|
||||
|
||||
if (keyPem.replace("-----BEGIN PUBLIC KEY-----", "").length === 0) {
|
||||
throw new OperationError("Please enter a public key.");
|
||||
@@ -145,7 +151,8 @@ class ECDSAVerify extends Operation {
|
||||
throw new OperationError("Provided key is not a public key.");
|
||||
}
|
||||
sig.init(key);
|
||||
sig.updateString(msg);
|
||||
const messageStr = Utils.convertToByteString(msg, msgFormat);
|
||||
sig.updateString(messageStr);
|
||||
const result = sig.verify(signatureASN1Hex);
|
||||
return result ? "Verified OK" : "Verification Failure";
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ class ExtractEmailAddresses extends Operation {
|
||||
run(input, args) {
|
||||
const [displayTotal, sort, unique] = args,
|
||||
// email regex from: https://www.regextester.com/98066
|
||||
regex = /(?:[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9](?:[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9-]*[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9])?\.)+[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9](?:[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9-]*[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}\])/ig;
|
||||
regex = /(?:[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9](?:[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9-]*[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9])?\.)+[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9](?:[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9-]*[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\])/ig;
|
||||
|
||||
const results = search(
|
||||
input,
|
||||
|
||||
@@ -21,7 +21,7 @@ class ExtractIPAddresses extends Operation {
|
||||
|
||||
this.name = "Extract IP addresses";
|
||||
this.module = "Regex";
|
||||
this.description = "Extracts all IPv4 and IPv6 addresses.<br><br>Warning: Given a string <code>710.65.0.456</code>, this will match <code>10.65.0.45</code> so always check the original input!";
|
||||
this.description = "Extracts all IPv4 and IPv6 addresses.<br><br>Warning: Given a string <code>1.2.3.4.5.6.7.8</code>, this will match <code>1.2.3.4 and 5.6.7.8</code> so always check the original input!";
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
this.args = [
|
||||
@@ -65,7 +65,21 @@ class ExtractIPAddresses extends Operation {
|
||||
*/
|
||||
run(input, args) {
|
||||
const [includeIpv4, includeIpv6, removeLocal, displayTotal, sort, unique] = args,
|
||||
ipv4 = "(?:(?:\\d|[01]?\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d\\d|\\d)(?:\\/\\d{1,2})?",
|
||||
|
||||
// IPv4 decimal groups can have values 0 to 255. To construct a regex the following sub-regex is reused:
|
||||
ipv4DecimalByte = "(?:25[0-5]|2[0-4]\\d|1?[0-9]\\d|\\d)",
|
||||
ipv4OctalByte = "(?:0[1-3]?[0-7]{1,2})",
|
||||
|
||||
// Look behind and ahead will be used to exclude matches with additional decimal digits left and right of IP address
|
||||
lookBehind = "(?<!\\d)",
|
||||
lookAhead = "(?!\\d)",
|
||||
|
||||
// Each variant requires exactly 4 groups with literal . between.
|
||||
ipv4Decimal = "(?:" + lookBehind + ipv4DecimalByte + "\\.){3}" + "(?:" + ipv4DecimalByte + lookAhead + ")",
|
||||
ipv4Octal = "(?:" + lookBehind + ipv4OctalByte + "\\.){3}" + "(?:" + ipv4OctalByte + lookAhead + ")",
|
||||
|
||||
// Then we allow IPv4 addresses to be expressed either entirely in decimal or entirely in Octal
|
||||
ipv4 = "(?:" + ipv4Decimal + "|" + ipv4Octal + ")",
|
||||
ipv6 = "((?=.*::)(?!.*::.+::)(::)?([\\dA-F]{1,4}:(:|\\b)|){5}|([\\dA-F]{1,4}:){6})(([\\dA-F]{1,4}((?!\\3)::|:\\b|(?![\\dA-F])))|(?!\\2\\3)){2}";
|
||||
let ips = "";
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
|
||||
import Operation from "../Operation.mjs";
|
||||
import Utils from "../Utils.mjs";
|
||||
import {ALPHABET_OPTIONS} from "../lib/Base32.mjs";
|
||||
|
||||
|
||||
/**
|
||||
* From Base32 operation
|
||||
@@ -27,8 +29,8 @@ class FromBase32 extends Operation {
|
||||
this.args = [
|
||||
{
|
||||
name: "Alphabet",
|
||||
type: "binaryString",
|
||||
value: "A-Z2-7="
|
||||
type: "editableOption",
|
||||
value: ALPHABET_OPTIONS
|
||||
},
|
||||
{
|
||||
name: "Remove non-alphabet chars",
|
||||
@@ -41,6 +43,11 @@ class FromBase32 extends Operation {
|
||||
pattern: "^(?:[A-Z2-7]{8})+(?:[A-Z2-7]{2}={6}|[A-Z2-7]{4}={4}|[A-Z2-7]{5}={3}|[A-Z2-7]{7}={1})?$",
|
||||
flags: "",
|
||||
args: ["A-Z2-7=", false]
|
||||
},
|
||||
{
|
||||
pattern: "^(?:[0-9A-V]{8})+(?:[0-9A-V]{2}={6}|[0-9A-V]{4}={4}|[0-9A-V]{5}={3}|[0-9A-V]{7}={1})?$",
|
||||
flags: "",
|
||||
args: ["0-9A-V=", false]
|
||||
}
|
||||
];
|
||||
}
|
||||
@@ -96,3 +103,4 @@ class FromBase32 extends Operation {
|
||||
}
|
||||
|
||||
export default FromBase32;
|
||||
|
||||
|
||||
254
src/core/operations/GenerateAllChecksums.mjs
Normal file
254
src/core/operations/GenerateAllChecksums.mjs
Normal file
@@ -0,0 +1,254 @@
|
||||
/**
|
||||
* @author r4mos [2k95ljkhg@mozmail.com]
|
||||
* @copyright Crown Copyright 2025
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation.mjs";
|
||||
import Adler32Checksum from "./Adler32Checksum.mjs";
|
||||
import CRCChecksum from "./CRCChecksum.mjs";
|
||||
import Fletcher8Checksum from "./Fletcher8Checksum.mjs";
|
||||
import Fletcher16Checksum from "./Fletcher16Checksum.mjs";
|
||||
import Fletcher32Checksum from "./Fletcher32Checksum.mjs";
|
||||
import Fletcher64Checksum from "./Fletcher64Checksum.mjs";
|
||||
|
||||
/**
|
||||
* Generate all checksums operation
|
||||
*/
|
||||
class GenerateAllChecksums extends Operation {
|
||||
|
||||
/**
|
||||
* GenerateAllChecksums constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "Generate all checksums";
|
||||
this.module = "Crypto";
|
||||
this.description = "Generates all available checksums for the input.";
|
||||
this.infoURL = "https://wikipedia.org/wiki/Checksum";
|
||||
this.inputType = "ArrayBuffer";
|
||||
this.outputType = "string";
|
||||
this.args = [
|
||||
{
|
||||
name: "Length (bits)",
|
||||
type: "option",
|
||||
value: [
|
||||
"All", "3", "4", "5", "6", "7", "8", "10", "11", "12", "13", "14", "15", "16", "17", "21", "24", "30", "31", "32", "40", "64", "82"
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Include names",
|
||||
type: "boolean",
|
||||
value: true
|
||||
},
|
||||
];
|
||||
|
||||
const adler32 = new Adler32Checksum;
|
||||
const crc = new CRCChecksum;
|
||||
const fletcher8 = new Fletcher8Checksum;
|
||||
const fletcher16 = new Fletcher16Checksum;
|
||||
const fletcher32 = new Fletcher32Checksum;
|
||||
const fletcher64 = new Fletcher64Checksum;
|
||||
this.checksums = [
|
||||
{name: "CRC-3/GSM", algo: crc, params: ["CRC-3/GSM"]},
|
||||
{name: "CRC-3/ROHC", algo: crc, params: ["CRC-3/ROHC"]},
|
||||
{name: "CRC-4/G-704", algo: crc, params: ["CRC-4/G-704"]},
|
||||
{name: "CRC-4/INTERLAKEN", algo: crc, params: ["CRC-4/INTERLAKEN"]},
|
||||
{name: "CRC-4/ITU", algo: crc, params: ["CRC-4/ITU"]},
|
||||
{name: "CRC-5/EPC", algo: crc, params: ["CRC-5/EPC"]},
|
||||
{name: "CRC-5/EPC-C1G2", algo: crc, params: ["CRC-5/EPC-C1G2"]},
|
||||
{name: "CRC-5/G-704", algo: crc, params: ["CRC-5/G-704"]},
|
||||
{name: "CRC-5/ITU", algo: crc, params: ["CRC-5/ITU"]},
|
||||
{name: "CRC-5/USB", algo: crc, params: ["CRC-5/USB"]},
|
||||
{name: "CRC-6/CDMA2000-A", algo: crc, params: ["CRC-6/CDMA2000-A"]},
|
||||
{name: "CRC-6/CDMA2000-B", algo: crc, params: ["CRC-6/CDMA2000-B"]},
|
||||
{name: "CRC-6/DARC", algo: crc, params: ["CRC-6/DARC"]},
|
||||
{name: "CRC-6/G-704", algo: crc, params: ["CRC-6/G-704"]},
|
||||
{name: "CRC-6/GSM", algo: crc, params: ["CRC-6/GSM"]},
|
||||
{name: "CRC-6/ITU", algo: crc, params: ["CRC-6/ITU"]},
|
||||
{name: "CRC-7/MMC", algo: crc, params: ["CRC-7/MMC"]},
|
||||
{name: "CRC-7/ROHC", algo: crc, params: ["CRC-7/ROHC"]},
|
||||
{name: "CRC-7/UMTS", algo: crc, params: ["CRC-7/UMTS"]},
|
||||
{name: "CRC-8", algo: crc, params: ["CRC-8"]},
|
||||
{name: "CRC-8/8H2F", algo: crc, params: ["CRC-8/8H2F"]},
|
||||
{name: "CRC-8/AES", algo: crc, params: ["CRC-8/AES"]},
|
||||
{name: "CRC-8/AUTOSAR", algo: crc, params: ["CRC-8/AUTOSAR"]},
|
||||
{name: "CRC-8/BLUETOOTH", algo: crc, params: ["CRC-8/BLUETOOTH"]},
|
||||
{name: "CRC-8/CDMA2000", algo: crc, params: ["CRC-8/CDMA2000"]},
|
||||
{name: "CRC-8/DARC", algo: crc, params: ["CRC-8/DARC"]},
|
||||
{name: "CRC-8/DVB-S2", algo: crc, params: ["CRC-8/DVB-S2"]},
|
||||
{name: "CRC-8/EBU", algo: crc, params: ["CRC-8/EBU"]},
|
||||
{name: "CRC-8/GSM-A", algo: crc, params: ["CRC-8/GSM-A"]},
|
||||
{name: "CRC-8/GSM-B", algo: crc, params: ["CRC-8/GSM-B"]},
|
||||
{name: "CRC-8/HITAG", algo: crc, params: ["CRC-8/HITAG"]},
|
||||
{name: "CRC-8/I-432-1", algo: crc, params: ["CRC-8/I-432-1"]},
|
||||
{name: "CRC-8/I-CODE", algo: crc, params: ["CRC-8/I-CODE"]},
|
||||
{name: "CRC-8/ITU", algo: crc, params: ["CRC-8/ITU"]},
|
||||
{name: "CRC-8/LTE", algo: crc, params: ["CRC-8/LTE"]},
|
||||
{name: "CRC-8/MAXIM", algo: crc, params: ["CRC-8/MAXIM"]},
|
||||
{name: "CRC-8/MAXIM-DOW", algo: crc, params: ["CRC-8/MAXIM-DOW"]},
|
||||
{name: "CRC-8/MIFARE-MAD", algo: crc, params: ["CRC-8/MIFARE-MAD"]},
|
||||
{name: "CRC-8/NRSC-5", algo: crc, params: ["CRC-8/NRSC-5"]},
|
||||
{name: "CRC-8/OPENSAFETY", algo: crc, params: ["CRC-8/OPENSAFETY"]},
|
||||
{name: "CRC-8/ROHC", algo: crc, params: ["CRC-8/ROHC"]},
|
||||
{name: "CRC-8/SAE-J1850", algo: crc, params: ["CRC-8/SAE-J1850"]},
|
||||
{name: "CRC-8/SAE-J1850-ZERO", algo: crc, params: ["CRC-8/SAE-J1850-ZERO"]},
|
||||
{name: "CRC-8/SMBUS", algo: crc, params: ["CRC-8/SMBUS"]},
|
||||
{name: "CRC-8/TECH-3250", algo: crc, params: ["CRC-8/TECH-3250"]},
|
||||
{name: "CRC-8/WCDMA", algo: crc, params: ["CRC-8/WCDMA"]},
|
||||
{name: "Fletcher-8", algo: fletcher8, params: []},
|
||||
{name: "CRC-10/ATM", algo: crc, params: ["CRC-10/ATM"]},
|
||||
{name: "CRC-10/CDMA2000", algo: crc, params: ["CRC-10/CDMA2000"]},
|
||||
{name: "CRC-10/GSM", algo: crc, params: ["CRC-10/GSM"]},
|
||||
{name: "CRC-10/I-610", algo: crc, params: ["CRC-10/I-610"]},
|
||||
{name: "CRC-11/FLEXRAY", algo: crc, params: ["CRC-11/FLEXRAY"]},
|
||||
{name: "CRC-11/UMTS", algo: crc, params: ["CRC-11/UMTS"]},
|
||||
{name: "CRC-12/3GPP", algo: crc, params: ["CRC-12/3GPP"]},
|
||||
{name: "CRC-12/CDMA2000", algo: crc, params: ["CRC-12/CDMA2000"]},
|
||||
{name: "CRC-12/DECT", algo: crc, params: ["CRC-12/DECT"]},
|
||||
{name: "CRC-12/GSM", algo: crc, params: ["CRC-12/GSM"]},
|
||||
{name: "CRC-12/UMTS", algo: crc, params: ["CRC-12/UMTS"]},
|
||||
{name: "CRC-13/BBC", algo: crc, params: ["CRC-13/BBC"]},
|
||||
{name: "CRC-14/DARC", algo: crc, params: ["CRC-14/DARC"]},
|
||||
{name: "CRC-14/GSM", algo: crc, params: ["CRC-14/GSM"]},
|
||||
{name: "CRC-15/CAN", algo: crc, params: ["CRC-15/CAN"]},
|
||||
{name: "CRC-15/MPT1327", algo: crc, params: ["CRC-15/MPT1327"]},
|
||||
{name: "CRC-16", algo: crc, params: ["CRC-16"]},
|
||||
{name: "CRC-16/A", algo: crc, params: ["CRC-16/A"]},
|
||||
{name: "CRC-16/ACORN", algo: crc, params: ["CRC-16/ACORN"]},
|
||||
{name: "CRC-16/ARC", algo: crc, params: ["CRC-16/ARC"]},
|
||||
{name: "CRC-16/AUG-CCITT", algo: crc, params: ["CRC-16/AUG-CCITT"]},
|
||||
{name: "CRC-16/AUTOSAR", algo: crc, params: ["CRC-16/AUTOSAR"]},
|
||||
{name: "CRC-16/B", algo: crc, params: ["CRC-16/B"]},
|
||||
{name: "CRC-16/BLUETOOTH", algo: crc, params: ["CRC-16/BLUETOOTH"]},
|
||||
{name: "CRC-16/BUYPASS", algo: crc, params: ["CRC-16/BUYPASS"]},
|
||||
{name: "CRC-16/CCITT", algo: crc, params: ["CRC-16/CCITT"]},
|
||||
{name: "CRC-16/CCITT-FALSE", algo: crc, params: ["CRC-16/CCITT-FALSE"]},
|
||||
{name: "CRC-16/CCITT-TRUE", algo: crc, params: ["CRC-16/CCITT-TRUE"]},
|
||||
{name: "CRC-16/CCITT-ZERO", algo: crc, params: ["CRC-16/CCITT-ZERO"]},
|
||||
{name: "CRC-16/CDMA2000", algo: crc, params: ["CRC-16/CDMA2000"]},
|
||||
{name: "CRC-16/CMS", algo: crc, params: ["CRC-16/CMS"]},
|
||||
{name: "CRC-16/DARC", algo: crc, params: ["CRC-16/DARC"]},
|
||||
{name: "CRC-16/DDS-110", algo: crc, params: ["CRC-16/DDS-110"]},
|
||||
{name: "CRC-16/DECT-R", algo: crc, params: ["CRC-16/DECT-R"]},
|
||||
{name: "CRC-16/DECT-X", algo: crc, params: ["CRC-16/DECT-X"]},
|
||||
{name: "CRC-16/DNP", algo: crc, params: ["CRC-16/DNP"]},
|
||||
{name: "CRC-16/EN-13757", algo: crc, params: ["CRC-16/EN-13757"]},
|
||||
{name: "CRC-16/EPC", algo: crc, params: ["CRC-16/EPC"]},
|
||||
{name: "CRC-16/EPC-C1G2", algo: crc, params: ["CRC-16/EPC-C1G2"]},
|
||||
{name: "CRC-16/GENIBUS", algo: crc, params: ["CRC-16/GENIBUS"]},
|
||||
{name: "CRC-16/GSM", algo: crc, params: ["CRC-16/GSM"]},
|
||||
{name: "CRC-16/I-CODE", algo: crc, params: ["CRC-16/I-CODE"]},
|
||||
{name: "CRC-16/IBM", algo: crc, params: ["CRC-16/IBM"]},
|
||||
{name: "CRC-16/IBM-3740", algo: crc, params: ["CRC-16/IBM-3740"]},
|
||||
{name: "CRC-16/IBM-SDLC", algo: crc, params: ["CRC-16/IBM-SDLC"]},
|
||||
{name: "CRC-16/IEC-61158-2", algo: crc, params: ["CRC-16/IEC-61158-2"]},
|
||||
{name: "CRC-16/ISO-HDLC", algo: crc, params: ["CRC-16/ISO-HDLC"]},
|
||||
{name: "CRC-16/ISO-IEC-14443-3-A", algo: crc, params: ["CRC-16/ISO-IEC-14443-3-A"]},
|
||||
{name: "CRC-16/ISO-IEC-14443-3-B", algo: crc, params: ["CRC-16/ISO-IEC-14443-3-B"]},
|
||||
{name: "CRC-16/KERMIT", algo: crc, params: ["CRC-16/KERMIT"]},
|
||||
{name: "CRC-16/LHA", algo: crc, params: ["CRC-16/LHA"]},
|
||||
{name: "CRC-16/LJ1200", algo: crc, params: ["CRC-16/LJ1200"]},
|
||||
{name: "CRC-16/LTE", algo: crc, params: ["CRC-16/LTE"]},
|
||||
{name: "CRC-16/M17", algo: crc, params: ["CRC-16/M17"]},
|
||||
{name: "CRC-16/MAXIM", algo: crc, params: ["CRC-16/MAXIM"]},
|
||||
{name: "CRC-16/MAXIM-DOW", algo: crc, params: ["CRC-16/MAXIM-DOW"]},
|
||||
{name: "CRC-16/MCRF4XX", algo: crc, params: ["CRC-16/MCRF4XX"]},
|
||||
{name: "CRC-16/MODBUS", algo: crc, params: ["CRC-16/MODBUS"]},
|
||||
{name: "CRC-16/NRSC-5", algo: crc, params: ["CRC-16/NRSC-5"]},
|
||||
{name: "CRC-16/OPENSAFETY-A", algo: crc, params: ["CRC-16/OPENSAFETY-A"]},
|
||||
{name: "CRC-16/OPENSAFETY-B", algo: crc, params: ["CRC-16/OPENSAFETY-B"]},
|
||||
{name: "CRC-16/PROFIBUS", algo: crc, params: ["CRC-16/PROFIBUS"]},
|
||||
{name: "CRC-16/RIELLO", algo: crc, params: ["CRC-16/RIELLO"]},
|
||||
{name: "CRC-16/SPI-FUJITSU", algo: crc, params: ["CRC-16/SPI-FUJITSU"]},
|
||||
{name: "CRC-16/T10-DIF", algo: crc, params: ["CRC-16/T10-DIF"]},
|
||||
{name: "CRC-16/TELEDISK", algo: crc, params: ["CRC-16/TELEDISK"]},
|
||||
{name: "CRC-16/TMS37157", algo: crc, params: ["CRC-16/TMS37157"]},
|
||||
{name: "CRC-16/UMTS", algo: crc, params: ["CRC-16/UMTS"]},
|
||||
{name: "CRC-16/USB", algo: crc, params: ["CRC-16/USB"]},
|
||||
{name: "CRC-16/V-41-LSB", algo: crc, params: ["CRC-16/V-41-LSB"]},
|
||||
{name: "CRC-16/V-41-MSB", algo: crc, params: ["CRC-16/V-41-MSB"]},
|
||||
{name: "CRC-16/VERIFONE", algo: crc, params: ["CRC-16/VERIFONE"]},
|
||||
{name: "CRC-16/X-25", algo: crc, params: ["CRC-16/X-25"]},
|
||||
{name: "CRC-16/XMODEM", algo: crc, params: ["CRC-16/XMODEM"]},
|
||||
{name: "CRC-16/ZMODEM", algo: crc, params: ["CRC-16/ZMODEM"]},
|
||||
{name: "Fletcher-16", algo: fletcher16, params: []},
|
||||
{name: "CRC-17/CAN-FD", algo: crc, params: ["CRC-17/CAN-FD"]},
|
||||
{name: "CRC-21/CAN-FD", algo: crc, params: ["CRC-21/CAN-FD"]},
|
||||
{name: "CRC-24/BLE", algo: crc, params: ["CRC-24/BLE"]},
|
||||
{name: "CRC-24/FLEXRAY-A", algo: crc, params: ["CRC-24/FLEXRAY-A"]},
|
||||
{name: "CRC-24/FLEXRAY-B", algo: crc, params: ["CRC-24/FLEXRAY-B"]},
|
||||
{name: "CRC-24/INTERLAKEN", algo: crc, params: ["CRC-24/INTERLAKEN"]},
|
||||
{name: "CRC-24/LTE-A", algo: crc, params: ["CRC-24/LTE-A"]},
|
||||
{name: "CRC-24/LTE-B", algo: crc, params: ["CRC-24/LTE-B"]},
|
||||
{name: "CRC-24/OPENPGP", algo: crc, params: ["CRC-24/OPENPGP"]},
|
||||
{name: "CRC-24/OS-9", algo: crc, params: ["CRC-24/OS-9"]},
|
||||
{name: "CRC-30/CDMA", algo: crc, params: ["CRC-30/CDMA"]},
|
||||
{name: "CRC-31/PHILIPS", algo: crc, params: ["CRC-31/PHILIPS"]},
|
||||
{name: "Adler-32", algo: adler32, params: []},
|
||||
{name: "CRC-32", algo: crc, params: ["CRC-32"]},
|
||||
{name: "CRC-32/AAL5", algo: crc, params: ["CRC-32/AAL5"]},
|
||||
{name: "CRC-32/ADCCP", algo: crc, params: ["CRC-32/ADCCP"]},
|
||||
{name: "CRC-32/AIXM", algo: crc, params: ["CRC-32/AIXM"]},
|
||||
{name: "CRC-32/AUTOSAR", algo: crc, params: ["CRC-32/AUTOSAR"]},
|
||||
{name: "CRC-32/BASE91-C", algo: crc, params: ["CRC-32/BASE91-C"]},
|
||||
{name: "CRC-32/BASE91-D", algo: crc, params: ["CRC-32/BASE91-D"]},
|
||||
{name: "CRC-32/BZIP2", algo: crc, params: ["CRC-32/BZIP2"]},
|
||||
{name: "CRC-32/C", algo: crc, params: ["CRC-32/C"]},
|
||||
{name: "CRC-32/CASTAGNOLI", algo: crc, params: ["CRC-32/CASTAGNOLI"]},
|
||||
{name: "CRC-32/CD-ROM-EDC", algo: crc, params: ["CRC-32/CD-ROM-EDC"]},
|
||||
{name: "CRC-32/CKSUM", algo: crc, params: ["CRC-32/CKSUM"]},
|
||||
{name: "CRC-32/D", algo: crc, params: ["CRC-32/D"]},
|
||||
{name: "CRC-32/DECT-B", algo: crc, params: ["CRC-32/DECT-B"]},
|
||||
{name: "CRC-32/INTERLAKEN", algo: crc, params: ["CRC-32/INTERLAKEN"]},
|
||||
{name: "CRC-32/ISCSI", algo: crc, params: ["CRC-32/ISCSI"]},
|
||||
{name: "CRC-32/ISO-HDLC", algo: crc, params: ["CRC-32/ISO-HDLC"]},
|
||||
{name: "CRC-32/JAMCRC", algo: crc, params: ["CRC-32/JAMCRC"]},
|
||||
{name: "CRC-32/MEF", algo: crc, params: ["CRC-32/MEF"]},
|
||||
{name: "CRC-32/MPEG-2", algo: crc, params: ["CRC-32/MPEG-2"]},
|
||||
{name: "CRC-32/NVME", algo: crc, params: ["CRC-32/NVME"]},
|
||||
{name: "CRC-32/PKZIP", algo: crc, params: ["CRC-32/PKZIP"]},
|
||||
{name: "CRC-32/POSIX", algo: crc, params: ["CRC-32/POSIX"]},
|
||||
{name: "CRC-32/Q", algo: crc, params: ["CRC-32/Q"]},
|
||||
{name: "CRC-32/SATA", algo: crc, params: ["CRC-32/SATA"]},
|
||||
{name: "CRC-32/V-42", algo: crc, params: ["CRC-32/V-42"]},
|
||||
{name: "CRC-32/XFER", algo: crc, params: ["CRC-32/XFER"]},
|
||||
{name: "CRC-32/XZ", algo: crc, params: ["CRC-32/XZ"]},
|
||||
{name: "Fletcher-32", algo: fletcher32, params: []},
|
||||
{name: "CRC-40/GSM", algo: crc, params: ["CRC-40/GSM"]},
|
||||
{name: "CRC-64/ECMA-182", algo: crc, params: ["CRC-64/ECMA-182"]},
|
||||
{name: "CRC-64/GO-ECMA", algo: crc, params: ["CRC-64/GO-ECMA"]},
|
||||
{name: "CRC-64/GO-ISO", algo: crc, params: ["CRC-64/GO-ISO"]},
|
||||
{name: "CRC-64/MS", algo: crc, params: ["CRC-64/MS"]},
|
||||
{name: "CRC-64/NVME", algo: crc, params: ["CRC-64/NVME"]},
|
||||
{name: "CRC-64/REDIS", algo: crc, params: ["CRC-64/REDIS"]},
|
||||
{name: "CRC-64/WE", algo: crc, params: ["CRC-64/WE"]},
|
||||
{name: "CRC-64/XZ", algo: crc, params: ["CRC-64/XZ"]},
|
||||
{name: "Fletcher-64", algo: fletcher64, params: []},
|
||||
{name: "CRC-82/DARC", algo: crc, params: ["CRC-82/DARC"]}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {ArrayBuffer} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
const [length, includeNames] = args;
|
||||
let output = "";
|
||||
this.checksums.forEach(checksum => {
|
||||
const checksumLength = checksum.name.match(new RegExp("-(\\d{1,2})(\\/|$)"))[1];
|
||||
if (length === "All" || length === checksumLength) {
|
||||
const value = checksum.algo.run(new Uint8Array(input), checksum.params || []);
|
||||
output += includeNames ?
|
||||
`${checksum.name}:${" ".repeat(25-checksum.name.length)}${value}\n`:
|
||||
`${value}\n`;
|
||||
}
|
||||
});
|
||||
return output;
|
||||
}
|
||||
}
|
||||
|
||||
export default GenerateAllChecksums;
|
||||
@@ -22,12 +22,6 @@ import HAS160 from "./HAS160.mjs";
|
||||
import Whirlpool from "./Whirlpool.mjs";
|
||||
import SSDEEP from "./SSDEEP.mjs";
|
||||
import CTPH from "./CTPH.mjs";
|
||||
import Fletcher8Checksum from "./Fletcher8Checksum.mjs";
|
||||
import Fletcher16Checksum from "./Fletcher16Checksum.mjs";
|
||||
import Fletcher32Checksum from "./Fletcher32Checksum.mjs";
|
||||
import Fletcher64Checksum from "./Fletcher64Checksum.mjs";
|
||||
import Adler32Checksum from "./Adler32Checksum.mjs";
|
||||
import CRCChecksum from "./CRCChecksum.mjs";
|
||||
import BLAKE2b from "./BLAKE2b.mjs";
|
||||
import BLAKE2s from "./BLAKE2s.mjs";
|
||||
import Streebog from "./Streebog.mjs";
|
||||
@@ -112,16 +106,6 @@ class GenerateAllHashes extends Operation {
|
||||
{name: "SSDEEP", algo: (new SSDEEP()), inputType: "str"},
|
||||
{name: "CTPH", algo: (new CTPH()), inputType: "str"}
|
||||
];
|
||||
this.checksums = [
|
||||
{name: "Fletcher-8", algo: (new Fletcher8Checksum), inputType: "byteArray", params: []},
|
||||
{name: "Fletcher-16", algo: (new Fletcher16Checksum), inputType: "byteArray", params: []},
|
||||
{name: "Fletcher-32", algo: (new Fletcher32Checksum), inputType: "byteArray", params: []},
|
||||
{name: "Fletcher-64", algo: (new Fletcher64Checksum), inputType: "byteArray", params: []},
|
||||
{name: "Adler-32", algo: (new Adler32Checksum), inputType: "byteArray", params: []},
|
||||
{name: "CRC-8", algo: (new CRCChecksum), inputType: "arrayBuffer", params: ["CRC-8"]},
|
||||
{name: "CRC-16", algo: (new CRCChecksum), inputType: "arrayBuffer", params: ["CRC-16"]},
|
||||
{name: "CRC-32", algo: (new CRCChecksum), inputType: "arrayBuffer", params: ["CRC-32"]}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -142,14 +126,6 @@ class GenerateAllHashes extends Operation {
|
||||
output += this.formatDigest(digest, length, includeNames, hash.name);
|
||||
});
|
||||
|
||||
if (length === "All") {
|
||||
output += "\nChecksums:\n";
|
||||
this.checksums.forEach(checksum => {
|
||||
digest = this.executeAlgo(checksum.algo, checksum.inputType, checksum.params || []);
|
||||
output += this.formatDigest(digest, length, includeNames, checksum.name);
|
||||
});
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
*/
|
||||
|
||||
import Operation from "../Operation.mjs";
|
||||
import crypto from "crypto";
|
||||
|
||||
import * as uuid from "uuid";
|
||||
import OperationError from "../errors/OperationError.mjs";
|
||||
/**
|
||||
* Generate UUID operation
|
||||
*/
|
||||
@@ -20,11 +20,38 @@ class GenerateUUID extends Operation {
|
||||
|
||||
this.name = "Generate UUID";
|
||||
this.module = "Crypto";
|
||||
this.description = "Generates an RFC 4122 version 4 compliant Universally Unique Identifier (UUID), also known as a Globally Unique Identifier (GUID).<br><br>A version 4 UUID relies on random numbers, in this case generated using <code>window.crypto</code> if available and falling back to <code>Math.random</code> if not.";
|
||||
this.description =
|
||||
"Generates an RFC 9562 (formerly RFC 4122) compliant Universally Unique Identifier (UUID), " +
|
||||
"also known as a Globally Unique Identifier (GUID).<br>" +
|
||||
"<br>" +
|
||||
"We currently support generating the following UUID versions:<br>" +
|
||||
"<ul>" +
|
||||
"<li><strong>v1</strong>: Timestamp-based</li>" +
|
||||
"<li><strong>v3</strong>: Namespace w/ MD5</li>" +
|
||||
"<li><strong>v4</strong>: Random (default)</li>" +
|
||||
"<li><strong>v5</strong>: Namespace w/ SHA-1</li>" +
|
||||
"<li><strong>v6</strong>: Timestamp, reordered</li>" +
|
||||
"<li><strong>v7</strong>: Unix Epoch time-based</li>" +
|
||||
"</ul>" +
|
||||
"UUIDs are generated using the <a href='https://npmjs.org/uuid/'><code>uuid</code><a> package.<br>";
|
||||
this.infoURL = "https://wikipedia.org/wiki/Universally_unique_identifier";
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
this.args = [];
|
||||
this.args = [
|
||||
{
|
||||
name: "Version",
|
||||
hint: "UUID version",
|
||||
type: "option",
|
||||
value: ["v1", "v3", "v4", "v5", "v6", "v7"],
|
||||
defaultIndex: 2,
|
||||
},
|
||||
{
|
||||
name: "Namespace",
|
||||
hint: "UUID namespace (UUID; valid for v3 and v5)",
|
||||
type: "string",
|
||||
value: "1b671a64-40d5-491e-99b0-da01ff1f3341"
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -33,16 +60,17 @@ class GenerateUUID extends Operation {
|
||||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
const buf = new Uint32Array(4).map(() => {
|
||||
return crypto.randomBytes(4).readUInt32BE(0, true);
|
||||
});
|
||||
let i = 0;
|
||||
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) {
|
||||
const r = (buf[i >> 3] >> ((i % 8) * 4)) & 0xf,
|
||||
v = c === "x" ? r : (r & 0x3 | 0x8);
|
||||
i++;
|
||||
return v.toString(16);
|
||||
});
|
||||
const [version, namespace] = args;
|
||||
const hasDesiredVersion = typeof uuid[version] === "function";
|
||||
if (!hasDesiredVersion) throw new OperationError("Invalid UUID version");
|
||||
|
||||
const requiresNamespace = ["v3", "v5"].includes(version);
|
||||
if (!requiresNamespace) return uuid[version]();
|
||||
|
||||
const hasValidNamespace = typeof namespace === "string" && uuid.validate(namespace);
|
||||
if (!hasValidNamespace) throw new OperationError("Invalid UUID namespace");
|
||||
|
||||
return uuid[version](input, namespace);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
65
src/core/operations/Jsonata.mjs
Normal file
65
src/core/operations/Jsonata.mjs
Normal file
@@ -0,0 +1,65 @@
|
||||
/**
|
||||
* @author Jon K (jon@ajarsoftware.com)
|
||||
* @copyright Crown Copyright 2016
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import jsonata from "jsonata";
|
||||
import Operation from "../Operation.mjs";
|
||||
import OperationError from "../errors/OperationError.mjs";
|
||||
|
||||
/**
|
||||
* Jsonata Query operation
|
||||
*/
|
||||
class JsonataQuery extends Operation {
|
||||
/**
|
||||
* JsonataQuery constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "Jsonata Query";
|
||||
this.module = "Code";
|
||||
this.description =
|
||||
"Query and transform JSON data with a jsonata query.";
|
||||
this.infoURL = "https://docs.jsonata.org/overview.html";
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
this.args = [
|
||||
{
|
||||
name: "Query",
|
||||
type: "text",
|
||||
value: "string",
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
async run(input, args) {
|
||||
const [query] = args;
|
||||
let result, jsonObj;
|
||||
|
||||
try {
|
||||
jsonObj = JSON.parse(input);
|
||||
} catch (err) {
|
||||
throw new OperationError(`Invalid input JSON: ${err.message}`);
|
||||
}
|
||||
|
||||
try {
|
||||
const expression = jsonata(query);
|
||||
result = await expression.evaluate(jsonObj);
|
||||
} catch (err) {
|
||||
throw new OperationError(
|
||||
`Invalid Jsonata Expression: ${err.message}`
|
||||
);
|
||||
}
|
||||
|
||||
return JSON.stringify(result === undefined ? "" : result);
|
||||
}
|
||||
}
|
||||
|
||||
export default JsonataQuery;
|
||||
126
src/core/operations/PHPSerialize.mjs
Normal file
126
src/core/operations/PHPSerialize.mjs
Normal file
@@ -0,0 +1,126 @@
|
||||
/**
|
||||
* @author brun0ne [brunonblok@gmail.com]
|
||||
* @copyright Crown Copyright 2023
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation.mjs";
|
||||
import OperationError from "../errors/OperationError.mjs";
|
||||
|
||||
/**
|
||||
* PHP Serialize operation
|
||||
*/
|
||||
class PHPSerialize extends Operation {
|
||||
|
||||
/**
|
||||
* PHPSerialize constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "PHP Serialize";
|
||||
this.module = "Default";
|
||||
this.description = "Performs PHP serialization on JSON data.<br><br>This function does not support <code>object</code> tags.<br><br>Since PHP doesn't distinguish dicts and arrays, this operation is not always symmetric to <code>PHP Deserialize</code>.<br><br>Example:<br><code>[5,"abc",true]</code><br>becomes<br><code>a:3:{i:0;i:5;i:1;s:3:"abc";i:2;b:1;}<code>";
|
||||
this.infoURL = "https://www.phpinternalsbook.com/php5/classes_objects/serialization.html";
|
||||
this.inputType = "JSON";
|
||||
this.outputType = "string";
|
||||
this.args = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {JSON} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
/**
|
||||
* Determines if a number is an integer
|
||||
* @param {number} value
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isInteger(value) {
|
||||
return typeof value === "number" && parseInt(value.toString(), 10) === value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize basic types
|
||||
* @param {string | number | boolean} content
|
||||
* @returns {string}
|
||||
*/
|
||||
function serializeBasicTypes(content) {
|
||||
const basicTypes = {
|
||||
"string": "s",
|
||||
"integer": "i",
|
||||
"float": "d",
|
||||
"boolean": "b"
|
||||
};
|
||||
/**
|
||||
* Booleans
|
||||
* cast to 0 or 1
|
||||
*/
|
||||
if (typeof content === "boolean") {
|
||||
return `${basicTypes.boolean}:${content ? 1 : 0}`;
|
||||
}
|
||||
/* Numbers */
|
||||
if (typeof content === "number") {
|
||||
if (isInteger(content)) {
|
||||
return `${basicTypes.integer}:${content.toString()}`;
|
||||
} else {
|
||||
return `${basicTypes.float}:${content.toString()}`;
|
||||
}
|
||||
}
|
||||
/* Strings */
|
||||
if (typeof content === "string")
|
||||
return `${basicTypes.string}:${content.length}:"${content}"`;
|
||||
|
||||
/** This should be unreachable */
|
||||
throw new OperationError(`Encountered a non-implemented type: ${typeof content}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively serialize
|
||||
* @param {*} object
|
||||
* @returns {string}
|
||||
*/
|
||||
function serialize(object) {
|
||||
/* Null */
|
||||
if (object == null) {
|
||||
return `N;`;
|
||||
}
|
||||
|
||||
if (typeof object !== "object") {
|
||||
/* Basic types */
|
||||
return `${serializeBasicTypes(object)};`;
|
||||
} else if (object instanceof Array) {
|
||||
/* Arrays */
|
||||
const serializedElements = [];
|
||||
|
||||
for (let i = 0; i < object.length; i++) {
|
||||
serializedElements.push(`${serialize(i)}${serialize(object[i])}`);
|
||||
}
|
||||
|
||||
return `a:${object.length}:{${serializedElements.join("")}}`;
|
||||
} else if (object instanceof Object) {
|
||||
/**
|
||||
* Objects
|
||||
* Note: the output cannot be guaranteed to be in the same order as the input
|
||||
*/
|
||||
const serializedElements = [];
|
||||
const keys = Object.keys(object);
|
||||
|
||||
for (const key of keys) {
|
||||
serializedElements.push(`${serialize(key)}${serialize(object[key])}`);
|
||||
}
|
||||
|
||||
return `a:${keys.length}:{${serializedElements.join("")}}`;
|
||||
}
|
||||
|
||||
/** This should be unreachable */
|
||||
throw new OperationError(`Encountered a non-implemented type: ${typeof object}`);
|
||||
}
|
||||
|
||||
return serialize(input);
|
||||
}
|
||||
}
|
||||
|
||||
export default PHPSerialize;
|
||||
@@ -72,7 +72,7 @@ class RailFenceCipherDecode extends Operation {
|
||||
}
|
||||
}
|
||||
|
||||
return plaintext.join("").trim();
|
||||
return plaintext.join("");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ class RailFenceCipherEncode extends Operation {
|
||||
rows[rowIdx] += plaintext[pos];
|
||||
}
|
||||
|
||||
return rows.join("").trim();
|
||||
return rows.join("");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/**
|
||||
* @author j433866 [j433866@gmail.com]
|
||||
* @copyright Crown Copyright 2019
|
||||
* @author 0xff1ce [github.com/0xff1ce]
|
||||
* @copyright Crown Copyright 2024
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
@@ -22,7 +23,7 @@ class ShowOnMap extends Operation {
|
||||
this.name = "Show on map";
|
||||
this.module = "Hashing";
|
||||
this.description = "Displays co-ordinates on a slippy map.<br><br>Co-ordinates will be converted to decimal degrees before being shown on the map.<br><br>Supported formats:<ul><li>Degrees Minutes Seconds (DMS)</li><li>Degrees Decimal Minutes (DDM)</li><li>Decimal Degrees (DD)</li><li>Geohash</li><li>Military Grid Reference System (MGRS)</li><li>Ordnance Survey National Grid (OSNG)</li><li>Universal Transverse Mercator (UTM)</li></ul><br>This operation will not work offline.";
|
||||
this.infoURL = "https://foundation.wikimedia.org/wiki/Maps_Terms_of_Use";
|
||||
this.infoURL = "https://osmfoundation.org/wiki/Terms_of_Use";
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
this.presentType = "html";
|
||||
@@ -85,10 +86,10 @@ class ShowOnMap extends Operation {
|
||||
data = "0, 0";
|
||||
}
|
||||
const zoomLevel = args[0];
|
||||
const tileUrl = "https://maps.wikimedia.org/osm-intl/{z}/{x}/{y}.png",
|
||||
tileAttribution = "<a href=\"https://wikimediafoundation.org/wiki/Maps_Terms_of_Use\">Wikimedia maps</a> | © <a href=\"https://www.openstreetmap.org/copyright\">OpenStreetMap</a> contributors",
|
||||
leafletUrl = "https://unpkg.com/leaflet@1.5.0/dist/leaflet.js",
|
||||
leafletCssUrl = "https://unpkg.com/leaflet@1.5.0/dist/leaflet.css";
|
||||
const tileUrl = "https://tile.openstreetmap.org/{z}/{x}/{y}.png",
|
||||
tileAttribution = "© <a href=\"https://www.openstreetmap.org/copyright\">OpenStreetMap</a> contributors",
|
||||
leafletUrl = "https://unpkg.com/leaflet@1.9.4/dist/leaflet.js",
|
||||
leafletCssUrl = "https://unpkg.com/leaflet@1.9.4/dist/leaflet.css";
|
||||
return `<link rel="stylesheet" href="${leafletCssUrl}" crossorigin=""/>
|
||||
<style>
|
||||
#output-text .cm-content,
|
||||
|
||||
53
src/core/operations/Template.mjs
Normal file
53
src/core/operations/Template.mjs
Normal file
@@ -0,0 +1,53 @@
|
||||
/**
|
||||
* @author kendallgoto [k@kgo.to]
|
||||
* @copyright Crown Copyright 2025
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation.mjs";
|
||||
import OperationError from "../errors/OperationError.mjs";
|
||||
import Handlebars from "handlebars";
|
||||
|
||||
/**
|
||||
* Template operation
|
||||
*/
|
||||
class Template extends Operation {
|
||||
|
||||
/**
|
||||
* Template constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "Template";
|
||||
this.module = "Handlebars";
|
||||
this.description = "Render a template with Handlebars/Mustache substituting variables using JSON input. Templates will be rendered to plain-text only, to prevent XSS.";
|
||||
this.infoURL = "https://handlebarsjs.com/";
|
||||
this.inputType = "JSON";
|
||||
this.outputType = "string";
|
||||
this.args = [
|
||||
{
|
||||
name: "Template definition (.handlebars)",
|
||||
type: "text",
|
||||
value: ""
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {JSON} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
const [templateStr] = args;
|
||||
try {
|
||||
const template = Handlebars.compile(templateStr);
|
||||
return template(input);
|
||||
} catch (e) {
|
||||
throw new OperationError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default Template;
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
import Operation from "../Operation.mjs";
|
||||
import Utils from "../Utils.mjs";
|
||||
import {ALPHABET_OPTIONS} from "../lib/Base32.mjs";
|
||||
|
||||
/**
|
||||
* To Base32 operation
|
||||
@@ -27,8 +28,8 @@ class ToBase32 extends Operation {
|
||||
this.args = [
|
||||
{
|
||||
name: "Alphabet",
|
||||
type: "binaryString",
|
||||
value: "A-Z2-7="
|
||||
type: "editableOption",
|
||||
value: ALPHABET_OPTIONS
|
||||
}
|
||||
];
|
||||
}
|
||||
@@ -83,3 +84,4 @@ class ToBase32 extends Operation {
|
||||
}
|
||||
|
||||
export default ToBase32;
|
||||
|
||||
|
||||
@@ -45,11 +45,12 @@ class ToDecimal extends Operation {
|
||||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
input = new Uint8Array(input);
|
||||
const delim = Utils.charRep(args[0]),
|
||||
signed = args[1];
|
||||
if (signed) {
|
||||
input = input.map(v => v > 0x7F ? v - 0xFF - 1 : v);
|
||||
input = new Int8Array(input);
|
||||
} else {
|
||||
input = new Uint8Array(input);
|
||||
}
|
||||
return input.join(delim);
|
||||
}
|
||||
|
||||
@@ -23,7 +23,13 @@ class URLDecode extends Operation {
|
||||
this.infoURL = "https://wikipedia.org/wiki/Percent-encoding";
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
this.args = [];
|
||||
this.args = [
|
||||
{
|
||||
"name": "Treat \"+\" as space",
|
||||
"type": "boolean",
|
||||
"value": true
|
||||
},
|
||||
];
|
||||
this.checks = [
|
||||
{
|
||||
pattern: ".*(?:%[\\da-f]{2}.*){4}",
|
||||
@@ -39,7 +45,8 @@ class URLDecode extends Operation {
|
||||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
const data = input.replace(/\+/g, "%20");
|
||||
const plusIsSpace = args[0];
|
||||
const data = plusIsSpace ? input.replace(/\+/g, "%20") : input;
|
||||
try {
|
||||
return decodeURIComponent(data);
|
||||
} catch (err) {
|
||||
|
||||
@@ -24,7 +24,7 @@ class VarIntDecode extends Operation {
|
||||
this.description = "Decodes a VarInt encoded integer. VarInt is an efficient way of encoding variable length integers and is commonly used with Protobuf.";
|
||||
this.infoURL = "https://developers.google.com/protocol-buffers/docs/encoding#varints";
|
||||
this.inputType = "byteArray";
|
||||
this.outputType = "number";
|
||||
this.outputType = "string";
|
||||
this.args = [];
|
||||
}
|
||||
|
||||
@@ -35,7 +35,18 @@ class VarIntDecode extends Operation {
|
||||
*/
|
||||
run(input, args) {
|
||||
try {
|
||||
return Protobuf.varIntDecode(input);
|
||||
if (typeof BigInt === "function") {
|
||||
let result = BigInt(0);
|
||||
let offset = BigInt(0);
|
||||
for (let i = 0; i < input.length; i++) {
|
||||
result |= BigInt(input[i] & 0x7f) << offset;
|
||||
if (!(input[i] & 0x80)) break;
|
||||
offset += BigInt(7);
|
||||
}
|
||||
return result.toString();
|
||||
} else {
|
||||
return Protobuf.varIntDecode(input).toString();
|
||||
}
|
||||
} catch (err) {
|
||||
throw new OperationError(err);
|
||||
}
|
||||
|
||||
@@ -23,19 +23,31 @@ class VarIntEncode extends Operation {
|
||||
this.module = "Default";
|
||||
this.description = "Encodes a Vn integer as a VarInt. VarInt is an efficient way of encoding variable length integers and is commonly used with Protobuf.";
|
||||
this.infoURL = "https://developers.google.com/protocol-buffers/docs/encoding#varints";
|
||||
this.inputType = "number";
|
||||
this.inputType = "string";
|
||||
this.outputType = "byteArray";
|
||||
this.args = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} input
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {byteArray}
|
||||
*/
|
||||
run(input, args) {
|
||||
try {
|
||||
return Protobuf.varIntEncode(input);
|
||||
if (typeof BigInt === "function") {
|
||||
let value = BigInt(input);
|
||||
if (value < 0) throw new OperationError("Negative values cannot be represented as VarInt");
|
||||
const result = [];
|
||||
while (value >= 0x80) {
|
||||
result.push(Number(value & BigInt(0x7f)) | 0x80);
|
||||
value >>= BigInt(7);
|
||||
}
|
||||
result.push(Number(value));
|
||||
return result;
|
||||
} else {
|
||||
return Protobuf.varIntEncode(Number(input));
|
||||
}
|
||||
} catch (err) {
|
||||
throw new OperationError(err);
|
||||
}
|
||||
|
||||
59
src/core/operations/XORChecksum.mjs
Normal file
59
src/core/operations/XORChecksum.mjs
Normal file
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* @author Thomas Weißschuh [thomas@t-8ch.de]
|
||||
* @copyright Crown Copyright 2023
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation.mjs";
|
||||
import Utils from "../Utils.mjs";
|
||||
import { toHex } from "../lib/Hex.mjs";
|
||||
|
||||
/**
|
||||
* XOR Checksum operation
|
||||
*/
|
||||
class XORChecksum extends Operation {
|
||||
|
||||
/**
|
||||
* XORChecksum constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "XOR Checksum";
|
||||
this.module = "Crypto";
|
||||
this.description = "XOR Checksum splits the input into blocks of a configurable size and performs the XOR operation on these blocks.";
|
||||
this.infoURL = "https://wikipedia.org/wiki/XOR";
|
||||
this.inputType = "ArrayBuffer";
|
||||
this.outputType = "string";
|
||||
this.args = [
|
||||
{
|
||||
name: "Blocksize",
|
||||
type: "number",
|
||||
value: 4
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {ArrayBuffer} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
const blocksize = args[0];
|
||||
input = new Uint8Array(input);
|
||||
|
||||
const res = Array(blocksize);
|
||||
res.fill(0);
|
||||
|
||||
for (const chunk of Utils.chunked(input, blocksize)) {
|
||||
for (let i = 0; i < blocksize; i++) {
|
||||
res[i] ^= chunk[i];
|
||||
}
|
||||
}
|
||||
|
||||
return toHex(res, "");
|
||||
}
|
||||
}
|
||||
|
||||
export default XORChecksum;
|
||||
@@ -74,11 +74,11 @@ function transformArgs(opArgsList, newArgs) {
|
||||
return opArgs.map((arg) => {
|
||||
if (arg.type === "option") {
|
||||
// pick default option if not already chosen
|
||||
return typeof arg.value === "string" ? arg.value : arg.value[0];
|
||||
return typeof arg.value === "string" ? arg.value : arg.value[arg.defaultIndex ?? 0];
|
||||
}
|
||||
|
||||
if (arg.type === "editableOption") {
|
||||
return typeof arg.value === "string" ? arg.value : arg.value[0].value;
|
||||
return typeof arg.value === "string" ? arg.value : arg.value[arg.defaultIndex ?? 0].value;
|
||||
}
|
||||
|
||||
if (arg.type === "toggleString") {
|
||||
|
||||
@@ -125,6 +125,7 @@ class Manager {
|
||||
window.addEventListener("focus", this.window.windowFocus.bind(this.window));
|
||||
window.addEventListener("statechange", this.app.stateChange.bind(this.app));
|
||||
window.addEventListener("popstate", this.app.popState.bind(this.app));
|
||||
window.addEventListener("message", this.input.handlePostMessage.bind(this.input));
|
||||
|
||||
// Controls
|
||||
document.getElementById("bake").addEventListener("click", this.controls.bakeClick.bind(this.controls));
|
||||
|
||||
@@ -1,23 +1,26 @@
|
||||
[
|
||||
{
|
||||
"@context": "http://schema.org",
|
||||
"@type": "Organization",
|
||||
"url": "https://gchq.github.io/CyberChef/",
|
||||
"logo": "https://gchq.github.io/CyberChef/images/cyberchef-128x128.png",
|
||||
"sameAs": [
|
||||
"https://github.com/gchq/CyberChef",
|
||||
"https://www.npmjs.com/package/cyberchef"
|
||||
"@graph": [
|
||||
{
|
||||
"@type": "Organization",
|
||||
"url": "https://gchq.github.io/CyberChef/",
|
||||
"logo": "https://gchq.github.io/CyberChef/images/cyberchef-128x128.png",
|
||||
"sameAs": [
|
||||
"https://github.com/gchq/CyberChef",
|
||||
"https://www.npmjs.com/package/cyberchef"
|
||||
]
|
||||
},
|
||||
{
|
||||
"@type": "WebSite",
|
||||
"url": "https://gchq.github.io/CyberChef/",
|
||||
"name": "CyberChef",
|
||||
"potentialAction": {
|
||||
"@type": "SearchAction",
|
||||
"target": "https://gchq.github.io/CyberChef/?op={operation_search_term}",
|
||||
"query-input": "required name=operation_search_term"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"@context": "http://schema.org",
|
||||
"@type": "WebSite",
|
||||
"url": "https://gchq.github.io/CyberChef/",
|
||||
"name": "CyberChef",
|
||||
"potentialAction": {
|
||||
"@type": "SearchAction",
|
||||
"target": "https://gchq.github.io/CyberChef/?op={operation_search_term}",
|
||||
"query-input": "required name=operation_search_term"
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
@@ -1654,6 +1654,23 @@ class InputWaiter {
|
||||
this.changeTab(inputNum, this.app.options.syncTabs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for incoming postMessages
|
||||
* If the events data has a `type` property set to `dataSubmit`
|
||||
* the value property is set to the current input
|
||||
* @param {event} e
|
||||
* @param {object} e.data
|
||||
* @param {string} e.data.type - the type of request, currently the only value is "dataSubmit"
|
||||
* @param {string} e.data.value - the value of the message
|
||||
*/
|
||||
handlePostMessage(e) {
|
||||
log.debug(e);
|
||||
if ("data" in e && "id" in e.data && "value" in e.data) {
|
||||
if (e.data.id === "setInput") {
|
||||
this.setInput(e.data.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default InputWaiter;
|
||||
|
||||
@@ -8,6 +8,7 @@ import HTMLOperation from "../HTMLOperation.mjs";
|
||||
import Sortable from "sortablejs";
|
||||
import Utils from "../../core/Utils.mjs";
|
||||
import {escapeControlChars} from "../utils/editorUtils.mjs";
|
||||
import DOMPurify from "dompurify";
|
||||
|
||||
|
||||
/**
|
||||
@@ -435,7 +436,9 @@ class RecipeWaiter {
|
||||
const item = document.createElement("li");
|
||||
|
||||
item.classList.add("operation");
|
||||
item.innerHTML = name;
|
||||
const clean = DOMPurify.sanitize(name);
|
||||
item.innerHTML = clean;
|
||||
|
||||
this.buildRecipeOperation(item);
|
||||
document.getElementById("rec-list").appendChild(item);
|
||||
|
||||
|
||||
@@ -580,10 +580,25 @@ Password: 282760`;
|
||||
assert.strictEqual(result.toString().substr(0, 37), "-----BEGIN PGP PRIVATE KEY BLOCK-----");
|
||||
}),
|
||||
|
||||
it("Generate UUID", () => {
|
||||
const result = chef.generateUUID();
|
||||
assert.ok(result.toString());
|
||||
assert.strictEqual(result.toString().length, 36);
|
||||
...[1, 3, 4, 5, 6, 7].map(version => it(`Generate UUID v${version}`, () => {
|
||||
const result = chef.generateUUID("", { "version": `v${version}` }).toString();
|
||||
assert.ok(result);
|
||||
assert.strictEqual(result.length, 36);
|
||||
})),
|
||||
|
||||
...[1, 3, 4, 5, 6, 7].map(version => it(`Analyze UUID v${version}`, () => {
|
||||
const uuid = chef.generateUUID("", { "version": `v${version}` }).toString();
|
||||
const result = chef.analyseUUID(uuid).toString();
|
||||
const expected = `UUID version: ${version}`;
|
||||
assert.strictEqual(result, expected);
|
||||
})),
|
||||
|
||||
it("Generate UUID using defaults", () => {
|
||||
const uuid = chef.generateUUID();
|
||||
assert.ok(uuid);
|
||||
|
||||
const analysis = chef.analyseUUID(uuid).toString();
|
||||
assert.strictEqual(analysis, "UUID version: 4");
|
||||
}),
|
||||
|
||||
it("Gzip, Gunzip", () => {
|
||||
|
||||
@@ -11,15 +11,14 @@
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import {
|
||||
setLongTestFailure,
|
||||
logTestReport,
|
||||
} from "../lib/utils.mjs";
|
||||
import { setLongTestFailure, logTestReport } from "../lib/utils.mjs";
|
||||
|
||||
import TestRegister from "../lib/TestRegister.mjs";
|
||||
import "./tests/AESKeyWrap.mjs";
|
||||
import "./tests/AlternatingCaps.mjs";
|
||||
import "./tests/AvroToJSON.mjs";
|
||||
import "./tests/BaconCipher.mjs";
|
||||
import "./tests/Base32.mjs";
|
||||
import "./tests/Base45.mjs";
|
||||
import "./tests/Base58.mjs";
|
||||
import "./tests/Base62.mjs";
|
||||
@@ -30,6 +29,7 @@ import "./tests/BCD.mjs";
|
||||
import "./tests/BitwiseOp.mjs";
|
||||
import "./tests/BLAKE2b.mjs";
|
||||
import "./tests/BLAKE2s.mjs";
|
||||
import "./tests/BLAKE3.mjs";
|
||||
import "./tests/Bombe.mjs";
|
||||
import "./tests/BSON.mjs";
|
||||
import "./tests/ByteRepr.mjs";
|
||||
@@ -66,11 +66,13 @@ import "./tests/ELFInfo.mjs";
|
||||
import "./tests/Enigma.mjs";
|
||||
import "./tests/ExtractEmailAddresses.mjs";
|
||||
import "./tests/ExtractHashes.mjs";
|
||||
import "./tests/ExtractIPAddresses.mjs";
|
||||
import "./tests/Float.mjs";
|
||||
import "./tests/FileTree.mjs";
|
||||
import "./tests/FletcherChecksum.mjs";
|
||||
import "./tests/Fork.mjs";
|
||||
import "./tests/FromDecimal.mjs";
|
||||
import "./tests/GenerateAllChecksums.mjs";
|
||||
import "./tests/GenerateAllHashes.mjs";
|
||||
import "./tests/GenerateDeBruijnSequence.mjs";
|
||||
import "./tests/GetAllCasings.mjs";
|
||||
@@ -88,6 +90,7 @@ import "./tests/IndexOfCoincidence.mjs";
|
||||
import "./tests/JA3Fingerprint.mjs";
|
||||
import "./tests/JA4.mjs";
|
||||
import "./tests/JA3SFingerprint.mjs";
|
||||
import "./tests/Jsonata.mjs";
|
||||
import "./tests/JSONBeautify.mjs";
|
||||
import "./tests/JSONMinify.mjs";
|
||||
import "./tests/JSONtoCSV.mjs";
|
||||
@@ -125,6 +128,7 @@ import "./tests/ParseUDP.mjs";
|
||||
import "./tests/PEMtoHex.mjs";
|
||||
import "./tests/PGP.mjs";
|
||||
import "./tests/PHP.mjs";
|
||||
import "./tests/PHPSerialize.mjs";
|
||||
import "./tests/PowerSet.mjs";
|
||||
import "./tests/Protobuf.mjs";
|
||||
import "./tests/PubKeyFromCert.mjs";
|
||||
@@ -155,12 +159,14 @@ import "./tests/Subsection.mjs";
|
||||
import "./tests/SwapCase.mjs";
|
||||
import "./tests/SymmetricDifference.mjs";
|
||||
import "./tests/TakeNthBytes.mjs";
|
||||
import "./tests/Template.mjs";
|
||||
import "./tests/TextEncodingBruteForce.mjs";
|
||||
import "./tests/ToFromInsensitiveRegex.mjs";
|
||||
import "./tests/TranslateDateTimeFormat.mjs";
|
||||
import "./tests/Typex.mjs";
|
||||
import "./tests/UnescapeString.mjs";
|
||||
import "./tests/Unicode.mjs";
|
||||
import "./tests/URLEncodeDecode.mjs";
|
||||
import "./tests/RSA.mjs";
|
||||
import "./tests/CBOREncode.mjs";
|
||||
import "./tests/CBORDecode.mjs";
|
||||
@@ -179,14 +185,14 @@ const testStatus = {
|
||||
allTestsPassing: true,
|
||||
counts: {
|
||||
total: 0,
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
setLongTestFailure();
|
||||
|
||||
const logOpsTestReport = logTestReport.bind(null, testStatus);
|
||||
|
||||
(async function() {
|
||||
(async function () {
|
||||
const results = await TestRegister.runTests();
|
||||
logOpsTestReport(results);
|
||||
})();
|
||||
|
||||
19
tests/operations/tests/AlternatingCaps.mjs
Normal file
19
tests/operations/tests/AlternatingCaps.mjs
Normal file
@@ -0,0 +1,19 @@
|
||||
/* @author sw5678
|
||||
* @copyright Crown Copyright 2024
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
import TestRegister from "../../lib/TestRegister.mjs";
|
||||
|
||||
TestRegister.addTests([
|
||||
{
|
||||
"name": "AlternatingCaps: Basic Example",
|
||||
"input": "Hello, world!",
|
||||
"expectedOutput": "hElLo, WoRlD!",
|
||||
"recipeConfig": [
|
||||
{
|
||||
"op": "Alternating Caps",
|
||||
"args": []
|
||||
},
|
||||
],
|
||||
}
|
||||
]);
|
||||
55
tests/operations/tests/BLAKE3.mjs
Normal file
55
tests/operations/tests/BLAKE3.mjs
Normal file
@@ -0,0 +1,55 @@
|
||||
/**
|
||||
* BLAKE3 tests.
|
||||
* @author xumptex [xumptex@outlook.fr]
|
||||
* @copyright Crown Copyright 2025
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
import TestRegister from "../../lib/TestRegister.mjs";
|
||||
|
||||
TestRegister.addTests([
|
||||
{
|
||||
name: "BLAKE3: 8 - Hello world",
|
||||
input: "Hello world",
|
||||
expectedOutput: "e7e6fb7d2869d109",
|
||||
recipeConfig: [
|
||||
{ "op": "BLAKE3",
|
||||
"args": [8, ""] }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "BLAKE3: 16 - Hello world 2",
|
||||
input: "Hello world 2",
|
||||
expectedOutput: "2a3df5fe5f0d3fcdd995fc203c7f7c52",
|
||||
recipeConfig: [
|
||||
{ "op": "BLAKE3",
|
||||
"args": [16, ""] }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "BLAKE3: 32 - Hello world",
|
||||
input: "Hello world",
|
||||
expectedOutput: "e7e6fb7d2869d109b62cdb1227208d4016cdaa0af6603d95223c6a698137d945",
|
||||
recipeConfig: [
|
||||
{ "op": "BLAKE3",
|
||||
"args": [32, ""] }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "BLAKE3: Key Test",
|
||||
input: "Hello world",
|
||||
expectedOutput: "59dd23ac9d025690",
|
||||
recipeConfig: [
|
||||
{ "op": "BLAKE3",
|
||||
"args": [8, "ThiskeyisexactlythirtytwoBytesLo"] }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "BLAKE3: Key Test 2",
|
||||
input: "Hello world",
|
||||
expectedOutput: "c8302c9634c1da42",
|
||||
recipeConfig: [
|
||||
{ "op": "BLAKE3",
|
||||
"args": [8, "ThiskeyisexactlythirtytwoByteslo"] }
|
||||
]
|
||||
}
|
||||
]);
|
||||
176
tests/operations/tests/Base32.mjs
Normal file
176
tests/operations/tests/Base32.mjs
Normal file
@@ -0,0 +1,176 @@
|
||||
/**
|
||||
* Base32 Tests
|
||||
*
|
||||
* @author Peter C-S [petercs@purelymail.com]
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import TestRegister from "../../lib/TestRegister.mjs";
|
||||
import {ALPHABET_OPTIONS} from "../../../src/core/lib/Base32.mjs";
|
||||
|
||||
// Example Standard Base32 Tests
|
||||
const STANDARD_INP = "HELLO BASE32";
|
||||
const STANDARD_OUT = "JBCUYTCPEBBECU2FGMZA====";
|
||||
|
||||
// Example Hex Extended Base32 Tests
|
||||
const EXTENDED_INP = "HELLO BASE32 EXTENDED";
|
||||
const EXTENDED_OUT = "912KOJ2F41142KQ56CP20HAOAH2KSH258G======";
|
||||
|
||||
// All Bytes
|
||||
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("");
|
||||
|
||||
const ALL_BYTES_EXTENDED_OUT = "000G40O40K30E209185GO38E1S8124GJ2GAHC5OO34D1M70T3OFI08924CI2A9H750KIKAPC5KN2UC1H68PJ8D9M6SS3IEHR7GUJSFQ085146H258P3KGIAA9D64QJIFA18L4KQKALB5EM2PB9DLONAUBTG62OJ3CHIMCPR8D5L6MR3DDPNN0SBIEDQ7ATJNF1SNKURSFLV7V041GA1O91C6GU48J2KBHI6OT3SGI699754LIQBPH6CQJEE9R7KVK2GQ58T4KMJAFA59LALQPBDELUOB3CLJMIQRDDTON6TBNF5TNQVS1GE2OF2CBHM7P34SLIUCPN7CVK6HQB9T9LEMQVCDJMMRRJETTNV0S7HE7P75SRJUHQFATFMERRNFU3OV5SVKUNRFFU7PVBTVPVFUVS======";
|
||||
const ALL_BYTES_STANDARD_OUT = "AAAQEAYEAUDAOCAJBIFQYDIOB4IBCEQTCQKRMFYYDENBWHA5DYPSAIJCEMSCKJRHFAUSUKZMFUXC6MBRGIZTINJWG44DSOR3HQ6T4P2AIFBEGRCFIZDUQSKKJNGE2TSPKBIVEU2UKVLFOWCZLJNVYXK6L5QGCYTDMRSWMZ3INFVGW3DNNZXXA4LSON2HK5TXPB4XU634PV7H7AEBQKBYJBMGQ6EITCULRSGY5D4QSGJJHFEVS2LZRGM2TOOJ3HU7UCQ2FI5EUWTKPKFJVKV2ZLNOV6YLDMVTWS23NN5YXG5LXPF5X274BQOCYPCMLRWHZDE4VS6MZXHM7UGR2LJ5JVOW27MNTWW33TO55X7A4HROHZHF43T6R2PK5PWO33XP6DY7F47U6X3PP6HZ7L57Z7P674======";
|
||||
|
||||
TestRegister.addTests([
|
||||
{
|
||||
name: "To Base32 Standard: nothing",
|
||||
input: "",
|
||||
expectedOutput: "",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "To Base32",
|
||||
args: [ALPHABET_OPTIONS[0].value],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "To Base32 Hex Extended: nothing",
|
||||
input: "",
|
||||
expectedOutput: "",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "To Base32",
|
||||
args: [ALPHABET_OPTIONS[1].value],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "From Base32 Standard: nothing",
|
||||
input: "",
|
||||
expectedOutput: "",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "From Base32",
|
||||
args: [ALPHABET_OPTIONS[0].value, false],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "From Base32 Hex Extended: nothing",
|
||||
input: "",
|
||||
expectedOutput: "",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "From Base32",
|
||||
args: [ALPHABET_OPTIONS[1].value, false],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "To Base32 Standard: " + STANDARD_INP,
|
||||
input: STANDARD_INP,
|
||||
expectedOutput: STANDARD_OUT,
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "To Base32",
|
||||
args: [ALPHABET_OPTIONS[0].value],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "To Base32 Hex Extended: " + EXTENDED_INP,
|
||||
input: EXTENDED_INP,
|
||||
expectedOutput: EXTENDED_OUT,
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "To Base32",
|
||||
args: [ALPHABET_OPTIONS[1].value],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "From Base32 Standard: " + STANDARD_OUT,
|
||||
input: STANDARD_OUT,
|
||||
expectedOutput: STANDARD_INP,
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "From Base32",
|
||||
args: [ALPHABET_OPTIONS[0].value, false],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "From Base32 Hex Extended: " + EXTENDED_OUT,
|
||||
input: EXTENDED_OUT,
|
||||
expectedOutput: EXTENDED_INP,
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "From Base32",
|
||||
args: [ALPHABET_OPTIONS[1].value, false],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "To Base32 Hex Standard: All Bytes",
|
||||
input: ALL_BYTES,
|
||||
expectedOutput: ALL_BYTES_STANDARD_OUT,
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "To Base32",
|
||||
args: [ALPHABET_OPTIONS[0].value],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "To Base32 Hex Extended: All Bytes",
|
||||
input: ALL_BYTES,
|
||||
expectedOutput: ALL_BYTES_EXTENDED_OUT,
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "To Base32",
|
||||
args: [ALPHABET_OPTIONS[1].value],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "From Base32 Hex Standard: All Bytes",
|
||||
input: ALL_BYTES_STANDARD_OUT,
|
||||
expectedOutput: ALL_BYTES,
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "From Base32",
|
||||
args: [ALPHABET_OPTIONS[0].value, false],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "From Base32 Hex Extended: All Bytes",
|
||||
input: ALL_BYTES_EXTENDED_OUT,
|
||||
expectedOutput: ALL_BYTES,
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "From Base32",
|
||||
args: [ALPHABET_OPTIONS[1].value, false],
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
|
||||
@@ -528,4 +528,15 @@ TestRegister.addTests([
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Rail Fence Cipher Encode: Normal with Offset with Spaces",
|
||||
input: "No one expects the spanish Inquisition.",
|
||||
expectedOutput: " e n ut.ooeepcstesaihIqiiinNnxthpsnso",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Rail Fence Cipher Encode",
|
||||
"args": [3, 2]
|
||||
}
|
||||
],
|
||||
},
|
||||
]);
|
||||
|
||||
@@ -6,7 +6,10 @@
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
import TestRegister from "../../lib/TestRegister.mjs";
|
||||
import { ASCII_TEXT } from "../../samples/Ciphers.mjs";
|
||||
import {ALL_BYTES, ASCII_TEXT, UTF8_TEXT} from "../../samples/Ciphers.mjs";
|
||||
|
||||
const SOME_HEX_BYTES = "cdb23f958e018418621d9e489b7bba0f0c481f604eba2eb1ea35e38f99490cc0";
|
||||
const SOME_BASE64_BYTES = "zbI/lY4BhBhiHZ5Im3u6DwxIH2BOui6x6jXjj5lJDMA=";
|
||||
|
||||
const P256 = {
|
||||
// openssl ecparam -name prime256v1 -genkey -noout -out p256.priv.key
|
||||
@@ -104,7 +107,7 @@ TestRegister.addTests([
|
||||
},
|
||||
{
|
||||
"op": "ECDSA Verify",
|
||||
"args": ["ASN.1 HEX", "MD5", P256.publicKey, ASCII_TEXT]
|
||||
"args": ["ASN.1 HEX", "MD5", P256.publicKey, ASCII_TEXT, "Raw"]
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -119,7 +122,7 @@ TestRegister.addTests([
|
||||
},
|
||||
{
|
||||
"op": "ECDSA Verify",
|
||||
"args": ["ASN.1 HEX", "SHA-1", P256.publicKey, ASCII_TEXT]
|
||||
"args": ["ASN.1 HEX", "SHA-1", P256.publicKey, ASCII_TEXT, "Raw"]
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -134,7 +137,7 @@ TestRegister.addTests([
|
||||
},
|
||||
{
|
||||
"op": "ECDSA Verify",
|
||||
"args": ["ASN.1 HEX", "SHA-256", P256.publicKey, ASCII_TEXT]
|
||||
"args": ["ASN.1 HEX", "SHA-256", P256.publicKey, ASCII_TEXT, "Raw"]
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -149,7 +152,7 @@ TestRegister.addTests([
|
||||
},
|
||||
{
|
||||
"op": "ECDSA Verify",
|
||||
"args": ["ASN.1 HEX", "SHA-384", P256.publicKey, ASCII_TEXT]
|
||||
"args": ["ASN.1 HEX", "SHA-384", P256.publicKey, ASCII_TEXT, "Raw"]
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -164,7 +167,7 @@ TestRegister.addTests([
|
||||
},
|
||||
{
|
||||
"op": "ECDSA Verify",
|
||||
"args": ["ASN.1 HEX", "SHA-512", P256.publicKey, ASCII_TEXT]
|
||||
"args": ["ASN.1 HEX", "SHA-512", P256.publicKey, ASCII_TEXT, "Raw"]
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -179,7 +182,7 @@ TestRegister.addTests([
|
||||
},
|
||||
{
|
||||
"op": "ECDSA Verify",
|
||||
"args": ["ASN.1 HEX", "SHA-256", P256.publicKey, ASCII_TEXT]
|
||||
"args": ["ASN.1 HEX", "SHA-256", P256.publicKey, ASCII_TEXT, "Raw"]
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -194,7 +197,7 @@ TestRegister.addTests([
|
||||
},
|
||||
{
|
||||
"op": "ECDSA Verify",
|
||||
"args": ["ASN.1 HEX", "SHA-384", P384.publicKey, ASCII_TEXT]
|
||||
"args": ["ASN.1 HEX", "SHA-384", P384.publicKey, ASCII_TEXT, "Raw"]
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -209,7 +212,7 @@ TestRegister.addTests([
|
||||
},
|
||||
{
|
||||
"op": "ECDSA Verify",
|
||||
"args": ["ASN.1 HEX", "SHA-512", P521.publicKey, ASCII_TEXT]
|
||||
"args": ["ASN.1 HEX", "SHA-512", P521.publicKey, ASCII_TEXT, "Raw"]
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -246,7 +249,7 @@ TestRegister.addTests([
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "ECDSA Verify",
|
||||
"args": ["Auto", "SHA-256", P256.publicKey, ASCII_TEXT]
|
||||
"args": ["Auto", "SHA-256", P256.publicKey, ASCII_TEXT, "Raw"]
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -257,7 +260,7 @@ TestRegister.addTests([
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "ECDSA Verify",
|
||||
"args": ["Auto", "SHA-256", P256.publicKey, ASCII_TEXT]
|
||||
"args": ["Auto", "SHA-256", P256.publicKey, ASCII_TEXT, "Raw"]
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -268,7 +271,7 @@ TestRegister.addTests([
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "ECDSA Verify",
|
||||
"args": ["Auto", "SHA-256", P256.publicKey, ASCII_TEXT]
|
||||
"args": ["Auto", "SHA-256", P256.publicKey, ASCII_TEXT, "Raw"]
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -279,7 +282,7 @@ TestRegister.addTests([
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "ECDSA Verify",
|
||||
"args": ["Auto", "SHA-256", P256.publicKey, ASCII_TEXT]
|
||||
"args": ["Auto", "SHA-256", P256.publicKey, ASCII_TEXT, "Raw"]
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -290,7 +293,7 @@ TestRegister.addTests([
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "ECDSA Verify",
|
||||
"args": ["Auto", "SHA-256", P256.publicKey, ASCII_TEXT]
|
||||
"args": ["Auto", "SHA-256", P256.publicKey, ASCII_TEXT, "Raw"]
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -301,7 +304,7 @@ TestRegister.addTests([
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "ECDSA Verify",
|
||||
"args": ["Auto", "SHA-256", P256.publicKey, ASCII_TEXT]
|
||||
"args": ["Auto", "SHA-256", P256.publicKey, ASCII_TEXT, "Raw"]
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -312,7 +315,7 @@ TestRegister.addTests([
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "ECDSA Verify",
|
||||
"args": ["ASN.1 HEX", "SHA-256", P256.privateKeyPkcs1, ASCII_TEXT]
|
||||
"args": ["ASN.1 HEX", "SHA-256", P256.privateKeyPkcs1, ASCII_TEXT, "Raw"]
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -323,7 +326,7 @@ TestRegister.addTests([
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "ECDSA Verify",
|
||||
"args": ["ASN.1 HEX", "SHA-256", PEM_PUB_RSA512, ASCII_TEXT]
|
||||
"args": ["ASN.1 HEX", "SHA-256", PEM_PUB_RSA512, ASCII_TEXT, "Raw"]
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -460,5 +463,73 @@ TestRegister.addTests([
|
||||
"args": ["Auto", "Raw JSON"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "ECDSA Sign/Verify: P-256 with SHA256 UTF8",
|
||||
input: UTF8_TEXT,
|
||||
expectedOutput: "Verified OK",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "ECDSA Sign",
|
||||
"args": [P256.privateKeyPkcs1, "SHA-256", "ASN.1 HEX"]
|
||||
},
|
||||
{
|
||||
"op": "ECDSA Verify",
|
||||
"args": ["ASN.1 HEX", "SHA-256", P256.publicKey, UTF8_TEXT, "Raw"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "ECDSA Sign/Verify: P-256 with SHA256 bytes raw",
|
||||
input: ALL_BYTES,
|
||||
expectedOutput: "Verified OK",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "ECDSA Sign",
|
||||
"args": [P256.privateKeyPkcs1, "SHA-256", "ASN.1 HEX"]
|
||||
},
|
||||
{
|
||||
"op": "ECDSA Verify",
|
||||
"args": ["ASN.1 HEX", "SHA-256", P256.publicKey, ALL_BYTES, "Raw"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "ECDSA Sign/Verify: P-256 with SHA256 bytes hex",
|
||||
input: SOME_HEX_BYTES,
|
||||
expectedOutput: "Verified OK",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "From Hex",
|
||||
"args": ["Auto"]
|
||||
},
|
||||
{
|
||||
"op": "ECDSA Sign",
|
||||
"args": [P256.privateKeyPkcs1, "SHA-256", "ASN.1 HEX"]
|
||||
},
|
||||
{
|
||||
"op": "ECDSA Verify",
|
||||
"args": ["ASN.1 HEX", "SHA-256", P256.publicKey, SOME_HEX_BYTES, "Hex"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "ECDSA Sign/Verify: P-256 with SHA256 bytes Base64",
|
||||
input: SOME_BASE64_BYTES,
|
||||
expectedOutput: "Verified OK",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "From Base64",
|
||||
"args": ["A-Za-z0-9+/=", true]
|
||||
},
|
||||
{
|
||||
"op": "ECDSA Sign",
|
||||
"args": [P256.privateKeyPkcs1, "SHA-256", "ASN.1 HEX"]
|
||||
},
|
||||
{
|
||||
"op": "ECDSA Verify",
|
||||
"args": ["ASN.1 HEX", "SHA-256", P256.publicKey, SOME_BASE64_BYTES, "Base64"]
|
||||
}
|
||||
]
|
||||
}
|
||||
]);
|
||||
|
||||
133
tests/operations/tests/ExtractIPAddresses.mjs
Normal file
133
tests/operations/tests/ExtractIPAddresses.mjs
Normal file
@@ -0,0 +1,133 @@
|
||||
/**
|
||||
* ExtractIPAddresses tests.
|
||||
*
|
||||
* @author gchqdev365 [gchqdev365@outlook.com]
|
||||
* @copyright Crown Copyright 2025
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
import TestRegister from "../../lib/TestRegister.mjs";
|
||||
|
||||
TestRegister.addTests([
|
||||
{
|
||||
name: "ExtractIPAddress All Zeros",
|
||||
input: "0.0.0.0",
|
||||
expectedOutput: "0.0.0.0",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Extract IP addresses",
|
||||
"args": [true, true, false, false, false, false]
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "ExtractIPAddress All 10s",
|
||||
input: "10.10.10.10",
|
||||
expectedOutput: "10.10.10.10",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Extract IP addresses",
|
||||
"args": [true, true, false, false, false, false]
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "ExtractIPAddress All 10s",
|
||||
input: "100.100.100.100",
|
||||
expectedOutput: "100.100.100.100",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Extract IP addresses",
|
||||
"args": [true, true, false, false, false, false]
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "ExtractIPAddress 255s",
|
||||
input: "255.255.255.255",
|
||||
expectedOutput: "255.255.255.255",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Extract IP addresses",
|
||||
"args": [true, true, false, false, false, false]
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "ExtractIPAddress double digits",
|
||||
input: "10.10.10.10 25.25.25.25 99.99.99.99",
|
||||
expectedOutput: "10.10.10.10\n25.25.25.25\n99.99.99.99",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Extract IP addresses",
|
||||
"args": [true, true, false, false, false, false]
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "ExtractIPAddress 256 in middle",
|
||||
input: "255.256.255.255 255.255.256.255",
|
||||
expectedOutput: "",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Extract IP addresses",
|
||||
"args": [true, true, false, false, false, false]
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "ExtractIPAddress 256 at each end",
|
||||
input: "256.255.255.255 255.255.255.256",
|
||||
expectedOutput: "",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Extract IP addresses",
|
||||
"args": [true, true, false, false, false, false]
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "ExtractIPAddress silly example",
|
||||
input: "710.65.0.456",
|
||||
expectedOutput: "",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Extract IP addresses",
|
||||
"args": [true, true, false, false, false, false]
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "ExtractIPAddress longer dotted decimal",
|
||||
input: "1.2.3.4.5.6.7.8",
|
||||
expectedOutput: "1.2.3.4\n5.6.7.8",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Extract IP addresses",
|
||||
"args": [true, true, false, false, false, false]
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "ExtractIPAddress octal valid",
|
||||
input: "01.01.01.01 0123.0123.0123.0123 0377.0377.0377.0377",
|
||||
expectedOutput: "01.01.01.01\n0123.0123.0123.0123\n0377.0377.0377.0377",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Extract IP addresses",
|
||||
"args": [true, true, false, false, false, false]
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "ExtractIPAddress octal invalid",
|
||||
input: "0378.01.01.01 03.0377.2.3",
|
||||
expectedOutput: "",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Extract IP addresses",
|
||||
"args": [true, true, false, false, false, false]
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
|
||||
805
tests/operations/tests/GenerateAllChecksums.mjs
Normal file
805
tests/operations/tests/GenerateAllChecksums.mjs
Normal file
@@ -0,0 +1,805 @@
|
||||
/**
|
||||
* GenerateAllChecksums tests.
|
||||
*
|
||||
* @author r4mos [2k95ljkhg@mozmail.com]
|
||||
* @copyright Crown Copyright 2025
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
import TestRegister from "../../lib/TestRegister.mjs";
|
||||
|
||||
const CHECK_STRING = "123456789";
|
||||
|
||||
TestRegister.addTests([
|
||||
{
|
||||
name: "Full generate all checksums with name",
|
||||
input: CHECK_STRING,
|
||||
expectedOutput: `CRC-3/GSM: 4
|
||||
CRC-3/ROHC: 6
|
||||
CRC-4/G-704: 7
|
||||
CRC-4/INTERLAKEN: b
|
||||
CRC-4/ITU: 7
|
||||
CRC-5/EPC: 00
|
||||
CRC-5/EPC-C1G2: 00
|
||||
CRC-5/G-704: 07
|
||||
CRC-5/ITU: 07
|
||||
CRC-5/USB: 19
|
||||
CRC-6/CDMA2000-A: 0d
|
||||
CRC-6/CDMA2000-B: 3b
|
||||
CRC-6/DARC: 26
|
||||
CRC-6/G-704: 06
|
||||
CRC-6/GSM: 13
|
||||
CRC-6/ITU: 06
|
||||
CRC-7/MMC: 75
|
||||
CRC-7/ROHC: 53
|
||||
CRC-7/UMTS: 61
|
||||
CRC-8: f4
|
||||
CRC-8/8H2F: df
|
||||
CRC-8/AES: 97
|
||||
CRC-8/AUTOSAR: df
|
||||
CRC-8/BLUETOOTH: 26
|
||||
CRC-8/CDMA2000: da
|
||||
CRC-8/DARC: 15
|
||||
CRC-8/DVB-S2: bc
|
||||
CRC-8/EBU: 97
|
||||
CRC-8/GSM-A: 37
|
||||
CRC-8/GSM-B: 94
|
||||
CRC-8/HITAG: b4
|
||||
CRC-8/I-432-1: a1
|
||||
CRC-8/I-CODE: 7e
|
||||
CRC-8/ITU: a1
|
||||
CRC-8/LTE: ea
|
||||
CRC-8/MAXIM: a1
|
||||
CRC-8/MAXIM-DOW: a1
|
||||
CRC-8/MIFARE-MAD: 99
|
||||
CRC-8/NRSC-5: f7
|
||||
CRC-8/OPENSAFETY: 3e
|
||||
CRC-8/ROHC: d0
|
||||
CRC-8/SAE-J1850: 4b
|
||||
CRC-8/SAE-J1850-ZERO: 37
|
||||
CRC-8/SMBUS: f4
|
||||
CRC-8/TECH-3250: 97
|
||||
CRC-8/WCDMA: 25
|
||||
Fletcher-8: 0c
|
||||
CRC-10/ATM: 199
|
||||
CRC-10/CDMA2000: 233
|
||||
CRC-10/GSM: 12a
|
||||
CRC-10/I-610: 199
|
||||
CRC-11/FLEXRAY: 5a3
|
||||
CRC-11/UMTS: 061
|
||||
CRC-12/3GPP: daf
|
||||
CRC-12/CDMA2000: d4d
|
||||
CRC-12/DECT: f5b
|
||||
CRC-12/GSM: b34
|
||||
CRC-12/UMTS: daf
|
||||
CRC-13/BBC: 04fa
|
||||
CRC-14/DARC: 082d
|
||||
CRC-14/GSM: 30ae
|
||||
CRC-15/CAN: 059e
|
||||
CRC-15/MPT1327: 2566
|
||||
CRC-16: bb3d
|
||||
CRC-16/A: bf05
|
||||
CRC-16/ACORN: 31c3
|
||||
CRC-16/ARC: bb3d
|
||||
CRC-16/AUG-CCITT: e5cc
|
||||
CRC-16/AUTOSAR: 29b1
|
||||
CRC-16/B: 906e
|
||||
CRC-16/BLUETOOTH: 2189
|
||||
CRC-16/BUYPASS: fee8
|
||||
CRC-16/CCITT: 2189
|
||||
CRC-16/CCITT-FALSE: 29b1
|
||||
CRC-16/CCITT-TRUE: 2189
|
||||
CRC-16/CCITT-ZERO: 31c3
|
||||
CRC-16/CDMA2000: 4c06
|
||||
CRC-16/CMS: aee7
|
||||
CRC-16/DARC: d64e
|
||||
CRC-16/DDS-110: 9ecf
|
||||
CRC-16/DECT-R: 007e
|
||||
CRC-16/DECT-X: 007f
|
||||
CRC-16/DNP: ea82
|
||||
CRC-16/EN-13757: c2b7
|
||||
CRC-16/EPC: d64e
|
||||
CRC-16/EPC-C1G2: d64e
|
||||
CRC-16/GENIBUS: d64e
|
||||
CRC-16/GSM: ce3c
|
||||
CRC-16/I-CODE: d64e
|
||||
CRC-16/IBM: bb3d
|
||||
CRC-16/IBM-3740: 29b1
|
||||
CRC-16/IBM-SDLC: 906e
|
||||
CRC-16/IEC-61158-2: a819
|
||||
CRC-16/ISO-HDLC: 906e
|
||||
CRC-16/ISO-IEC-14443-3-A: bf05
|
||||
CRC-16/ISO-IEC-14443-3-B: 906e
|
||||
CRC-16/KERMIT: 2189
|
||||
CRC-16/LHA: bb3d
|
||||
CRC-16/LJ1200: bdf4
|
||||
CRC-16/LTE: 31c3
|
||||
CRC-16/M17: 772b
|
||||
CRC-16/MAXIM: 44c2
|
||||
CRC-16/MAXIM-DOW: 44c2
|
||||
CRC-16/MCRF4XX: 6f91
|
||||
CRC-16/MODBUS: 4b37
|
||||
CRC-16/NRSC-5: a066
|
||||
CRC-16/OPENSAFETY-A: 5d38
|
||||
CRC-16/OPENSAFETY-B: 20fe
|
||||
CRC-16/PROFIBUS: a819
|
||||
CRC-16/RIELLO: 63d0
|
||||
CRC-16/SPI-FUJITSU: e5cc
|
||||
CRC-16/T10-DIF: d0db
|
||||
CRC-16/TELEDISK: 0fb3
|
||||
CRC-16/TMS37157: 26b1
|
||||
CRC-16/UMTS: fee8
|
||||
CRC-16/USB: b4c8
|
||||
CRC-16/V-41-LSB: 2189
|
||||
CRC-16/V-41-MSB: 31c3
|
||||
CRC-16/VERIFONE: fee8
|
||||
CRC-16/X-25: 906e
|
||||
CRC-16/XMODEM: 31c3
|
||||
CRC-16/ZMODEM: 31c3
|
||||
Fletcher-16: 1ede
|
||||
CRC-17/CAN-FD: 04f03
|
||||
CRC-21/CAN-FD: 0ed841
|
||||
CRC-24/BLE: c25a56
|
||||
CRC-24/FLEXRAY-A: 7979bd
|
||||
CRC-24/FLEXRAY-B: 1f23b8
|
||||
CRC-24/INTERLAKEN: b4f3e6
|
||||
CRC-24/LTE-A: cde703
|
||||
CRC-24/LTE-B: 23ef52
|
||||
CRC-24/OPENPGP: 21cf02
|
||||
CRC-24/OS-9: 200fa5
|
||||
CRC-30/CDMA: 04c34abf
|
||||
CRC-31/PHILIPS: 0ce9e46c
|
||||
Adler-32: 091e01de
|
||||
CRC-32: cbf43926
|
||||
CRC-32/AAL5: fc891918
|
||||
CRC-32/ADCCP: cbf43926
|
||||
CRC-32/AIXM: 3010bf7f
|
||||
CRC-32/AUTOSAR: 1697d06a
|
||||
CRC-32/BASE91-C: e3069283
|
||||
CRC-32/BASE91-D: 87315576
|
||||
CRC-32/BZIP2: fc891918
|
||||
CRC-32/C: e3069283
|
||||
CRC-32/CASTAGNOLI: e3069283
|
||||
CRC-32/CD-ROM-EDC: 6ec2edc4
|
||||
CRC-32/CKSUM: 765e7680
|
||||
CRC-32/D: 87315576
|
||||
CRC-32/DECT-B: fc891918
|
||||
CRC-32/INTERLAKEN: e3069283
|
||||
CRC-32/ISCSI: e3069283
|
||||
CRC-32/ISO-HDLC: cbf43926
|
||||
CRC-32/JAMCRC: 340bc6d9
|
||||
CRC-32/MEF: d2c22f51
|
||||
CRC-32/MPEG-2: 0376e6e7
|
||||
CRC-32/NVME: e3069283
|
||||
CRC-32/PKZIP: cbf43926
|
||||
CRC-32/POSIX: 765e7680
|
||||
CRC-32/Q: 3010bf7f
|
||||
CRC-32/SATA: cf72afe8
|
||||
CRC-32/V-42: cbf43926
|
||||
CRC-32/XFER: bd0be338
|
||||
CRC-32/XZ: cbf43926
|
||||
Fletcher-32: df09d509
|
||||
CRC-40/GSM: d4164fc646
|
||||
CRC-64/ECMA-182: 6c40df5f0b497347
|
||||
CRC-64/GO-ECMA: 995dc9bbdf1939fa
|
||||
CRC-64/GO-ISO: b90956c775a41001
|
||||
CRC-64/MS: 75d4b74f024eceea
|
||||
CRC-64/NVME: ae8b14860a799888
|
||||
CRC-64/REDIS: e9c6d914c4b8d9ca
|
||||
CRC-64/WE: 62ec59e3f1a4f00a
|
||||
CRC-64/XZ: 995dc9bbdf1939fa
|
||||
Fletcher-64: 0d0803376c6a689f
|
||||
CRC-82/DARC: 09ea83f625023801fd612
|
||||
`,
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Generate all checksums",
|
||||
"args": ["All", true]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Full generate all checksums without name",
|
||||
input: CHECK_STRING,
|
||||
expectedOutput: `4
|
||||
6
|
||||
7
|
||||
b
|
||||
7
|
||||
00
|
||||
00
|
||||
07
|
||||
07
|
||||
19
|
||||
0d
|
||||
3b
|
||||
26
|
||||
06
|
||||
13
|
||||
06
|
||||
75
|
||||
53
|
||||
61
|
||||
f4
|
||||
df
|
||||
97
|
||||
df
|
||||
26
|
||||
da
|
||||
15
|
||||
bc
|
||||
97
|
||||
37
|
||||
94
|
||||
b4
|
||||
a1
|
||||
7e
|
||||
a1
|
||||
ea
|
||||
a1
|
||||
a1
|
||||
99
|
||||
f7
|
||||
3e
|
||||
d0
|
||||
4b
|
||||
37
|
||||
f4
|
||||
97
|
||||
25
|
||||
0c
|
||||
199
|
||||
233
|
||||
12a
|
||||
199
|
||||
5a3
|
||||
061
|
||||
daf
|
||||
d4d
|
||||
f5b
|
||||
b34
|
||||
daf
|
||||
04fa
|
||||
082d
|
||||
30ae
|
||||
059e
|
||||
2566
|
||||
bb3d
|
||||
bf05
|
||||
31c3
|
||||
bb3d
|
||||
e5cc
|
||||
29b1
|
||||
906e
|
||||
2189
|
||||
fee8
|
||||
2189
|
||||
29b1
|
||||
2189
|
||||
31c3
|
||||
4c06
|
||||
aee7
|
||||
d64e
|
||||
9ecf
|
||||
007e
|
||||
007f
|
||||
ea82
|
||||
c2b7
|
||||
d64e
|
||||
d64e
|
||||
d64e
|
||||
ce3c
|
||||
d64e
|
||||
bb3d
|
||||
29b1
|
||||
906e
|
||||
a819
|
||||
906e
|
||||
bf05
|
||||
906e
|
||||
2189
|
||||
bb3d
|
||||
bdf4
|
||||
31c3
|
||||
772b
|
||||
44c2
|
||||
44c2
|
||||
6f91
|
||||
4b37
|
||||
a066
|
||||
5d38
|
||||
20fe
|
||||
a819
|
||||
63d0
|
||||
e5cc
|
||||
d0db
|
||||
0fb3
|
||||
26b1
|
||||
fee8
|
||||
b4c8
|
||||
2189
|
||||
31c3
|
||||
fee8
|
||||
906e
|
||||
31c3
|
||||
31c3
|
||||
1ede
|
||||
04f03
|
||||
0ed841
|
||||
c25a56
|
||||
7979bd
|
||||
1f23b8
|
||||
b4f3e6
|
||||
cde703
|
||||
23ef52
|
||||
21cf02
|
||||
200fa5
|
||||
04c34abf
|
||||
0ce9e46c
|
||||
091e01de
|
||||
cbf43926
|
||||
fc891918
|
||||
cbf43926
|
||||
3010bf7f
|
||||
1697d06a
|
||||
e3069283
|
||||
87315576
|
||||
fc891918
|
||||
e3069283
|
||||
e3069283
|
||||
6ec2edc4
|
||||
765e7680
|
||||
87315576
|
||||
fc891918
|
||||
e3069283
|
||||
e3069283
|
||||
cbf43926
|
||||
340bc6d9
|
||||
d2c22f51
|
||||
0376e6e7
|
||||
e3069283
|
||||
cbf43926
|
||||
765e7680
|
||||
3010bf7f
|
||||
cf72afe8
|
||||
cbf43926
|
||||
bd0be338
|
||||
cbf43926
|
||||
df09d509
|
||||
d4164fc646
|
||||
6c40df5f0b497347
|
||||
995dc9bbdf1939fa
|
||||
b90956c775a41001
|
||||
75d4b74f024eceea
|
||||
ae8b14860a799888
|
||||
e9c6d914c4b8d9ca
|
||||
62ec59e3f1a4f00a
|
||||
995dc9bbdf1939fa
|
||||
0d0803376c6a689f
|
||||
09ea83f625023801fd612
|
||||
`,
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Generate all checksums",
|
||||
"args": ["All", false]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Full generate 3 bits checksums with name",
|
||||
input: CHECK_STRING,
|
||||
expectedOutput: `CRC-3/GSM: 4
|
||||
CRC-3/ROHC: 6
|
||||
`,
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Generate all checksums",
|
||||
"args": ["3", true]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Full generate 4 bits checksums with name",
|
||||
input: CHECK_STRING,
|
||||
expectedOutput: `CRC-4/G-704: 7
|
||||
CRC-4/INTERLAKEN: b
|
||||
CRC-4/ITU: 7
|
||||
`,
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Generate all checksums",
|
||||
"args": ["4", true]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Full generate 5 bits checksums with name",
|
||||
input: CHECK_STRING,
|
||||
expectedOutput: `CRC-5/EPC: 00
|
||||
CRC-5/EPC-C1G2: 00
|
||||
CRC-5/G-704: 07
|
||||
CRC-5/ITU: 07
|
||||
CRC-5/USB: 19
|
||||
`,
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Generate all checksums",
|
||||
"args": ["5", true]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Full generate 6 bits checksums with name",
|
||||
input: CHECK_STRING,
|
||||
expectedOutput: `CRC-6/CDMA2000-A: 0d
|
||||
CRC-6/CDMA2000-B: 3b
|
||||
CRC-6/DARC: 26
|
||||
CRC-6/G-704: 06
|
||||
CRC-6/GSM: 13
|
||||
CRC-6/ITU: 06
|
||||
`,
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Generate all checksums",
|
||||
"args": ["6", true]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Full generate 7 bits checksums with name",
|
||||
input: CHECK_STRING,
|
||||
expectedOutput: `CRC-7/MMC: 75
|
||||
CRC-7/ROHC: 53
|
||||
CRC-7/UMTS: 61
|
||||
`,
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Generate all checksums",
|
||||
"args": ["7", true]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Full generate 8 bits checksums with name",
|
||||
input: CHECK_STRING,
|
||||
expectedOutput: `CRC-8: f4
|
||||
CRC-8/8H2F: df
|
||||
CRC-8/AES: 97
|
||||
CRC-8/AUTOSAR: df
|
||||
CRC-8/BLUETOOTH: 26
|
||||
CRC-8/CDMA2000: da
|
||||
CRC-8/DARC: 15
|
||||
CRC-8/DVB-S2: bc
|
||||
CRC-8/EBU: 97
|
||||
CRC-8/GSM-A: 37
|
||||
CRC-8/GSM-B: 94
|
||||
CRC-8/HITAG: b4
|
||||
CRC-8/I-432-1: a1
|
||||
CRC-8/I-CODE: 7e
|
||||
CRC-8/ITU: a1
|
||||
CRC-8/LTE: ea
|
||||
CRC-8/MAXIM: a1
|
||||
CRC-8/MAXIM-DOW: a1
|
||||
CRC-8/MIFARE-MAD: 99
|
||||
CRC-8/NRSC-5: f7
|
||||
CRC-8/OPENSAFETY: 3e
|
||||
CRC-8/ROHC: d0
|
||||
CRC-8/SAE-J1850: 4b
|
||||
CRC-8/SAE-J1850-ZERO: 37
|
||||
CRC-8/SMBUS: f4
|
||||
CRC-8/TECH-3250: 97
|
||||
CRC-8/WCDMA: 25
|
||||
Fletcher-8: 0c
|
||||
`,
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Generate all checksums",
|
||||
"args": ["8", true]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Full generate 10 bits checksums with name",
|
||||
input: CHECK_STRING,
|
||||
expectedOutput: `CRC-10/ATM: 199
|
||||
CRC-10/CDMA2000: 233
|
||||
CRC-10/GSM: 12a
|
||||
CRC-10/I-610: 199
|
||||
`,
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Generate all checksums",
|
||||
"args": ["10", true]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Full generate 11 bits checksums with name",
|
||||
input: CHECK_STRING,
|
||||
expectedOutput: `CRC-11/FLEXRAY: 5a3
|
||||
CRC-11/UMTS: 061
|
||||
`,
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Generate all checksums",
|
||||
"args": ["11", true]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Full generate 12 bits checksums with name",
|
||||
input: CHECK_STRING,
|
||||
expectedOutput: `CRC-12/3GPP: daf
|
||||
CRC-12/CDMA2000: d4d
|
||||
CRC-12/DECT: f5b
|
||||
CRC-12/GSM: b34
|
||||
CRC-12/UMTS: daf
|
||||
`,
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Generate all checksums",
|
||||
"args": ["12", true]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Full generate 13 bits checksums with name",
|
||||
input: CHECK_STRING,
|
||||
expectedOutput: `CRC-13/BBC: 04fa
|
||||
`,
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Generate all checksums",
|
||||
"args": ["13", true]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Full generate 14 bits checksums with name",
|
||||
input: CHECK_STRING,
|
||||
expectedOutput: `CRC-14/DARC: 082d
|
||||
CRC-14/GSM: 30ae
|
||||
`,
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Generate all checksums",
|
||||
"args": ["14", true]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Full generate 15 bits checksums with name",
|
||||
input: CHECK_STRING,
|
||||
expectedOutput: `CRC-15/CAN: 059e
|
||||
CRC-15/MPT1327: 2566
|
||||
`,
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Generate all checksums",
|
||||
"args": ["15", true]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Full generate 16 bits checksums with name",
|
||||
input: CHECK_STRING,
|
||||
expectedOutput: `CRC-16: bb3d
|
||||
CRC-16/A: bf05
|
||||
CRC-16/ACORN: 31c3
|
||||
CRC-16/ARC: bb3d
|
||||
CRC-16/AUG-CCITT: e5cc
|
||||
CRC-16/AUTOSAR: 29b1
|
||||
CRC-16/B: 906e
|
||||
CRC-16/BLUETOOTH: 2189
|
||||
CRC-16/BUYPASS: fee8
|
||||
CRC-16/CCITT: 2189
|
||||
CRC-16/CCITT-FALSE: 29b1
|
||||
CRC-16/CCITT-TRUE: 2189
|
||||
CRC-16/CCITT-ZERO: 31c3
|
||||
CRC-16/CDMA2000: 4c06
|
||||
CRC-16/CMS: aee7
|
||||
CRC-16/DARC: d64e
|
||||
CRC-16/DDS-110: 9ecf
|
||||
CRC-16/DECT-R: 007e
|
||||
CRC-16/DECT-X: 007f
|
||||
CRC-16/DNP: ea82
|
||||
CRC-16/EN-13757: c2b7
|
||||
CRC-16/EPC: d64e
|
||||
CRC-16/EPC-C1G2: d64e
|
||||
CRC-16/GENIBUS: d64e
|
||||
CRC-16/GSM: ce3c
|
||||
CRC-16/I-CODE: d64e
|
||||
CRC-16/IBM: bb3d
|
||||
CRC-16/IBM-3740: 29b1
|
||||
CRC-16/IBM-SDLC: 906e
|
||||
CRC-16/IEC-61158-2: a819
|
||||
CRC-16/ISO-HDLC: 906e
|
||||
CRC-16/ISO-IEC-14443-3-A: bf05
|
||||
CRC-16/ISO-IEC-14443-3-B: 906e
|
||||
CRC-16/KERMIT: 2189
|
||||
CRC-16/LHA: bb3d
|
||||
CRC-16/LJ1200: bdf4
|
||||
CRC-16/LTE: 31c3
|
||||
CRC-16/M17: 772b
|
||||
CRC-16/MAXIM: 44c2
|
||||
CRC-16/MAXIM-DOW: 44c2
|
||||
CRC-16/MCRF4XX: 6f91
|
||||
CRC-16/MODBUS: 4b37
|
||||
CRC-16/NRSC-5: a066
|
||||
CRC-16/OPENSAFETY-A: 5d38
|
||||
CRC-16/OPENSAFETY-B: 20fe
|
||||
CRC-16/PROFIBUS: a819
|
||||
CRC-16/RIELLO: 63d0
|
||||
CRC-16/SPI-FUJITSU: e5cc
|
||||
CRC-16/T10-DIF: d0db
|
||||
CRC-16/TELEDISK: 0fb3
|
||||
CRC-16/TMS37157: 26b1
|
||||
CRC-16/UMTS: fee8
|
||||
CRC-16/USB: b4c8
|
||||
CRC-16/V-41-LSB: 2189
|
||||
CRC-16/V-41-MSB: 31c3
|
||||
CRC-16/VERIFONE: fee8
|
||||
CRC-16/X-25: 906e
|
||||
CRC-16/XMODEM: 31c3
|
||||
CRC-16/ZMODEM: 31c3
|
||||
Fletcher-16: 1ede
|
||||
`,
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Generate all checksums",
|
||||
"args": ["16", true]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Full generate 17 bits checksums with name",
|
||||
input: CHECK_STRING,
|
||||
expectedOutput: `CRC-17/CAN-FD: 04f03
|
||||
`,
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Generate all checksums",
|
||||
"args": ["17", true]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Full generate 21 bits checksums with name",
|
||||
input: CHECK_STRING,
|
||||
expectedOutput: `CRC-21/CAN-FD: 0ed841
|
||||
`,
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Generate all checksums",
|
||||
"args": ["21", true]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Full generate 24 bits checksums with name",
|
||||
input: CHECK_STRING,
|
||||
expectedOutput: `CRC-24/BLE: c25a56
|
||||
CRC-24/FLEXRAY-A: 7979bd
|
||||
CRC-24/FLEXRAY-B: 1f23b8
|
||||
CRC-24/INTERLAKEN: b4f3e6
|
||||
CRC-24/LTE-A: cde703
|
||||
CRC-24/LTE-B: 23ef52
|
||||
CRC-24/OPENPGP: 21cf02
|
||||
CRC-24/OS-9: 200fa5
|
||||
`,
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Generate all checksums",
|
||||
"args": ["24", true]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Full generate 30 bits checksums with name",
|
||||
input: CHECK_STRING,
|
||||
expectedOutput: `CRC-30/CDMA: 04c34abf
|
||||
`,
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Generate all checksums",
|
||||
"args": ["30", true]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Full generate 31 bits checksums with name",
|
||||
input: CHECK_STRING,
|
||||
expectedOutput: `CRC-31/PHILIPS: 0ce9e46c
|
||||
`,
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Generate all checksums",
|
||||
"args": ["31", true]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Full generate 32 bits checksums with name",
|
||||
input: CHECK_STRING,
|
||||
expectedOutput: `Adler-32: 091e01de
|
||||
CRC-32: cbf43926
|
||||
CRC-32/AAL5: fc891918
|
||||
CRC-32/ADCCP: cbf43926
|
||||
CRC-32/AIXM: 3010bf7f
|
||||
CRC-32/AUTOSAR: 1697d06a
|
||||
CRC-32/BASE91-C: e3069283
|
||||
CRC-32/BASE91-D: 87315576
|
||||
CRC-32/BZIP2: fc891918
|
||||
CRC-32/C: e3069283
|
||||
CRC-32/CASTAGNOLI: e3069283
|
||||
CRC-32/CD-ROM-EDC: 6ec2edc4
|
||||
CRC-32/CKSUM: 765e7680
|
||||
CRC-32/D: 87315576
|
||||
CRC-32/DECT-B: fc891918
|
||||
CRC-32/INTERLAKEN: e3069283
|
||||
CRC-32/ISCSI: e3069283
|
||||
CRC-32/ISO-HDLC: cbf43926
|
||||
CRC-32/JAMCRC: 340bc6d9
|
||||
CRC-32/MEF: d2c22f51
|
||||
CRC-32/MPEG-2: 0376e6e7
|
||||
CRC-32/NVME: e3069283
|
||||
CRC-32/PKZIP: cbf43926
|
||||
CRC-32/POSIX: 765e7680
|
||||
CRC-32/Q: 3010bf7f
|
||||
CRC-32/SATA: cf72afe8
|
||||
CRC-32/V-42: cbf43926
|
||||
CRC-32/XFER: bd0be338
|
||||
CRC-32/XZ: cbf43926
|
||||
Fletcher-32: df09d509
|
||||
`,
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Generate all checksums",
|
||||
"args": ["32", true]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Full generate 40 bits checksums with name",
|
||||
input: CHECK_STRING,
|
||||
expectedOutput: `CRC-40/GSM: d4164fc646
|
||||
`,
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Generate all checksums",
|
||||
"args": ["40", true]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Full generate 64 bits checksums with name",
|
||||
input: CHECK_STRING,
|
||||
expectedOutput: `CRC-64/ECMA-182: 6c40df5f0b497347
|
||||
CRC-64/GO-ECMA: 995dc9bbdf1939fa
|
||||
CRC-64/GO-ISO: b90956c775a41001
|
||||
CRC-64/MS: 75d4b74f024eceea
|
||||
CRC-64/NVME: ae8b14860a799888
|
||||
CRC-64/REDIS: e9c6d914c4b8d9ca
|
||||
CRC-64/WE: 62ec59e3f1a4f00a
|
||||
CRC-64/XZ: 995dc9bbdf1939fa
|
||||
Fletcher-64: 0d0803376c6a689f
|
||||
`,
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Generate all checksums",
|
||||
"args": ["64", true]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Full generate 82 bits checksums with name",
|
||||
input: CHECK_STRING,
|
||||
expectedOutput: `CRC-82/DARC: 09ea83f625023801fd612
|
||||
`,
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Generate all checksums",
|
||||
"args": ["82", true]
|
||||
}
|
||||
]
|
||||
}
|
||||
]);
|
||||
@@ -54,16 +54,6 @@ LM Hash: 01FC5A6BE7BC6929AAD3B435B51404EE
|
||||
NT Hash: 0CB6948805F797BF2A82807973B89537
|
||||
SSDEEP: 3:Hn:Hn
|
||||
CTPH: A:E:E
|
||||
|
||||
Checksums:
|
||||
Fletcher-8: 3d
|
||||
Fletcher-16: 5dc1
|
||||
Fletcher-32: 3f5cd9e7
|
||||
Fletcher-64: 7473657474736574
|
||||
Adler-32: 045d01c1
|
||||
CRC-8: b9
|
||||
CRC-16: f82e
|
||||
CRC-32: d87f7e0c
|
||||
`,
|
||||
recipeConfig: [
|
||||
{
|
||||
|
||||
551
tests/operations/tests/Jsonata.mjs
Normal file
551
tests/operations/tests/Jsonata.mjs
Normal file
@@ -0,0 +1,551 @@
|
||||
/**
|
||||
* Jsonata Query tests.
|
||||
*
|
||||
* @author Jon King [jon@ajarsoftware.com]
|
||||
*
|
||||
* @copyright Crown Copyright 2025
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
import TestRegister from "../../lib/TestRegister.mjs";
|
||||
|
||||
const INPUT_JSON_OBJECT_WITH_ARRAYS = `{
|
||||
"FirstName": "Fred",
|
||||
"Surname": "Smith",
|
||||
"Age": 28,
|
||||
"Address": {
|
||||
"Street": "Hursley Park",
|
||||
"City": "Winchester",
|
||||
"Postcode": "SO21 2JN"
|
||||
},
|
||||
"Phone": [
|
||||
{
|
||||
"type": "home",
|
||||
"number": "0203 544 1234"
|
||||
},
|
||||
{
|
||||
"type": "office",
|
||||
"number": "01962 001234"
|
||||
},
|
||||
{
|
||||
"type": "office",
|
||||
"number": "01962 001235"
|
||||
},
|
||||
{
|
||||
"type": "mobile",
|
||||
"number": "077 7700 1234"
|
||||
}
|
||||
],
|
||||
"Email": [
|
||||
{
|
||||
"type": "work",
|
||||
"address": ["fred.smith@my-work.com", "fsmith@my-work.com"]
|
||||
},
|
||||
{
|
||||
"type": "home",
|
||||
"address": ["freddy@my-social.com", "frederic.smith@very-serious.com"]
|
||||
}
|
||||
],
|
||||
"Other": {
|
||||
"Over 18 ?": true,
|
||||
"Misc": null,
|
||||
"Alternative.Address": {
|
||||
"Street": "Brick Lane",
|
||||
"City": "London",
|
||||
"Postcode": "E1 6RF"
|
||||
}
|
||||
}
|
||||
}`;
|
||||
|
||||
const INPUT_ARRAY_OF_OBJECTS = `[
|
||||
{ "ref": [ 1,2 ] },
|
||||
{ "ref": [ 3,4 ] }
|
||||
]`;
|
||||
|
||||
const INPUT_NUMBER_ARRAY = `{
|
||||
"Numbers": [1, 2.4, 3.5, 10, 20.9, 30]
|
||||
}`;
|
||||
|
||||
TestRegister.addTests([
|
||||
{
|
||||
name: "Jsonata: Returns a JSON string (double quoted)",
|
||||
input: INPUT_JSON_OBJECT_WITH_ARRAYS,
|
||||
expectedOutput: '"Smith"',
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Jsonata Query",
|
||||
args: ["Surname"],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Jsonata: Returns a JSON number",
|
||||
input: INPUT_JSON_OBJECT_WITH_ARRAYS,
|
||||
expectedOutput: "28",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Jsonata Query",
|
||||
args: ["Age"],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Jsonata: Field references are separated by '.'",
|
||||
input: INPUT_JSON_OBJECT_WITH_ARRAYS,
|
||||
expectedOutput: '"Winchester"',
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Jsonata Query",
|
||||
args: ["Address.City"],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Jsonata: Matched the path and returns the null value",
|
||||
input: INPUT_JSON_OBJECT_WITH_ARRAYS,
|
||||
expectedOutput: "null",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Jsonata Query",
|
||||
args: ["Other.Misc"],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Jsonata: Path not found. Returns nothing",
|
||||
input: INPUT_JSON_OBJECT_WITH_ARRAYS,
|
||||
expectedOutput: '""',
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Jsonata Query",
|
||||
args: ["Other.DoesntExist"],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Jsonata: Field references containing whitespace or reserved tokens can be enclosed in backticks",
|
||||
input: INPUT_JSON_OBJECT_WITH_ARRAYS,
|
||||
expectedOutput: "true",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Jsonata Query",
|
||||
args: ["Other.`Over 18 ?`"],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Jsonata: Returns the first item (an object)",
|
||||
input: INPUT_JSON_OBJECT_WITH_ARRAYS,
|
||||
expectedOutput: '{"type":"home","number":"0203 544 1234"}',
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Jsonata Query",
|
||||
args: ["Phone[0]"],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Jsonata: Returns the second item",
|
||||
input: INPUT_JSON_OBJECT_WITH_ARRAYS,
|
||||
expectedOutput: '{"type":"office","number":"01962 001234"}',
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Jsonata Query",
|
||||
args: ["Phone[1]"],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Jsonata: Returns the last item",
|
||||
input: INPUT_JSON_OBJECT_WITH_ARRAYS,
|
||||
expectedOutput: '{"type":"mobile","number":"077 7700 1234"}',
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Jsonata Query",
|
||||
args: ["Phone[-1]"],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Jsonata: Negative indexed count from the end",
|
||||
input: INPUT_JSON_OBJECT_WITH_ARRAYS,
|
||||
expectedOutput: '{"type":"office","number":"01962 001235"}',
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Jsonata Query",
|
||||
args: ["Phone[-2]"],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Jsonata: Doesn't exist - returns nothing",
|
||||
input: INPUT_JSON_OBJECT_WITH_ARRAYS,
|
||||
expectedOutput: '""',
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Jsonata Query",
|
||||
args: ["Phone[8]"],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Jsonata: Selects the number field in the first item",
|
||||
input: INPUT_JSON_OBJECT_WITH_ARRAYS,
|
||||
expectedOutput: '"0203 544 1234"',
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Jsonata Query",
|
||||
args: ["Phone[0].number"],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Jsonata: No index is given to Phone so it selects all of them (the whole array), then it selects all the number fields for each of them",
|
||||
input: INPUT_JSON_OBJECT_WITH_ARRAYS,
|
||||
expectedOutput:
|
||||
'["0203 544 1234","01962 001234","01962 001235","077 7700 1234"]',
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Jsonata Query",
|
||||
args: ["Phone.number"],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Jsonata: Might expect it to just return the first number, but it returns the first number of each of the items selected by Phone",
|
||||
input: INPUT_JSON_OBJECT_WITH_ARRAYS,
|
||||
expectedOutput:
|
||||
'["0203 544 1234","01962 001234","01962 001235","077 7700 1234"]',
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Jsonata Query",
|
||||
args: ["Phone.number[0]"],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Jsonata: Applies the index to the array returned by Phone.number.",
|
||||
input: INPUT_JSON_OBJECT_WITH_ARRAYS,
|
||||
expectedOutput: '"0203 544 1234"',
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Jsonata Query",
|
||||
args: ["(Phone.number)[0]"],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Jsonata: Returns a range of items by creating an array of indexes",
|
||||
input: INPUT_JSON_OBJECT_WITH_ARRAYS,
|
||||
expectedOutput:
|
||||
'[{"type":"home","number":"0203 544 1234"},{"type":"office","number":"01962 001234"}]',
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Jsonata Query",
|
||||
args: ["Phone[[0..1]]"],
|
||||
},
|
||||
],
|
||||
},
|
||||
// Predicates
|
||||
{
|
||||
name: "Jsonata: Select the Phone items that have a type field that equals 'mobile'",
|
||||
input: INPUT_JSON_OBJECT_WITH_ARRAYS,
|
||||
expectedOutput: '{"type":"mobile","number":"077 7700 1234"}',
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Jsonata Query",
|
||||
args: ["Phone[type='mobile']"],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Jsonata: Select the mobile phone number",
|
||||
input: INPUT_JSON_OBJECT_WITH_ARRAYS,
|
||||
expectedOutput: '"077 7700 1234"',
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Jsonata Query",
|
||||
args: ["Phone[type='mobile'].number"],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Jsonata: Select the office phone numbers - there are two of them",
|
||||
input: INPUT_JSON_OBJECT_WITH_ARRAYS,
|
||||
expectedOutput: '["01962 001234","01962 001235"]',
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Jsonata Query",
|
||||
args: ["Phone[type='office'].number"],
|
||||
},
|
||||
],
|
||||
},
|
||||
// Wildcards
|
||||
{
|
||||
name: "Jsonata: Select the values of all the fields of 'Address'",
|
||||
input: INPUT_JSON_OBJECT_WITH_ARRAYS,
|
||||
expectedOutput: '["Hursley Park","Winchester","SO21 2JN"]',
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Jsonata Query",
|
||||
args: ["Address.*"],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Jsonata: Select the 'Postcode' value of any child object",
|
||||
input: INPUT_JSON_OBJECT_WITH_ARRAYS,
|
||||
expectedOutput: '"SO21 2JN"',
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Jsonata Query",
|
||||
args: ["*.Postcode"],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Jsonata: Select all Postcode values, regardless of how deeply nested they are in the structure",
|
||||
input: INPUT_JSON_OBJECT_WITH_ARRAYS,
|
||||
expectedOutput: '["SO21 2JN","E1 6RF"]',
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Jsonata Query",
|
||||
args: ["**.Postcode"],
|
||||
},
|
||||
],
|
||||
},
|
||||
// String Expressions
|
||||
{
|
||||
name: "Jsonata: Concatenate 'FirstName' followed by space followed by 'Surname'",
|
||||
input: INPUT_JSON_OBJECT_WITH_ARRAYS,
|
||||
expectedOutput: '"Fred Smith"',
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Jsonata Query",
|
||||
args: ["FirstName & ' ' & Surname"],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Jsonata: Concatenates the 'Street' and 'City' from the 'Address' object with a comma separator",
|
||||
input: INPUT_JSON_OBJECT_WITH_ARRAYS,
|
||||
expectedOutput: '"Hursley Park, Winchester"',
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Jsonata Query",
|
||||
args: ["Address.(Street & ', ' & City)"],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Jsonata: Casts the operands to strings, if necessary",
|
||||
input: INPUT_JSON_OBJECT_WITH_ARRAYS,
|
||||
expectedOutput: '"50true"',
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Jsonata Query",
|
||||
args: ["5&0&true"],
|
||||
},
|
||||
],
|
||||
},
|
||||
// Numeric Expressions
|
||||
{
|
||||
name: "Jsonata: Addition",
|
||||
input: INPUT_NUMBER_ARRAY,
|
||||
expectedOutput: "3.4",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Jsonata Query",
|
||||
args: ["Numbers[0] + Numbers[1]"],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Jsonata: Subtraction",
|
||||
input: INPUT_NUMBER_ARRAY,
|
||||
expectedOutput: "-19.9",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Jsonata Query",
|
||||
args: ["Numbers[0] - Numbers[4]"],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Jsonata: Multiplication",
|
||||
input: INPUT_NUMBER_ARRAY,
|
||||
expectedOutput: "30",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Jsonata Query",
|
||||
args: ["Numbers[0] * Numbers[5]"],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Jsonata: Division",
|
||||
input: INPUT_NUMBER_ARRAY,
|
||||
expectedOutput: "0.04784688995215311",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Jsonata Query",
|
||||
args: ["Numbers[0] / Numbers[4]"],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Jsonata: Modulus",
|
||||
input: INPUT_NUMBER_ARRAY,
|
||||
expectedOutput: "3.5",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Jsonata Query",
|
||||
args: ["Numbers[2] % Numbers[5]"],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Jsonata: Equality",
|
||||
input: INPUT_NUMBER_ARRAY,
|
||||
expectedOutput: "false",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Jsonata Query",
|
||||
args: ["Numbers[0] = Numbers[5]"],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Jsonata: Inequality",
|
||||
input: INPUT_NUMBER_ARRAY,
|
||||
expectedOutput: "true",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Jsonata Query",
|
||||
args: ["Numbers[0] != Numbers[4]"],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Jsonata: Less than",
|
||||
input: INPUT_NUMBER_ARRAY,
|
||||
expectedOutput: "true",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Jsonata Query",
|
||||
args: ["Numbers[0] < Numbers[4]"],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Jsonata: Less than or equal to",
|
||||
input: INPUT_NUMBER_ARRAY,
|
||||
expectedOutput: "true",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Jsonata Query",
|
||||
args: ["Numbers[0] <= Numbers[4]"],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Jsonata: Greater than",
|
||||
input: INPUT_NUMBER_ARRAY,
|
||||
expectedOutput: "false",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Jsonata Query",
|
||||
args: ["Numbers[0] > Numbers[4]"],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Jsonata: Greater than or equal to",
|
||||
input: INPUT_NUMBER_ARRAY,
|
||||
expectedOutput: "false",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Jsonata Query",
|
||||
args: ["Numbers[2] >= Numbers[4]"],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Jsonata: Value is contained in",
|
||||
input: INPUT_JSON_OBJECT_WITH_ARRAYS,
|
||||
expectedOutput: "true",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Jsonata Query",
|
||||
args: ['"01962 001234" in Phone.number'],
|
||||
},
|
||||
],
|
||||
},
|
||||
// Boolean Expressions
|
||||
{
|
||||
name: "Jsonata: and",
|
||||
input: INPUT_NUMBER_ARRAY,
|
||||
expectedOutput: "true",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Jsonata Query",
|
||||
args: ["(Numbers[2] != 0) and (Numbers[5] != Numbers[1])"],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Jsonata: or",
|
||||
input: INPUT_NUMBER_ARRAY,
|
||||
expectedOutput: "true",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Jsonata Query",
|
||||
args: ["(Numbers[2] != 0) or (Numbers[5] = Numbers[1])"],
|
||||
},
|
||||
],
|
||||
},
|
||||
// Array tests
|
||||
{
|
||||
name: "Jsonata: $ at the start of an expression refers to the entire input document, subscripting it with 0 selects the first item",
|
||||
input: INPUT_ARRAY_OF_OBJECTS,
|
||||
expectedOutput: '{"ref":[1,2]}',
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Jsonata Query",
|
||||
args: ["$[0]"],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Jsonata: .ref here returns the entire internal array",
|
||||
input: INPUT_ARRAY_OF_OBJECTS,
|
||||
expectedOutput: "[1,2]",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Jsonata Query",
|
||||
args: ["$[0].ref"],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Jsonata: returns element on first position of the internal array",
|
||||
input: INPUT_ARRAY_OF_OBJECTS,
|
||||
expectedOutput: "1",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Jsonata Query",
|
||||
args: ["$[0].ref[0]"],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Jsonata: $.field_reference flattens the result into a single array",
|
||||
input: INPUT_ARRAY_OF_OBJECTS,
|
||||
expectedOutput: "[1,2,3,4]",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Jsonata Query",
|
||||
args: ["$.ref"],
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
112
tests/operations/tests/PHPSerialize.mjs
Normal file
112
tests/operations/tests/PHPSerialize.mjs
Normal file
@@ -0,0 +1,112 @@
|
||||
/**
|
||||
* PHP Serialization tests.
|
||||
*
|
||||
* @author brun0ne [brunonblok@gmail.com]
|
||||
*
|
||||
* @copyright Crown Copyright 2023
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import TestRegister from "../../lib/TestRegister.mjs";
|
||||
|
||||
TestRegister.addTests([
|
||||
{
|
||||
name: "PHP Serialize empty array",
|
||||
input: "[]",
|
||||
expectedOutput: "a:0:{}",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "PHP Serialize",
|
||||
args: []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "PHP Serialize empty object",
|
||||
input: "{}",
|
||||
expectedOutput: "a:0:{}",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "PHP Serialize",
|
||||
args: []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "PHP Serialize null",
|
||||
input: "null",
|
||||
expectedOutput: "N;",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "PHP Serialize",
|
||||
args: []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "PHP Serialize integer",
|
||||
input: "10",
|
||||
expectedOutput: "i:10;",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "PHP Serialize",
|
||||
args: []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "PHP Serialize float",
|
||||
input: "14.523",
|
||||
expectedOutput: "d:14.523;",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "PHP Serialize",
|
||||
args: []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "PHP Serialize boolean",
|
||||
input: "[true, false]",
|
||||
expectedOutput: "a:2:{i:0;b:1;i:1;b:0;}",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "PHP Serialize",
|
||||
args: []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "PHP Serialize string",
|
||||
input: "\"Test string to serialize\"",
|
||||
expectedOutput: "s:24:\"Test string to serialize\";",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "PHP Serialize",
|
||||
args: []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "PHP Serialize object",
|
||||
input: "{\"a\": 10,\"0\": {\"ab\": true}}",
|
||||
expectedOutput: "a:2:{s:1:\"0\";a:1:{s:2:\"ab\";b:1;}s:1:\"a\";i:10;}",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "PHP Serialize",
|
||||
args: []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "PHP Serialize array",
|
||||
input: "[1,\"abc\",true,{\"x\":1,\"y\":2}]",
|
||||
expectedOutput: "a:4:{i:0;i:1;i:1;s:3:\"abc\";i:2;b:1;i:3;a:2:{s:1:\"x\";i:1;s:1:\"y\";i:2;}}",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "PHP Serialize",
|
||||
args: []
|
||||
}
|
||||
]
|
||||
}
|
||||
]);
|
||||
53
tests/operations/tests/Template.mjs
Normal file
53
tests/operations/tests/Template.mjs
Normal file
@@ -0,0 +1,53 @@
|
||||
/**
|
||||
* @author kendallgoto [k@kgo.to]
|
||||
* @copyright Crown Copyright 2025
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import TestRegister from "../../lib/TestRegister.mjs";
|
||||
TestRegister.addTests([
|
||||
{
|
||||
"name": "Template: Simple Print",
|
||||
"input": "{}",
|
||||
"expectedOutput": "Hello, world!",
|
||||
"recipeConfig": [
|
||||
{
|
||||
"op": "Template",
|
||||
"args": ["Hello, world!"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Template: Print Basic Variables",
|
||||
"input": "{\"one\": 1, \"two\": 2}",
|
||||
"expectedOutput": "1 2",
|
||||
"recipeConfig": [
|
||||
{
|
||||
"op": "Template",
|
||||
"args": ["{{ one }} {{ two }}"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Template: Partials",
|
||||
"input": "{\"users\":[{\"name\":\"Someone\",\"age\":25},{\"name\":\"Someone Else\",\"age\":32}]}",
|
||||
"expectedOutput": "Name: Someone\nAge: 25\n\nName: Someone Else\nAge: 32\n\n",
|
||||
"recipeConfig": [
|
||||
{
|
||||
"op": "Template",
|
||||
"args": ["{{#*inline \"user\"}}\nName: {{ name }}\nAge: {{ age }}\n{{/inline}}\n{{#each users}}\n{{> user}}\n\n{{/each}}"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Template: Disallow XSS",
|
||||
"input": "{\"test\": \"<script></script>\"}",
|
||||
"expectedOutput": "<script></script><script></script>",
|
||||
"recipeConfig": [
|
||||
{
|
||||
"op": "Template",
|
||||
"args": ["<script></script>{{ test }}"]
|
||||
}
|
||||
]
|
||||
}
|
||||
]);
|
||||
92
tests/operations/tests/URLEncodeDecode.mjs
Normal file
92
tests/operations/tests/URLEncodeDecode.mjs
Normal file
@@ -0,0 +1,92 @@
|
||||
/**
|
||||
* URLEncode and URLDecode tests.
|
||||
*
|
||||
* @author es45411 [135977478+es45411@users.noreply.github.com]
|
||||
*
|
||||
* @copyright Crown Copyright 2018
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import TestRegister from "../../lib/TestRegister.mjs";
|
||||
|
||||
TestRegister.addTests([
|
||||
// URL Decode
|
||||
{
|
||||
name: "URLDecode: nothing",
|
||||
input: "",
|
||||
expectedOutput: "",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "URL Decode",
|
||||
args: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "URLDecode: spaces without special chars",
|
||||
input: "Hello%20world%21",
|
||||
expectedOutput: "Hello world!",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "URL Decode",
|
||||
args: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "URLDecode: spaces with special chars",
|
||||
input: "Hello%20world!",
|
||||
expectedOutput: "Hello world!",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "URL Decode",
|
||||
args: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "URLDecode: decode plus as space",
|
||||
input: "Hello%20world!",
|
||||
expectedOutput: "Hello world!",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "URL Decode",
|
||||
args: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
// URL Encode
|
||||
{
|
||||
name: "URLEncode: nothing",
|
||||
input: "",
|
||||
expectedOutput: "",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "URL Encode",
|
||||
args: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "URLEncode: spaces without special chars",
|
||||
input: "Hello world!",
|
||||
expectedOutput: "Hello%20world!",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "URL Encode",
|
||||
args: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "URLEncode: spaces with special chars",
|
||||
input: "Hello world!",
|
||||
expectedOutput: "Hello%20world%21",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "URL Encode",
|
||||
args: [true],
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
120
tests/operations/tests/XORChecksum.mjs
Normal file
120
tests/operations/tests/XORChecksum.mjs
Normal file
@@ -0,0 +1,120 @@
|
||||
/**
|
||||
* Checksum tests.
|
||||
*
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
* @copyright Crown Copyright 2018
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
import TestRegister from "../../lib/TestRegister.mjs";
|
||||
|
||||
const BASIC_STRING = "The ships hung in the sky in much the same way that bricks don't.";
|
||||
const UTF8_STR = "ნუ პანიკას";
|
||||
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("");
|
||||
|
||||
TestRegister.addTests([
|
||||
{
|
||||
name: "XOR Checksum (1): nothing",
|
||||
input: "",
|
||||
expectedOutput: "00",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "XOR Checksum",
|
||||
"args": [1]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "XOR Checksum (1): basic string",
|
||||
input: BASIC_STRING,
|
||||
expectedOutput: "08",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "XOR Checksum",
|
||||
"args": [1]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "XOR Checksum (1): UTF-8",
|
||||
input: UTF8_STR,
|
||||
expectedOutput: "df",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "XOR Checksum",
|
||||
"args": [1]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "XOR Checksum (1): all bytes",
|
||||
input: ALL_BYTES,
|
||||
expectedOutput: "00",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "XOR Checksum",
|
||||
"args": [1]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "XOR Checksum (4): nothing",
|
||||
input: "",
|
||||
expectedOutput: "00000000",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "XOR Checksum",
|
||||
"args": [4]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "XOR Checksum (4): basic string",
|
||||
input: BASIC_STRING,
|
||||
expectedOutput: "4918421b",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "XOR Checksum",
|
||||
"args": [4]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "XOR Checksum (4): UTF-8",
|
||||
input: UTF8_STR,
|
||||
expectedOutput: "83a424dc",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "XOR Checksum",
|
||||
"args": [4]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "XOR Checksum (4): all bytes",
|
||||
input: ALL_BYTES,
|
||||
expectedOutput: "00000000",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "XOR Checksum",
|
||||
"args": [4]
|
||||
}
|
||||
]
|
||||
},
|
||||
]);
|
||||
Reference in New Issue
Block a user