cyberchef 10.23.0 → 10.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +51 -0
- package/CONTRIBUTING.md +4 -1
- package/Gruntfile.js +2 -16
- package/package.json +14 -14
- package/src/core/config/Categories.json +2 -1
- package/src/core/config/OperationConfig.json +54 -3
- package/src/core/config/modules/Default.mjs +2 -0
- package/src/core/config/scripts/fixCryptoApiImports.mjs +54 -0
- package/src/core/config/scripts/fixSnackBarMarkup.mjs +28 -0
- package/src/core/lib/Extract.mjs +5 -0
- package/src/core/lib/ParityBit.mjs +50 -0
- package/src/core/operations/AnalyseUUID.mjs +109 -6
- package/src/core/operations/ExtractEmailAddresses.mjs +2 -3
- package/src/core/operations/ParityBit.mjs +128 -0
- package/src/core/operations/RegularExpression.mjs +2 -1
- package/src/core/operations/RenderMarkdown.mjs +35 -4
- package/src/core/operations/index.mjs +2 -0
- package/src/node/index.mjs +5 -0
- package/src/web/HTMLOperation.mjs +8 -2
- package/src/web/html/index.html +1 -1
- package/src/web/waiters/OperationsWaiter.mjs +30 -13
- package/tests/node/tests/operations.mjs +2 -3
- package/tests/operations/index.mjs +5 -0
- package/tests/operations/tests/AnalyseUUID.mjs +66 -0
- package/tests/operations/tests/ExtractEmailAddresses.mjs +38 -12
- package/tests/operations/tests/Fernet.mjs +18 -3
- package/tests/operations/tests/ParityBit.mjs +147 -0
- package/tests/operations/tests/RegularExpression.mjs +75 -0
- package/tests/operations/tests/RenderMarkdown.mjs +110 -0
package/CHANGELOG.md
CHANGED
|
@@ -13,6 +13,30 @@ All major and minor version changes will be documented in this file. Details of
|
|
|
13
13
|
|
|
14
14
|
## Details
|
|
15
15
|
|
|
16
|
+
### [10.24.0] - 2026-04-27
|
|
17
|
+
- Update CONTRIBUTING.md [@GCHQDeveloper581] | [#2333]
|
|
18
|
+
- Fix, and link, Fernet tests [@GCHQDeveloper581] | [#2335]
|
|
19
|
+
- [#927] added parity bit operation [@j83305] | [#1036]
|
|
20
|
+
- Feature md link blanks [@BjoernAkAManf] [@GCHQDeveloper581] | [#660]
|
|
21
|
+
- Accessibility - Add support for screenreaders in operations search [@mattnotmitt] | [#1862]
|
|
22
|
+
- Added metadata extraction for UUID strings. [@ko80240] | [#2322]
|
|
23
|
+
- chore (deps): bump the patch-updates group with 6 updates | [#2330]
|
|
24
|
+
- chore (deps): bump @codemirror/search from 6.6.0 to 6.7.0 | [#2331]
|
|
25
|
+
- (Feature) Improve CI [@GCHQDeveloper581] | [#2328]
|
|
26
|
+
- Update dependabot.yml [@GCHQDeveloper581] | [#2326]
|
|
27
|
+
- chore (deps): bump lodash, grunt-legacy-log and grunt-legacy-util | [#2327]
|
|
28
|
+
- chore (deps): bump the patch-updates group with 6 updates [@GCHQDeveloper581] | [#2323]
|
|
29
|
+
- chore (deps): bump autoprefixer from 10.4.27 to 10.5.0 | [#2324]
|
|
30
|
+
- chore (deps): bump dompurify from 3.3.3 to 3.4.0 | [#2321]
|
|
31
|
+
- chore (deps): bump follow-redirects from 1.15.11 to 1.16.0 | [#2320]
|
|
32
|
+
- Regular Expression operation email address regex: Support IPv4 domains [@C85297] [@GCHQDeveloper581] | [#2167]
|
|
33
|
+
- Rewriting fixCryptoApiImports and fixSnackbarMarkup to js to make it OS agnostic [@BigYellowHammer] | [#2298]
|
|
34
|
+
- chore (deps): bump basic-ftp from 5.2.1 to 5.2.2 | [#2317]
|
|
35
|
+
- chore (deps): bump axios from 1.13.6 to 1.15.0 | [#2316]
|
|
36
|
+
- chore (deps): bump webpack from 5.105.4 to 5.106.0 | [#2315]
|
|
37
|
+
- chore (deps): bump basic-ftp from 5.2.0 to 5.2.1 | [#2313]
|
|
38
|
+
- Update vulnerable dependencies [@GCHQDeveloper581] | [#2311]
|
|
39
|
+
|
|
16
40
|
### [10.23.0] - 2026-04-06
|
|
17
41
|
- Properly escape HTML entities in sampleDelim to avoid XSS issue [@GCHQDeveloper581] | [#2307]
|
|
18
42
|
- chore (deps): bump lodash from 4.17.23 to 4.18.1 | [#2304]
|
|
@@ -596,6 +620,7 @@ All major and minor version changes will be documented in this file. Details of
|
|
|
596
620
|
## [4.0.0] - 2016-11-28
|
|
597
621
|
- Initial open source commit [@n1474335] | [b1d73a72](https://github.com/gchq/CyberChef/commit/b1d73a725dc7ab9fb7eb789296efd2b7e4b08306)
|
|
598
622
|
|
|
623
|
+
[10.24.0]: https://github.com/gchq/CyberChef/releases/tag/v10.24.0
|
|
599
624
|
[10.23.0]: https://github.com/gchq/CyberChef/releases/tag/v10.23.0
|
|
600
625
|
[10.22.0]: https://github.com/gchq/CyberChef/releases/tag/v10.22.0
|
|
601
626
|
[10.21.0]: https://github.com/gchq/CyberChef/releases/tag/v10.21.0
|
|
@@ -872,6 +897,10 @@ All major and minor version changes will be documented in this file. Details of
|
|
|
872
897
|
[@aby-jo]: https://github.com/aby-jo
|
|
873
898
|
[@atsiv1]: https://github.com/atsiv1
|
|
874
899
|
[@fjh1997]: https://github.com/fjh1997
|
|
900
|
+
[@j83305]: https://github.com/j83305
|
|
901
|
+
[@BjoernAkAManf]: https://github.com/BjoernAkAManf
|
|
902
|
+
[@ko80240]: https://github.com/ko80240
|
|
903
|
+
[@BigYellowHammer]: https://github.com/BigYellowHammer
|
|
875
904
|
|
|
876
905
|
|
|
877
906
|
[8ad18b]: https://github.com/gchq/CyberChef/commit/8ad18bc7db6d9ff184ba3518686293a7685bf7b7
|
|
@@ -1141,4 +1170,26 @@ All major and minor version changes will be documented in this file. Details of
|
|
|
1141
1170
|
[#2194]: https://github.com/gchq/CyberChef/pull/2194
|
|
1142
1171
|
[#2193]: https://github.com/gchq/CyberChef/pull/2193
|
|
1143
1172
|
[#2192]: https://github.com/gchq/CyberChef/pull/2192
|
|
1173
|
+
[#2333]: https://github.com/gchq/CyberChef/pull/2333
|
|
1174
|
+
[#2335]: https://github.com/gchq/CyberChef/pull/2335
|
|
1175
|
+
[#1036]: https://github.com/gchq/CyberChef/pull/1036
|
|
1176
|
+
[#660]: https://github.com/gchq/CyberChef/pull/660
|
|
1177
|
+
[#1862]: https://github.com/gchq/CyberChef/pull/1862
|
|
1178
|
+
[#2322]: https://github.com/gchq/CyberChef/pull/2322
|
|
1179
|
+
[#2330]: https://github.com/gchq/CyberChef/pull/2330
|
|
1180
|
+
[#2331]: https://github.com/gchq/CyberChef/pull/2331
|
|
1181
|
+
[#2328]: https://github.com/gchq/CyberChef/pull/2328
|
|
1182
|
+
[#2326]: https://github.com/gchq/CyberChef/pull/2326
|
|
1183
|
+
[#2327]: https://github.com/gchq/CyberChef/pull/2327
|
|
1184
|
+
[#2323]: https://github.com/gchq/CyberChef/pull/2323
|
|
1185
|
+
[#2324]: https://github.com/gchq/CyberChef/pull/2324
|
|
1186
|
+
[#2321]: https://github.com/gchq/CyberChef/pull/2321
|
|
1187
|
+
[#2320]: https://github.com/gchq/CyberChef/pull/2320
|
|
1188
|
+
[#2167]: https://github.com/gchq/CyberChef/pull/2167
|
|
1189
|
+
[#2298]: https://github.com/gchq/CyberChef/pull/2298
|
|
1190
|
+
[#2317]: https://github.com/gchq/CyberChef/pull/2317
|
|
1191
|
+
[#2316]: https://github.com/gchq/CyberChef/pull/2316
|
|
1192
|
+
[#2315]: https://github.com/gchq/CyberChef/pull/2315
|
|
1193
|
+
[#2313]: https://github.com/gchq/CyberChef/pull/2313
|
|
1194
|
+
[#2311]: https://github.com/gchq/CyberChef/pull/2311
|
|
1144
1195
|
|
package/CONTRIBUTING.md
CHANGED
|
@@ -6,10 +6,13 @@ There are lots of opportunities to contribute to CyberChef. If you want ideas, t
|
|
|
6
6
|
|
|
7
7
|
Before your contributions can be accepted, you must:
|
|
8
8
|
|
|
9
|
-
-
|
|
9
|
+
- Fork the CyberChef repo
|
|
10
|
+
- Create a new branch within your fork for the changes
|
|
10
11
|
- Push your changes to your fork.
|
|
12
|
+
- Sign the [GCHQ Contributor Licence Agreement](https://cla-assistant.io/gchq/CyberChef)
|
|
11
13
|
- Submit a pull request.
|
|
12
14
|
|
|
15
|
+
Please note that we will ***reject*** pull requests from the master branch of your fork owing to the mess it makes of our own working repositories and the extra work entailed.
|
|
13
16
|
|
|
14
17
|
## Coding conventions
|
|
15
18
|
|
package/Gruntfile.js
CHANGED
|
@@ -411,25 +411,11 @@ module.exports = function (grunt) {
|
|
|
411
411
|
stdout: false,
|
|
412
412
|
},
|
|
413
413
|
fixCryptoApiImports: {
|
|
414
|
-
command:
|
|
415
|
-
switch (process.platform) {
|
|
416
|
-
case "darwin":
|
|
417
|
-
return `find ./node_modules/crypto-api/src/ \\( -type d -name .git -prune \\) -o -type f -print0 | xargs -0 sed -i '' -e '/\\.mjs/!s/\\(from "\\.[^"]*\\)";/\\1.mjs";/g'`;
|
|
418
|
-
default:
|
|
419
|
-
return `find ./node_modules/crypto-api/src/ \\( -type d -name .git -prune \\) -o -type f -print0 | xargs -0 sed -i -e '/\\.mjs/!s/\\(from "\\.[^"]*\\)";/\\1.mjs";/g'`;
|
|
420
|
-
}
|
|
421
|
-
},
|
|
414
|
+
command: `node ${nodeFlags} src/core/config/scripts/fixCryptoApiImports.mjs`,
|
|
422
415
|
stdout: false
|
|
423
416
|
},
|
|
424
417
|
fixSnackbarMarkup: {
|
|
425
|
-
command:
|
|
426
|
-
switch (process.platform) {
|
|
427
|
-
case "darwin":
|
|
428
|
-
return `sed -i '' 's/<div id=snackbar-container\\/>/<div id=snackbar-container>/g' ./node_modules/snackbarjs/src/snackbar.js`;
|
|
429
|
-
default:
|
|
430
|
-
return `sed -i 's/<div id=snackbar-container\\/>/<div id=snackbar-container>/g' ./node_modules/snackbarjs/src/snackbar.js`;
|
|
431
|
-
}
|
|
432
|
-
},
|
|
418
|
+
command: `node ${nodeFlags} src/core/config/scripts/fixSnackBarMarkup.mjs`,
|
|
433
419
|
stdout: false
|
|
434
420
|
},
|
|
435
421
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cyberchef",
|
|
3
|
-
"version": "10.
|
|
3
|
+
"version": "10.24.0",
|
|
4
4
|
"description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.",
|
|
5
5
|
"author": "n1474335 <n1474335@gmail.com>",
|
|
6
6
|
"homepage": "https://gchq.github.io/CyberChef",
|
|
@@ -46,10 +46,10 @@
|
|
|
46
46
|
"@babel/runtime": "^7.29.2",
|
|
47
47
|
"@codemirror/commands": "^6.10.3",
|
|
48
48
|
"@codemirror/language": "^6.12.3",
|
|
49
|
-
"@codemirror/search": "^6.
|
|
49
|
+
"@codemirror/search": "^6.7.0",
|
|
50
50
|
"@codemirror/state": "^6.5.4",
|
|
51
|
-
"@codemirror/view": "^6.41.
|
|
52
|
-
"autoprefixer": "^10.
|
|
51
|
+
"@codemirror/view": "^6.41.1",
|
|
52
|
+
"autoprefixer": "^10.5.0",
|
|
53
53
|
"babel-loader": "^10.1.1",
|
|
54
54
|
"base64-loader": "^1.0.0",
|
|
55
55
|
"chromedriver": "^146.0.6",
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
"eslint": "^9.39.4",
|
|
64
64
|
"eslint-plugin-jsdoc": "^50.8.0",
|
|
65
65
|
"globals": "^15.15.0",
|
|
66
|
-
"grunt": "^1.6.
|
|
66
|
+
"grunt": "^1.6.2",
|
|
67
67
|
"grunt-chmod": "~1.1.1",
|
|
68
68
|
"grunt-concurrent": "^3.0.0",
|
|
69
69
|
"grunt-contrib-clean": "~2.0.1",
|
|
@@ -74,19 +74,19 @@
|
|
|
74
74
|
"grunt-exec": "~3.0.0",
|
|
75
75
|
"grunt-webpack": "^6.0.0",
|
|
76
76
|
"grunt-zip": "^1.0.0",
|
|
77
|
-
"html-webpack-plugin": "^5.6.
|
|
77
|
+
"html-webpack-plugin": "^5.6.7",
|
|
78
78
|
"imports-loader": "^5.0.0",
|
|
79
79
|
"mini-css-extract-plugin": "2.10.2",
|
|
80
80
|
"modify-source-webpack-plugin": "^4.1.0",
|
|
81
81
|
"nightwatch": "^3.15.0",
|
|
82
|
-
"postcss": "^8.5.
|
|
82
|
+
"postcss": "^8.5.10",
|
|
83
83
|
"postcss-css-variables": "^0.19.0",
|
|
84
84
|
"postcss-import": "^16.1.1",
|
|
85
85
|
"postcss-loader": "^8.2.1",
|
|
86
86
|
"prompt": "^1.3.0",
|
|
87
87
|
"sitemap": "^8.0.3",
|
|
88
|
-
"terser": "^5.46.
|
|
89
|
-
"webpack": "^5.
|
|
88
|
+
"terser": "^5.46.2",
|
|
89
|
+
"webpack": "^5.106.2",
|
|
90
90
|
"webpack-bundle-analyzer": "^4.10.2",
|
|
91
91
|
"webpack-dev-server": "5.0.4",
|
|
92
92
|
"webpack-node-externals": "^3.0.0",
|
|
@@ -97,7 +97,7 @@
|
|
|
97
97
|
"@astronautlabs/amf": "^0.0.6",
|
|
98
98
|
"@blu3r4y/lzma": "^2.3.3",
|
|
99
99
|
"@wavesenterprise/crypto-gost-js": "^2.1.0-RC1",
|
|
100
|
-
"@xmldom/xmldom": "^0.8.
|
|
100
|
+
"@xmldom/xmldom": "^0.8.13",
|
|
101
101
|
"argon2-browser": "^1.18.0",
|
|
102
102
|
"arrive": "^2.5.3",
|
|
103
103
|
"assert": "^2.1.0",
|
|
@@ -121,7 +121,7 @@
|
|
|
121
121
|
"d3": "7.9.0",
|
|
122
122
|
"d3-hexbin": "^0.2.2",
|
|
123
123
|
"diff": "^5.2.2",
|
|
124
|
-
"dompurify": "^3.
|
|
124
|
+
"dompurify": "^3.4.1",
|
|
125
125
|
"es6-promisify": "^7.0.0",
|
|
126
126
|
"escodegen": "^2.1.0",
|
|
127
127
|
"esprima": "^4.0.1",
|
|
@@ -135,7 +135,7 @@
|
|
|
135
135
|
"hash-wasm": "^4.12.0",
|
|
136
136
|
"highlight.js": "^11.11.1",
|
|
137
137
|
"ieee754": "^1.2.1",
|
|
138
|
-
"jimp": "
|
|
138
|
+
"jimp": "1.6.0",
|
|
139
139
|
"jq-web": "^0.5.1",
|
|
140
140
|
"jquery": "3.7.1",
|
|
141
141
|
"js-sha3": "^0.9.3",
|
|
@@ -145,7 +145,7 @@
|
|
|
145
145
|
"jsonpath-plus": "^10.4.0",
|
|
146
146
|
"jsonwebtoken": "9.0.3",
|
|
147
147
|
"jsqr": "^1.4.0",
|
|
148
|
-
"jsrsasign": "^11.1.
|
|
148
|
+
"jsrsasign": "^11.1.3",
|
|
149
149
|
"kbpgp": "^2.1.17",
|
|
150
150
|
"libbzip2-wasm": "0.0.4",
|
|
151
151
|
"libyara-wasm": "^1.2.1",
|
|
@@ -168,7 +168,7 @@
|
|
|
168
168
|
"path": "^0.12.7",
|
|
169
169
|
"popper.js": "^1.16.1",
|
|
170
170
|
"process": "^0.11.10",
|
|
171
|
-
"protobufjs": "^7.5.
|
|
171
|
+
"protobufjs": "^7.5.5",
|
|
172
172
|
"qr-image": "^3.2.0",
|
|
173
173
|
"reflect-metadata": "^0.2.2",
|
|
174
174
|
"rison": "^0.1.1",
|
|
@@ -702,13 +702,19 @@
|
|
|
702
702
|
},
|
|
703
703
|
"Analyse UUID": {
|
|
704
704
|
"module": "Crypto",
|
|
705
|
-
"description": "
|
|
705
|
+
"description": "Operation for extracting metadata and detecting the version of a given UUID.",
|
|
706
706
|
"infoURL": "https://wikipedia.org/wiki/Universally_unique_identifier",
|
|
707
707
|
"inputType": "string",
|
|
708
708
|
"outputType": "string",
|
|
709
709
|
"flowControl": false,
|
|
710
710
|
"manualBake": false,
|
|
711
|
-
"args": [
|
|
711
|
+
"args": [
|
|
712
|
+
{
|
|
713
|
+
"name": "Include Metadata",
|
|
714
|
+
"type": "boolean",
|
|
715
|
+
"value": true
|
|
716
|
+
}
|
|
717
|
+
]
|
|
712
718
|
},
|
|
713
719
|
"Argon2": {
|
|
714
720
|
"module": "Crypto",
|
|
@@ -13218,6 +13224,46 @@
|
|
|
13218
13224
|
}
|
|
13219
13225
|
]
|
|
13220
13226
|
},
|
|
13227
|
+
"Parity Bit": {
|
|
13228
|
+
"module": "Default",
|
|
13229
|
+
"description": "A parity bit, or check bit, is the simplest form of error detection. It is a bit which is added to a string of bits and represents if the number of 1's in the binary string is an even number or odd number.<br><br>If a delimiter is specified, the parity bit calculation will be performed on each 'block' of the input data, where the blocks are created by slicing the input at each occurence of the delimiter character",
|
|
13230
|
+
"infoURL": "https://wikipedia.org/wiki/Parity_bit",
|
|
13231
|
+
"inputType": "string",
|
|
13232
|
+
"outputType": "string",
|
|
13233
|
+
"flowControl": false,
|
|
13234
|
+
"manualBake": false,
|
|
13235
|
+
"args": [
|
|
13236
|
+
{
|
|
13237
|
+
"name": "Mode",
|
|
13238
|
+
"type": "option",
|
|
13239
|
+
"value": [
|
|
13240
|
+
"Even Parity",
|
|
13241
|
+
"Odd Parity"
|
|
13242
|
+
]
|
|
13243
|
+
},
|
|
13244
|
+
{
|
|
13245
|
+
"name": "Postion",
|
|
13246
|
+
"type": "option",
|
|
13247
|
+
"value": [
|
|
13248
|
+
"Start",
|
|
13249
|
+
"End"
|
|
13250
|
+
]
|
|
13251
|
+
},
|
|
13252
|
+
{
|
|
13253
|
+
"name": "Encode or Decode",
|
|
13254
|
+
"type": "option",
|
|
13255
|
+
"value": [
|
|
13256
|
+
"Encode",
|
|
13257
|
+
"Decode"
|
|
13258
|
+
]
|
|
13259
|
+
},
|
|
13260
|
+
{
|
|
13261
|
+
"name": "Delimiter",
|
|
13262
|
+
"type": "shortString",
|
|
13263
|
+
"value": ""
|
|
13264
|
+
}
|
|
13265
|
+
]
|
|
13266
|
+
},
|
|
13221
13267
|
"Parse ASN.1 hex string": {
|
|
13222
13268
|
"module": "PublicKey",
|
|
13223
13269
|
"description": "Abstract Syntax Notation One (ASN.1) is a standard and notation that describes rules and structures for representing, encoding, transmitting, and decoding data in telecommunications and computer networking.<br><br>This operation parses arbitrary ASN.1 data (encoded as an hex string: use the 'To Hex' operation if necessary) and presents the resulting tree.",
|
|
@@ -15436,7 +15482,7 @@
|
|
|
15436
15482
|
},
|
|
15437
15483
|
{
|
|
15438
15484
|
"name": "Email address",
|
|
15439
|
-
"value": "(?:[\\u00A0-\\uD7FF\\uE000-\\uFFFFa-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[\\u00A0-\\uD7FF\\uE000-\\uFFFFa-z0-9!#$%&'*+/=?^_`{|}~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]
|
|
15485
|
+
"value": "(?:[\\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]))\\])"
|
|
15440
15486
|
},
|
|
15441
15487
|
{
|
|
15442
15488
|
"name": "URL",
|
|
@@ -15660,6 +15706,11 @@
|
|
|
15660
15706
|
"name": "Enable syntax highlighting",
|
|
15661
15707
|
"type": "boolean",
|
|
15662
15708
|
"value": true
|
|
15709
|
+
},
|
|
15710
|
+
{
|
|
15711
|
+
"name": "Open links in new tab.",
|
|
15712
|
+
"type": "boolean",
|
|
15713
|
+
"value": false
|
|
15663
15714
|
}
|
|
15664
15715
|
]
|
|
15665
15716
|
},
|
|
@@ -115,6 +115,7 @@ import PHPDeserialize from "../../operations/PHPDeserialize.mjs";
|
|
|
115
115
|
import PHPSerialize from "../../operations/PHPSerialize.mjs";
|
|
116
116
|
import PLISTViewer from "../../operations/PLISTViewer.mjs";
|
|
117
117
|
import PadLines from "../../operations/PadLines.mjs";
|
|
118
|
+
import ParityBit from "../../operations/ParityBit.mjs";
|
|
118
119
|
import ParseColourCode from "../../operations/ParseColourCode.mjs";
|
|
119
120
|
import ParseDateTime from "../../operations/ParseDateTime.mjs";
|
|
120
121
|
import ParseEthernetFrame from "../../operations/ParseEthernetFrame.mjs";
|
|
@@ -324,6 +325,7 @@ OpModules.Default = {
|
|
|
324
325
|
"PHP Serialize": PHPSerialize,
|
|
325
326
|
"P-list Viewer": PLISTViewer,
|
|
326
327
|
"Pad lines": PadLines,
|
|
328
|
+
"Parity Bit": ParityBit,
|
|
327
329
|
"Parse colour code": ParseColourCode,
|
|
328
330
|
"Parse DateTime": ParseDateTime,
|
|
329
331
|
"Parse Ethernet frame": ParseEthernetFrame,
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This script updates crypto-api package
|
|
3
|
+
* It adds .mjs to local imports where its missing
|
|
4
|
+
*
|
|
5
|
+
* before:
|
|
6
|
+
* import foo from "./bar";
|
|
7
|
+
* after
|
|
8
|
+
* import foo from "./bar.mjs";
|
|
9
|
+
*
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/* eslint no-console: ["off"] */
|
|
13
|
+
|
|
14
|
+
import { readdirSync, readFileSync, writeFileSync } from "fs";
|
|
15
|
+
import { join } from "path";
|
|
16
|
+
|
|
17
|
+
// Base directory of crypto-api source
|
|
18
|
+
const baseDir = join(process.cwd(), "node_modules/crypto-api/src");
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Recursively walk a directory, updating import statements
|
|
22
|
+
* to include ".mjs" if missing
|
|
23
|
+
*/
|
|
24
|
+
function walk(dir) {
|
|
25
|
+
const entries = readdirSync(dir, { withFileTypes: true });
|
|
26
|
+
|
|
27
|
+
for (const entry of entries) {
|
|
28
|
+
if (entry.name === ".git") continue;
|
|
29
|
+
|
|
30
|
+
const fullPath = join(dir, entry.name);
|
|
31
|
+
|
|
32
|
+
if (entry.isDirectory()) {
|
|
33
|
+
walk(fullPath);
|
|
34
|
+
} else if (entry.isFile()) {
|
|
35
|
+
const content = readFileSync(fullPath, "utf8");
|
|
36
|
+
|
|
37
|
+
// Add .mjs to imports if not present
|
|
38
|
+
const updated = content.replace(
|
|
39
|
+
/from "(\.[^"]*)";/g,
|
|
40
|
+
(match, p1) => {
|
|
41
|
+
if (p1.endsWith(".mjs")) return match;
|
|
42
|
+
return `from "${p1}.mjs";`;
|
|
43
|
+
}
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
if (updated !== content) {
|
|
47
|
+
writeFileSync(fullPath, updated, "utf8");
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Run the walker
|
|
54
|
+
walk(baseDir);
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This script updates snackbarjs package
|
|
3
|
+
* Replaces self-closing div with standard opening div
|
|
4
|
+
*
|
|
5
|
+
* before:
|
|
6
|
+
* <div id=snackbar-container/>
|
|
7
|
+
* after:
|
|
8
|
+
* <div id=snackbar-container>
|
|
9
|
+
*
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/* eslint no-console: ["off"] */
|
|
13
|
+
|
|
14
|
+
import { readFileSync, writeFileSync } from "fs";
|
|
15
|
+
import { join } from "path";
|
|
16
|
+
|
|
17
|
+
// Base directory of snackbarjs source
|
|
18
|
+
const filePath = join(process.cwd(), "node_modules/snackbarjs/src/snackbar.js");
|
|
19
|
+
|
|
20
|
+
const content = readFileSync(filePath, "utf8");
|
|
21
|
+
|
|
22
|
+
// Replace self-closing div with standard opening div
|
|
23
|
+
const updated = content.replace(
|
|
24
|
+
/<div id=snackbar-container\/>/g,
|
|
25
|
+
"<div id=snackbar-container>"
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
writeFileSync(filePath, updated, "utf8");
|
package/src/core/lib/Extract.mjs
CHANGED
|
@@ -45,6 +45,11 @@ export function search(input, searchRegex, removeRegex=null, sortBy=null, unique
|
|
|
45
45
|
return results;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
+
/**
|
|
49
|
+
* Email regular expression
|
|
50
|
+
*/
|
|
51
|
+
export const EMAIL_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;
|
|
52
|
+
|
|
48
53
|
|
|
49
54
|
/**
|
|
50
55
|
* URL regular expression
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parity Bit functions.
|
|
3
|
+
*
|
|
4
|
+
* @author j83305 [awz22@protonmail.com]
|
|
5
|
+
* @copyright Crown Copyright 2020
|
|
6
|
+
* @license Apache-2.0
|
|
7
|
+
*
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import OperationError from "../errors/OperationError.mjs";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Function to take the user input and encode using the given arguments
|
|
14
|
+
* @param input string of binary
|
|
15
|
+
* @param args array
|
|
16
|
+
*/
|
|
17
|
+
export function calculateParityBit(input, args) {
|
|
18
|
+
let count1s = 0;
|
|
19
|
+
for (let i = 0; i < input.length; i++) {
|
|
20
|
+
const character = input.charAt(i);
|
|
21
|
+
if (character === "1") {
|
|
22
|
+
count1s++;
|
|
23
|
+
} else if (character !== args[3] && character !== "0" && character !== " ") {
|
|
24
|
+
throw new OperationError("unexpected character encountered: \"" + character + "\"");
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
let parityBit = "1";
|
|
28
|
+
const flipflop = args[0] === "Even Parity" ? 0 : 1;
|
|
29
|
+
if (count1s % 2 === flipflop) {
|
|
30
|
+
parityBit = "0";
|
|
31
|
+
}
|
|
32
|
+
if (args[1] === "End") {
|
|
33
|
+
return input + parityBit;
|
|
34
|
+
} else {
|
|
35
|
+
return parityBit + input;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* just removes the parity bit to return the original data
|
|
41
|
+
* @param input string of binary, encoded
|
|
42
|
+
* @param args array
|
|
43
|
+
*/
|
|
44
|
+
export function decodeParityBit(input, args) {
|
|
45
|
+
if (args[1] === "End") {
|
|
46
|
+
return input.slice(0, -1);
|
|
47
|
+
} else {
|
|
48
|
+
return input.slice(1);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @author n1474335 [n1474335@gmail.com]
|
|
3
|
+
* @author ko80240 [csk.dev@proton.me]
|
|
3
4
|
* @copyright Crown Copyright 2023
|
|
4
5
|
* @license Apache-2.0
|
|
5
6
|
*/
|
|
@@ -8,6 +9,7 @@ import * as uuid from "uuid";
|
|
|
8
9
|
|
|
9
10
|
import Operation from "../Operation.mjs";
|
|
10
11
|
import OperationError from "../errors/OperationError.mjs";
|
|
12
|
+
import { toHex } from "../lib/Hex.mjs";
|
|
11
13
|
|
|
12
14
|
/**
|
|
13
15
|
* Analyse UUID operation
|
|
@@ -22,27 +24,128 @@ class AnalyseUUID extends Operation {
|
|
|
22
24
|
|
|
23
25
|
this.name = "Analyse UUID";
|
|
24
26
|
this.module = "Crypto";
|
|
25
|
-
this.description = "
|
|
27
|
+
this.description = "Operation for extracting metadata and detecting the version of a given UUID.";
|
|
26
28
|
this.infoURL = "https://wikipedia.org/wiki/Universally_unique_identifier";
|
|
27
29
|
this.inputType = "string";
|
|
28
30
|
this.outputType = "string";
|
|
29
|
-
this.args = [
|
|
31
|
+
this.args = [
|
|
32
|
+
{
|
|
33
|
+
name: "Include Metadata",
|
|
34
|
+
type: "boolean",
|
|
35
|
+
value: true
|
|
36
|
+
}
|
|
37
|
+
];
|
|
30
38
|
}
|
|
31
39
|
|
|
32
40
|
/**
|
|
33
|
-
* @param {string} input
|
|
41
|
+
* @param {string} input - Expects a valid UUID string
|
|
34
42
|
* @param {Object[]} args
|
|
35
43
|
* @returns {string}
|
|
36
44
|
*/
|
|
37
45
|
run(input, args) {
|
|
46
|
+
input = input.trim();
|
|
47
|
+
|
|
48
|
+
let uuidVersion, uuidBytes;
|
|
38
49
|
try {
|
|
39
|
-
|
|
40
|
-
|
|
50
|
+
uuidVersion = uuid.version(input); // Re-using the uuid library to extract version
|
|
51
|
+
uuidBytes = uuid.parse(input); // Re-using the uuid library to parse bytes
|
|
41
52
|
} catch (error) {
|
|
42
53
|
throw new OperationError("Invalid UUID");
|
|
43
54
|
}
|
|
44
|
-
}
|
|
45
55
|
|
|
56
|
+
const [includeMetadata] = args;
|
|
57
|
+
const dv = new DataView(uuidBytes.buffer, uuidBytes.byteOffset, uuidBytes.byteLength); // Dataview helps handle the multi-byte ints
|
|
58
|
+
const uuidInteger = (dv.getBigUint64(0) << 64n) | dv.getBigUint64(8);
|
|
59
|
+
|
|
60
|
+
const sections = [`Version:\n${uuidVersion}`];
|
|
61
|
+
|
|
62
|
+
if (includeMetadata) {
|
|
63
|
+
const parser = UUID_PARSERS[uuidVersion];
|
|
64
|
+
const decoded = parser?.(uuidBytes, dv);
|
|
65
|
+
sections.push(formatDecoded(decoded));
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
sections.push(`UUID Integer:\n${uuidInteger}`);
|
|
69
|
+
|
|
70
|
+
return sections.filter(Boolean).join("\n\n");
|
|
71
|
+
}
|
|
46
72
|
}
|
|
47
73
|
|
|
48
74
|
export default AnalyseUUID;
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Metadata can be extracted for versions 1, 6, and 7.
|
|
78
|
+
* Enum-like frozen mapping of UUID version to parser function.
|
|
79
|
+
*/
|
|
80
|
+
const UUID_PARSERS = Object.freeze({
|
|
81
|
+
1: parsev1v6,
|
|
82
|
+
6: parsev1v6,
|
|
83
|
+
7: parsev7,
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Versions 1 and 6. Note 6 is a re-order of 1.
|
|
88
|
+
* Version 1 == layout: timeLow(32) | timeMid(16) | timeHi(12)
|
|
89
|
+
* Version 6 == layout: timeHi(32) | timeMid(16) | timeLow(12)
|
|
90
|
+
*/
|
|
91
|
+
function parsev1v6(uuidBytes, dv) {
|
|
92
|
+
const isV1 = (uuidBytes[6] >> 4) === 1;
|
|
93
|
+
|
|
94
|
+
const timeStamp =
|
|
95
|
+
isV1 ? (
|
|
96
|
+
(BigInt(dv.getUint16(6) & 0x0fff) << 48n) | // mask off version bits
|
|
97
|
+
(BigInt(dv.getUint16(4)) << 32n) |
|
|
98
|
+
BigInt(dv.getUint32(0))
|
|
99
|
+
) : (
|
|
100
|
+
(BigInt(dv.getUint32(0)) << 28n) |
|
|
101
|
+
(BigInt(dv.getUint16(4)) << 12n) |
|
|
102
|
+
(BigInt(dv.getUint16(6) & 0x0fff))
|
|
103
|
+
);
|
|
104
|
+
|
|
105
|
+
// Convert to Unix time
|
|
106
|
+
const milliseconds =
|
|
107
|
+
Number(
|
|
108
|
+
(timeStamp - 122192928000000000n) / 10000n
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
return {
|
|
112
|
+
timestamp: milliseconds,
|
|
113
|
+
isoTimestamp: new Date(milliseconds).toISOString(),
|
|
114
|
+
clock: ((uuidBytes[8] & 0x3f) << 8) | uuidBytes[9],
|
|
115
|
+
node: toHex(uuidBytes.slice(10), ":").toUpperCase()
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/** Version 7 */
|
|
120
|
+
function parsev7(uuidBytes, dv) {
|
|
121
|
+
const milliseconds = Number((BigInt(dv.getUint32(0)) << 16n) | BigInt(dv.getUint16(4)));
|
|
122
|
+
|
|
123
|
+
return {
|
|
124
|
+
timestamp: milliseconds,
|
|
125
|
+
isoTimestamp: new Date(milliseconds).toISOString(),
|
|
126
|
+
randA: ((uuidBytes[6] & 0x0f) << 8) | uuidBytes[7],
|
|
127
|
+
randB: toHex(uuidBytes.slice(8), "").toUpperCase()
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Formats metadata
|
|
133
|
+
*
|
|
134
|
+
* @param {Object|undefined} decoded
|
|
135
|
+
* @returns {string}
|
|
136
|
+
*/
|
|
137
|
+
function formatDecoded(decoded) {
|
|
138
|
+
if (!decoded) return "No metadata available. Only versions 1, 6, 7 are supported.";
|
|
139
|
+
|
|
140
|
+
return Object.entries({
|
|
141
|
+
"Timestamp": decoded.timestamp,
|
|
142
|
+
"Timestamp (ISO)": decoded.isoTimestamp,
|
|
143
|
+
"Node": decoded.node,
|
|
144
|
+
"Clock": decoded.clock,
|
|
145
|
+
"Rand A": decoded.randA,
|
|
146
|
+
"Rand B": decoded.randB
|
|
147
|
+
})
|
|
148
|
+
.filter(([, value]) => value !== undefined)
|
|
149
|
+
.map(([label, value]) => `${label}:\n${value}`)
|
|
150
|
+
.join("\n\n");
|
|
151
|
+
}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import Operation from "../Operation.mjs";
|
|
8
|
-
import { search } from "../lib/Extract.mjs";
|
|
8
|
+
import { EMAIL_REGEX, search } from "../lib/Extract.mjs";
|
|
9
9
|
import { caseInsensitiveSort } from "../lib/Sort.mjs";
|
|
10
10
|
|
|
11
11
|
/**
|
|
@@ -50,8 +50,7 @@ class ExtractEmailAddresses extends Operation {
|
|
|
50
50
|
*/
|
|
51
51
|
run(input, args) {
|
|
52
52
|
const [displayTotal, sort, unique] = args,
|
|
53
|
-
|
|
54
|
-
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;
|
|
53
|
+
regex = EMAIL_REGEX;
|
|
55
54
|
|
|
56
55
|
const results = search(
|
|
57
56
|
input,
|