cyberchef 11.2.0 → 11.3.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.
Files changed (134) hide show
  1. package/AGENTS.md +75 -0
  2. package/CHANGELOG.md +147 -1
  3. package/Dockerfile +2 -2
  4. package/Gruntfile.js +1 -0
  5. package/package.json +22 -21
  6. package/src/core/Dish.mjs +1 -5
  7. package/src/core/Ingredient.mjs +92 -0
  8. package/src/core/Operation.mjs +19 -0
  9. package/src/core/Recipe.mjs +4 -0
  10. package/src/core/Utils.mjs +48 -0
  11. package/src/core/config/Categories.json +22 -6
  12. package/src/core/config/OperationConfig.json +4771 -1226
  13. package/src/core/config/modules/Ciphers.mjs +20 -0
  14. package/src/core/config/modules/Crypto.mjs +10 -0
  15. package/src/core/config/modules/Default.mjs +8 -0
  16. package/src/core/config/modules/File.mjs +16 -0
  17. package/src/core/config/modules/OpModules.mjs +2 -0
  18. package/src/core/config/scripts/generateHTMLEntities.mjs +139 -0
  19. package/src/core/config/scripts/htmlEntityOverrides.mjs +86 -0
  20. package/src/core/lib/Arithmetic.mjs +21 -5
  21. package/src/core/lib/BigIntUtils.mjs +0 -1
  22. package/src/core/lib/COBS.mjs +86 -0
  23. package/src/core/lib/Decimal.mjs +5 -5
  24. package/src/core/lib/HTMLEntities.mjs +2068 -0
  25. package/src/core/lib/Present.mjs +422 -0
  26. package/src/core/lib/TEA.mjs +494 -0
  27. package/src/core/lib/TLVParser.mjs +16 -7
  28. package/src/core/lib/Twofish.mjs +608 -0
  29. package/src/core/operations/AsconDecrypt.mjs +112 -0
  30. package/src/core/operations/AsconEncrypt.mjs +108 -0
  31. package/src/core/operations/AsconHash.mjs +49 -0
  32. package/src/core/operations/AsconMAC.mjs +68 -0
  33. package/src/core/operations/AutomatedValidationTestOp.mjs +84 -0
  34. package/src/core/operations/AvroToJSON.mjs +1 -1
  35. package/src/core/operations/BLAKE3.mjs +5 -1
  36. package/src/core/operations/BcryptCompare.mjs +11 -5
  37. package/src/core/operations/BitShiftLeft.mjs +4 -1
  38. package/src/core/operations/Bzip2Compress.mjs +1 -1
  39. package/src/core/operations/DechunkHTTPResponse.mjs +4 -1
  40. package/src/core/operations/ExtendedGCD.mjs +101 -0
  41. package/src/core/operations/FromBase.mjs +2 -1
  42. package/src/core/operations/FromCOBS.mjs +38 -0
  43. package/src/core/operations/FromDecimal.mjs +6 -1
  44. package/src/core/operations/FromHTMLEntity.mjs +2 -1458
  45. package/src/core/operations/GenerateHOTP.mjs +21 -6
  46. package/src/core/operations/GenerateImage.mjs +22 -10
  47. package/src/core/operations/GeneratePrime.mjs +154 -0
  48. package/src/core/operations/GenerateTOTP.mjs +24 -7
  49. package/src/core/operations/Gzip.mjs +1 -3
  50. package/src/core/operations/Jsonata.mjs +12 -0
  51. package/src/core/operations/MIMEDecoding.mjs +1 -1
  52. package/src/core/operations/MOD.mjs +62 -0
  53. package/src/core/operations/ModularInverse.mjs +107 -0
  54. package/src/core/operations/PRESENTDecrypt.mjs +94 -0
  55. package/src/core/operations/PRESENTEncrypt.mjs +94 -0
  56. package/src/core/operations/ParseURI.mjs +18 -5
  57. package/src/core/operations/PseudoRandomNumberGenerator.mjs +2 -1
  58. package/src/core/operations/RandomPrime.mjs +154 -0
  59. package/src/core/operations/RenderPDF.mjs +100 -0
  60. package/src/core/operations/SM4Encrypt.mjs +1 -1
  61. package/src/core/operations/SetDifference.mjs +8 -1
  62. package/src/core/operations/SetIntersection.mjs +8 -1
  63. package/src/core/operations/ShowOnMap.mjs +14 -2
  64. package/src/core/operations/TEADecrypt.mjs +98 -0
  65. package/src/core/operations/TEAEncrypt.mjs +98 -0
  66. package/src/core/operations/ToBase.mjs +4 -4
  67. package/src/core/operations/ToBase32.mjs +20 -4
  68. package/src/core/operations/ToBinary.mjs +4 -1
  69. package/src/core/operations/ToCOBS.mjs +38 -0
  70. package/src/core/operations/ToHTMLEntity.mjs +7 -1430
  71. package/src/core/operations/TwofishDecrypt.mjs +94 -0
  72. package/src/core/operations/TwofishEncrypt.mjs +94 -0
  73. package/src/core/operations/URLEncode.mjs +22 -18
  74. package/src/core/operations/UnescapeUnicodeCharacters.mjs +2 -1
  75. package/src/core/operations/ViewBitPlane.mjs +9 -3
  76. package/src/core/operations/Wrap.mjs +5 -0
  77. package/src/core/operations/XORBruteForce.mjs +4 -1
  78. package/src/core/operations/XORChecksum.mjs +2 -2
  79. package/src/core/operations/XTEADecrypt.mjs +110 -0
  80. package/src/core/operations/XTEAEncrypt.mjs +110 -0
  81. package/src/core/operations/index.mjs +42 -0
  82. package/src/core/vendor/ascon.mjs +162 -0
  83. package/src/core/vendor/htmlEntities/entity.json +2233 -0
  84. package/src/core/vendor/htmlEntities/entity.txt +14 -0
  85. package/src/node/api.mjs +4 -1
  86. package/src/node/index.mjs +105 -0
  87. package/src/web/HTMLOperation.mjs +2 -1
  88. package/src/web/stylesheets/layout/_io.css +8 -0
  89. package/tests/browser/00_nightwatch.js +26 -0
  90. package/tests/browser/02_ops.js +20 -4
  91. package/tests/node/index.mjs +1 -0
  92. package/tests/node/tests/Dish.mjs +19 -0
  93. package/tests/node/tests/NodeDish.mjs +36 -0
  94. package/tests/node/tests/ToHTMLEntity.mjs +82 -0
  95. package/tests/node/tests/Utils.mjs +77 -0
  96. package/tests/node/tests/nodeApi.mjs +33 -1
  97. package/tests/node/tests/operations.mjs +26 -1
  98. package/tests/operations/index.mjs +17 -0
  99. package/tests/operations/tests/Arithmetic.mjs +33 -0
  100. package/tests/operations/tests/Ascon.mjs +501 -0
  101. package/tests/operations/tests/AutomatedValidation.mjs +154 -0
  102. package/tests/operations/tests/BLAKE3.mjs +39 -1
  103. package/tests/operations/tests/Base32.mjs +22 -0
  104. package/tests/operations/tests/COBS.mjs +476 -0
  105. package/tests/operations/tests/CharEnc.mjs +2 -2
  106. package/tests/operations/tests/DechunkHTTPResponse.mjs +66 -0
  107. package/tests/operations/tests/ExtendedGCD.mjs +78 -0
  108. package/tests/operations/tests/FromBase.mjs +66 -0
  109. package/tests/operations/tests/FromDecimal.mjs +55 -0
  110. package/tests/operations/tests/GenerateLoremIpsum.mjs +2 -2
  111. package/tests/operations/tests/Gzip.mjs +60 -0
  112. package/tests/operations/tests/HTMLEntity.mjs +126 -0
  113. package/tests/operations/tests/Hash.mjs +44 -0
  114. package/tests/operations/tests/Hexdump.mjs +1 -1
  115. package/tests/operations/tests/Image.mjs +26 -0
  116. package/tests/operations/tests/Jsonata.mjs +23 -0
  117. package/tests/operations/tests/MIMEDecoding.mjs +33 -0
  118. package/tests/operations/tests/MOD.mjs +208 -0
  119. package/tests/operations/tests/Median.mjs +33 -0
  120. package/tests/operations/tests/ModularInverse.mjs +78 -0
  121. package/tests/operations/tests/OTP.mjs +167 -2
  122. package/tests/operations/tests/PRESENT.mjs +465 -0
  123. package/tests/operations/tests/ParseTLV.mjs +41 -0
  124. package/tests/operations/tests/RenderPDF.mjs +55 -0
  125. package/tests/operations/tests/SM2.mjs +1 -1
  126. package/tests/operations/tests/SetDifference.mjs +22 -0
  127. package/tests/operations/tests/SetIntersection.mjs +23 -1
  128. package/tests/operations/tests/ShowOnMap.mjs +61 -0
  129. package/tests/operations/tests/TEA.mjs +566 -0
  130. package/tests/operations/tests/Twofish.mjs +486 -0
  131. package/tests/operations/tests/URLEncodeDecode.mjs +26 -0
  132. package/tests/operations/tests/UnescapeUnicodeCharacters.mjs +88 -0
  133. package/tests/operations/tests/Wrap.mjs +44 -0
  134. package/webpack.config.js +3 -3
@@ -13,6 +13,8 @@ import AESKeyUnwrap from "../../operations/AESKeyUnwrap.mjs";
13
13
  import AESKeyWrap from "../../operations/AESKeyWrap.mjs";
14
14
  import AffineCipherDecode from "../../operations/AffineCipherDecode.mjs";
15
15
  import AffineCipherEncode from "../../operations/AffineCipherEncode.mjs";
16
+ import AsconDecrypt from "../../operations/AsconDecrypt.mjs";
17
+ import AsconEncrypt from "../../operations/AsconEncrypt.mjs";
16
18
  import AtbashCipher from "../../operations/AtbashCipher.mjs";
17
19
  import BifidCipherDecode from "../../operations/BifidCipherDecode.mjs";
18
20
  import BifidCipherEncode from "../../operations/BifidCipherEncode.mjs";
@@ -37,6 +39,8 @@ import GOSTSign from "../../operations/GOSTSign.mjs";
37
39
  import GOSTVerify from "../../operations/GOSTVerify.mjs";
38
40
  import GenerateECDSAKeyPair from "../../operations/GenerateECDSAKeyPair.mjs";
39
41
  import GenerateRSAKeyPair from "../../operations/GenerateRSAKeyPair.mjs";
42
+ import PRESENTDecrypt from "../../operations/PRESENTDecrypt.mjs";
43
+ import PRESENTEncrypt from "../../operations/PRESENTEncrypt.mjs";
40
44
  import PseudoRandomIntegerGenerator from "../../operations/PseudoRandomIntegerGenerator.mjs";
41
45
  import PseudoRandomNumberGenerator from "../../operations/PseudoRandomNumberGenerator.mjs";
42
46
  import RC2Decrypt from "../../operations/RC2Decrypt.mjs";
@@ -55,11 +59,17 @@ import RailFenceCipherEncode from "../../operations/RailFenceCipherEncode.mjs";
55
59
  import SM4Decrypt from "../../operations/SM4Decrypt.mjs";
56
60
  import SM4Encrypt from "../../operations/SM4Encrypt.mjs";
57
61
  import Salsa20 from "../../operations/Salsa20.mjs";
62
+ import TEADecrypt from "../../operations/TEADecrypt.mjs";
63
+ import TEAEncrypt from "../../operations/TEAEncrypt.mjs";
58
64
  import TripleDESDecrypt from "../../operations/TripleDESDecrypt.mjs";
59
65
  import TripleDESEncrypt from "../../operations/TripleDESEncrypt.mjs";
66
+ import TwofishDecrypt from "../../operations/TwofishDecrypt.mjs";
67
+ import TwofishEncrypt from "../../operations/TwofishEncrypt.mjs";
60
68
  import VigenèreDecode from "../../operations/VigenèreDecode.mjs";
61
69
  import VigenèreEncode from "../../operations/VigenèreEncode.mjs";
62
70
  import XSalsa20 from "../../operations/XSalsa20.mjs";
71
+ import XTEADecrypt from "../../operations/XTEADecrypt.mjs";
72
+ import XTEAEncrypt from "../../operations/XTEAEncrypt.mjs";
63
73
  import XXTEADecrypt from "../../operations/XXTEADecrypt.mjs";
64
74
  import XXTEAEncrypt from "../../operations/XXTEAEncrypt.mjs";
65
75
 
@@ -74,6 +84,8 @@ OpModules.Ciphers = {
74
84
  "AES Key Wrap": AESKeyWrap,
75
85
  "Affine Cipher Decode": AffineCipherDecode,
76
86
  "Affine Cipher Encode": AffineCipherEncode,
87
+ "Ascon Decrypt": AsconDecrypt,
88
+ "Ascon Encrypt": AsconEncrypt,
77
89
  "Atbash Cipher": AtbashCipher,
78
90
  "Bifid Cipher Decode": BifidCipherDecode,
79
91
  "Bifid Cipher Encode": BifidCipherEncode,
@@ -98,6 +110,8 @@ OpModules.Ciphers = {
98
110
  "GOST Verify": GOSTVerify,
99
111
  "Generate ECDSA Key Pair": GenerateECDSAKeyPair,
100
112
  "Generate RSA Key Pair": GenerateRSAKeyPair,
113
+ "PRESENT Decrypt": PRESENTDecrypt,
114
+ "PRESENT Encrypt": PRESENTEncrypt,
101
115
  "Pseudo-Random Integer Generator": PseudoRandomIntegerGenerator,
102
116
  "Pseudo-Random Number Generator": PseudoRandomNumberGenerator,
103
117
  "RC2 Decrypt": RC2Decrypt,
@@ -116,11 +130,17 @@ OpModules.Ciphers = {
116
130
  "SM4 Decrypt": SM4Decrypt,
117
131
  "SM4 Encrypt": SM4Encrypt,
118
132
  "Salsa20": Salsa20,
133
+ "TEA Decrypt": TEADecrypt,
134
+ "TEA Encrypt": TEAEncrypt,
119
135
  "Triple DES Decrypt": TripleDESDecrypt,
120
136
  "Triple DES Encrypt": TripleDESEncrypt,
137
+ "Twofish Decrypt": TwofishDecrypt,
138
+ "Twofish Encrypt": TwofishEncrypt,
121
139
  "Vigenère Decode": VigenèreDecode,
122
140
  "Vigenère Encode": VigenèreEncode,
123
141
  "XSalsa20": XSalsa20,
142
+ "XTEA Decrypt": XTEADecrypt,
143
+ "XTEA Encrypt": XTEAEncrypt,
124
144
  "XXTEA Decrypt": XXTEADecrypt,
125
145
  "XXTEA Encrypt": XXTEAEncrypt,
126
146
  };
@@ -10,6 +10,8 @@ import AnalyseHash from "../../operations/AnalyseHash.mjs";
10
10
  import AnalyseUUID from "../../operations/AnalyseUUID.mjs";
11
11
  import Argon2 from "../../operations/Argon2.mjs";
12
12
  import Argon2Compare from "../../operations/Argon2Compare.mjs";
13
+ import AsconHash from "../../operations/AsconHash.mjs";
14
+ import AsconMAC from "../../operations/AsconMAC.mjs";
13
15
  import Bcrypt from "../../operations/Bcrypt.mjs";
14
16
  import BcryptCompare from "../../operations/BcryptCompare.mjs";
15
17
  import BcryptParse from "../../operations/BcryptParse.mjs";
@@ -20,6 +22,7 @@ import CipherSaber2Encrypt from "../../operations/CipherSaber2Encrypt.mjs";
20
22
  import CompareCTPHHashes from "../../operations/CompareCTPHHashes.mjs";
21
23
  import CompareSSDEEPHashes from "../../operations/CompareSSDEEPHashes.mjs";
22
24
  import DeriveHKDFKey from "../../operations/DeriveHKDFKey.mjs";
25
+ import ExtendedGCD from "../../operations/ExtendedGCD.mjs";
23
26
  import FlaskSessionDecode from "../../operations/FlaskSessionDecode.mjs";
24
27
  import FlaskSessionSign from "../../operations/FlaskSessionSign.mjs";
25
28
  import FlaskSessionVerify from "../../operations/FlaskSessionVerify.mjs";
@@ -29,6 +32,7 @@ import Fletcher64Checksum from "../../operations/Fletcher64Checksum.mjs";
29
32
  import Fletcher8Checksum from "../../operations/Fletcher8Checksum.mjs";
30
33
  import GenerateAllChecksums from "../../operations/GenerateAllChecksums.mjs";
31
34
  import GenerateAllHashes from "../../operations/GenerateAllHashes.mjs";
35
+ import RandomPrime from "../../operations/RandomPrime.mjs";
32
36
  import GenerateUUID from "../../operations/GenerateUUID.mjs";
33
37
  import HAS160 from "../../operations/HAS160.mjs";
34
38
  import HASSHClientFingerprint from "../../operations/HASSHClientFingerprint.mjs";
@@ -49,6 +53,7 @@ import MD2 from "../../operations/MD2.mjs";
49
53
  import MD4 from "../../operations/MD4.mjs";
50
54
  import MD5 from "../../operations/MD5.mjs";
51
55
  import MD6 from "../../operations/MD6.mjs";
56
+ import ModularInverse from "../../operations/ModularInverse.mjs";
52
57
  import NTHash from "../../operations/NTHash.mjs";
53
58
  import RIPEMD from "../../operations/RIPEMD.mjs";
54
59
  import SHA0 from "../../operations/SHA0.mjs";
@@ -74,6 +79,8 @@ OpModules.Crypto = {
74
79
  "Analyse UUID": AnalyseUUID,
75
80
  "Argon2": Argon2,
76
81
  "Argon2 compare": Argon2Compare,
82
+ "Ascon Hash": AsconHash,
83
+ "Ascon MAC": AsconMAC,
77
84
  "Bcrypt": Bcrypt,
78
85
  "Bcrypt compare": BcryptCompare,
79
86
  "Bcrypt parse": BcryptParse,
@@ -84,6 +91,7 @@ OpModules.Crypto = {
84
91
  "Compare CTPH hashes": CompareCTPHHashes,
85
92
  "Compare SSDEEP hashes": CompareSSDEEPHashes,
86
93
  "Derive HKDF key": DeriveHKDFKey,
94
+ "Extended GCD": ExtendedGCD,
87
95
  "Flask Session Decode": FlaskSessionDecode,
88
96
  "Flask Session Sign": FlaskSessionSign,
89
97
  "Flask Session Verify": FlaskSessionVerify,
@@ -93,6 +101,7 @@ OpModules.Crypto = {
93
101
  "Fletcher-8 Checksum": Fletcher8Checksum,
94
102
  "Generate all checksums": GenerateAllChecksums,
95
103
  "Generate all hashes": GenerateAllHashes,
104
+ "Pseudo-Random Prime Generator": RandomPrime,
96
105
  "Generate UUID": GenerateUUID,
97
106
  "HAS-160": HAS160,
98
107
  "HASSH Client Fingerprint": HASSHClientFingerprint,
@@ -113,6 +122,7 @@ OpModules.Crypto = {
113
122
  "MD4": MD4,
114
123
  "MD5": MD5,
115
124
  "MD6": MD6,
125
+ "Modular Inverse": ModularInverse,
116
126
  "NT Hash": NTHash,
117
127
  "RIPEMD": RIPEMD,
118
128
  "SHA0": SHA0,
@@ -9,6 +9,7 @@ import ADD from "../../operations/ADD.mjs";
9
9
  import AND from "../../operations/AND.mjs";
10
10
  import AddLineNumbers from "../../operations/AddLineNumbers.mjs";
11
11
  import AlternatingCaps from "../../operations/AlternatingCaps.mjs";
12
+ import AutomatedValidationTestOp from "../../operations/AutomatedValidationTestOp.mjs";
12
13
  import BaconCipherDecode from "../../operations/BaconCipherDecode.mjs";
13
14
  import BaconCipherEncode from "../../operations/BaconCipherEncode.mjs";
14
15
  import BitShiftLeft from "../../operations/BitShiftLeft.mjs";
@@ -67,6 +68,7 @@ import FromBase92 from "../../operations/FromBase92.mjs";
67
68
  import FromBech32 from "../../operations/FromBech32.mjs";
68
69
  import FromBinary from "../../operations/FromBinary.mjs";
69
70
  import FromBraille from "../../operations/FromBraille.mjs";
71
+ import FromCOBS from "../../operations/FromCOBS.mjs";
70
72
  import FromCaseInsensitiveRegex from "../../operations/FromCaseInsensitiveRegex.mjs";
71
73
  import FromCharcode from "../../operations/FromCharcode.mjs";
72
74
  import FromDecimal from "../../operations/FromDecimal.mjs";
@@ -101,6 +103,7 @@ import Label from "../../operations/Label.mjs";
101
103
  import LevenshteinDistance from "../../operations/LevenshteinDistance.mjs";
102
104
  import LuhnChecksum from "../../operations/LuhnChecksum.mjs";
103
105
  import MIMEDecoding from "../../operations/MIMEDecoding.mjs";
106
+ import MOD from "../../operations/MOD.mjs";
104
107
  import Magic from "../../operations/Magic.mjs";
105
108
  import Mean from "../../operations/Mean.mjs";
106
109
  import Median from "../../operations/Median.mjs";
@@ -186,6 +189,7 @@ import ToBase92 from "../../operations/ToBase92.mjs";
186
189
  import ToBech32 from "../../operations/ToBech32.mjs";
187
190
  import ToBinary from "../../operations/ToBinary.mjs";
188
191
  import ToBraille from "../../operations/ToBraille.mjs";
192
+ import ToCOBS from "../../operations/ToCOBS.mjs";
189
193
  import ToCaseInsensitiveRegex from "../../operations/ToCaseInsensitiveRegex.mjs";
190
194
  import ToCharcode from "../../operations/ToCharcode.mjs";
191
195
  import ToDecimal from "../../operations/ToDecimal.mjs";
@@ -223,6 +227,7 @@ OpModules.Default = {
223
227
  "AND": AND,
224
228
  "Add line numbers": AddLineNumbers,
225
229
  "Alternating Caps": AlternatingCaps,
230
+ "Automated Validation Test Op": AutomatedValidationTestOp,
226
231
  "Bacon Cipher Decode": BaconCipherDecode,
227
232
  "Bacon Cipher Encode": BaconCipherEncode,
228
233
  "Bit shift left": BitShiftLeft,
@@ -281,6 +286,7 @@ OpModules.Default = {
281
286
  "From Bech32": FromBech32,
282
287
  "From Binary": FromBinary,
283
288
  "From Braille": FromBraille,
289
+ "From COBS": FromCOBS,
284
290
  "From Case Insensitive Regex": FromCaseInsensitiveRegex,
285
291
  "From Charcode": FromCharcode,
286
292
  "From Decimal": FromDecimal,
@@ -315,6 +321,7 @@ OpModules.Default = {
315
321
  "Levenshtein Distance": LevenshteinDistance,
316
322
  "Luhn Checksum": LuhnChecksum,
317
323
  "MIME Decoding": MIMEDecoding,
324
+ "MOD": MOD,
318
325
  "Magic": Magic,
319
326
  "Mean": Mean,
320
327
  "Median": Median,
@@ -400,6 +407,7 @@ OpModules.Default = {
400
407
  "To Bech32": ToBech32,
401
408
  "To Binary": ToBinary,
402
409
  "To Braille": ToBraille,
410
+ "To COBS": ToCOBS,
403
411
  "To Case Insensitive Regex": ToCaseInsensitiveRegex,
404
412
  "To Charcode": ToCharcode,
405
413
  "To Decimal": ToDecimal,
@@ -0,0 +1,16 @@
1
+ /**
2
+ * THIS FILE IS AUTOMATICALLY GENERATED BY src/core/config/scripts/generateConfig.mjs
3
+ *
4
+ * @author n1474335 [n1474335@gmail.com]
5
+ * @copyright Crown Copyright 2026
6
+ * @license Apache-2.0
7
+ */
8
+ import RenderPDF from "../../operations/RenderPDF.mjs";
9
+
10
+ const OpModules = typeof self === "undefined" ? {} : self.OpModules || {};
11
+
12
+ OpModules.File = {
13
+ "Render PDF": RenderPDF,
14
+ };
15
+
16
+ export default OpModules;
@@ -28,6 +28,7 @@ import OCRModule from "./OCR.mjs";
28
28
  import URLModule from "./URL.mjs";
29
29
  import UserAgentModule from "./UserAgent.mjs";
30
30
  import ProtobufModule from "./Protobuf.mjs";
31
+ import FileModule from "./File.mjs";
31
32
  import HandlebarsModule from "./Handlebars.mjs";
32
33
  import YaraModule from "./Yara.mjs";
33
34
 
@@ -56,6 +57,7 @@ Object.assign(
56
57
  URLModule,
57
58
  UserAgentModule,
58
59
  ProtobufModule,
60
+ FileModule,
59
61
  HandlebarsModule,
60
62
  YaraModule,
61
63
  );
@@ -0,0 +1,139 @@
1
+ /**
2
+ * This script automatically generates src/core/lib/HTMLEntities.mjs, the shared
3
+ * HTML entity lookup tables used by the "To HTML Entity" and "From HTML Entity"
4
+ * operations.
5
+ *
6
+ * The data is derived from the vendored WHATWG named character reference set
7
+ * (src/core/vendor/htmlEntities/entity.json, from
8
+ * https://html.spec.whatwg.org/entities.json) so the
9
+ * two operations cannot drift apart and every entity is spec-conformant:
10
+ *
11
+ * - HTML_ENTITY_REVERSE_LOOKUP (decode) is every single-code-point spec name.
12
+ * - HTML_ENTITY_LOOKUP (encode) picks one canonical name per code point via a
13
+ * deterministic tiebreak, overridden by htmlEntityOverrides.mjs where a
14
+ * specific historical name is preferred.
15
+ *
16
+ * @author roberson-io [michaelroberson@gmail.com]
17
+ * @copyright Crown Copyright 2026
18
+ * @license Apache-2.0
19
+ */
20
+
21
+ /* eslint no-console: ["off"] */
22
+
23
+ import path from "path";
24
+ import fs from "fs";
25
+ import process from "process";
26
+ import { fileURLToPath } from "url";
27
+ import { HTML_ENTITY_CANONICAL_OVERRIDES } from "./htmlEntityOverrides.mjs";
28
+
29
+ const scriptDir = path.dirname(fileURLToPath(import.meta.url));
30
+
31
+ if (!fs.existsSync(path.join(process.cwd(), "src/core/lib"))) {
32
+ console.log("\nCWD: " + process.cwd());
33
+ console.log("Error: generateHTMLEntities.mjs should be run from the project root");
34
+ console.log("Example> node src/core/config/scripts/generateHTMLEntities.mjs");
35
+ process.exit(1);
36
+ }
37
+
38
+ const SPEC = JSON.parse(fs.readFileSync(
39
+ path.join(scriptDir, "..", "..", "vendor", "htmlEntities", "entity.json"), "utf8"));
40
+
41
+ // Build code point -> [spec names] for single-code-point, semicolon-terminated
42
+ // references (the representable subset; multi-code-point entities are skipped).
43
+ const codePointNames = {};
44
+ for (const [key, val] of Object.entries(SPEC)) {
45
+ if (!key.endsWith(";") || val.codepoints.length !== 1) continue;
46
+ const name = key.slice(1, -1); // strip leading "&" and trailing ";"
47
+ (codePointNames[val.codepoints[0]] ??= []).push(name);
48
+ }
49
+
50
+ // Deterministic canonical-name tiebreak: prefer a lower-case name, then the
51
+ // shortest, then alphabetical. Overridden per code point where a specific
52
+ // historical name is preferred.
53
+ const isAllUpper = s => s === s.toUpperCase() && s !== s.toLowerCase();
54
+
55
+ /**
56
+ * Choose the single canonical entity name for a code point.
57
+ *
58
+ * @param {number} codePoint - the Unicode code point being encoded
59
+ * @param {string[]} names - all valid WHATWG names for that code point
60
+ * @returns {string} the canonical name to emit when encoding
61
+ */
62
+ function canonicalName(codePoint, names) {
63
+ const override = HTML_ENTITY_CANONICAL_OVERRIDES[codePoint];
64
+ if (override !== undefined) {
65
+ if (!names.includes(override))
66
+ throw new Error(`Override &${override}; is not a spec name for code point ${codePoint} (spec: ${names})`);
67
+ return override;
68
+ }
69
+ return [...names].sort((a, b) =>
70
+ (isAllUpper(a) - isAllUpper(b)) ||
71
+ (a.length - b.length) ||
72
+ (a < b ? -1 : a > b ? 1 : 0)
73
+ )[0];
74
+ }
75
+
76
+ const forward = {}; // code point -> canonical name (encode)
77
+ const reverse = {}; // name -> code point (decode, every spec name)
78
+ for (const [cpStr, names] of Object.entries(codePointNames)) {
79
+ const cp = Number(cpStr);
80
+ forward[cp] = canonicalName(cp, names);
81
+ for (const name of names) reverse[name] = cp;
82
+ }
83
+
84
+ // Decode-only aliases = spec names that are not the canonical encode name.
85
+ const aliases = {};
86
+ for (const [name, cp] of Object.entries(reverse)) {
87
+ if (forward[cp] !== name) aliases[name] = cp;
88
+ }
89
+
90
+ // --- emit -----------------------------------------------------------------
91
+ const fwdEntries = Object.keys(forward).map(Number).sort((a, b) => a - b)
92
+ .map(cp => ` ${cp}: "${forward[cp]}",`).join("\n").replace(/,$/, "");
93
+ const aliasEntries = Object.keys(aliases).sort()
94
+ .map(n => ` ${JSON.stringify(n)}: ${aliases[n]},`).join("\n").replace(/,$/, "");
95
+
96
+ const code = `/**
97
+ * THIS FILE IS AUTOMATICALLY GENERATED BY src/core/config/scripts/generateHTMLEntities.mjs
98
+ *
99
+ * HTML entity lookup tables shared by the "To HTML Entity" and "From HTML Entity"
100
+ * operations, derived from the WHATWG named character reference set
101
+ * (https://html.spec.whatwg.org/entities.json). Do not edit by hand — change the
102
+ * vendored src/core/vendor/htmlEntities/entity.json or htmlEntityOverrides.mjs
103
+ * and regenerate.
104
+ *
105
+ * @author roberson-io [michaelroberson@gmail.com]
106
+ * @copyright Crown Copyright ${new Date().getUTCFullYear()}
107
+ * @license Apache-2.0
108
+ */
109
+
110
+ /**
111
+ * Canonical lookup: Unicode code point -> entity name (without "&" and ";"),
112
+ * used for ENCODING. One canonical name per code point.
113
+ */
114
+ export const HTML_ENTITY_LOOKUP = {
115
+ ${fwdEntries}
116
+ };
117
+
118
+ /**
119
+ * Legacy / alias names that only DECODE (spelling variants, deprecated names,
120
+ * box-drawing aliases, etc.); not used for encoding.
121
+ */
122
+ export const HTML_ENTITY_DECODE_ALIASES = {
123
+ ${aliasEntries}
124
+ };
125
+
126
+ /**
127
+ * Derived reverse lookup: entity name -> code point, used for DECODING. Built
128
+ * from the canonical lookup plus the legacy aliases.
129
+ */
130
+ export const HTML_ENTITY_REVERSE_LOOKUP = {...HTML_ENTITY_DECODE_ALIASES};
131
+ for (const codePoint in HTML_ENTITY_LOOKUP) {
132
+ HTML_ENTITY_REVERSE_LOOKUP[HTML_ENTITY_LOOKUP[codePoint]] = Number(codePoint);
133
+ }
134
+ `;
135
+
136
+ fs.writeFileSync(path.join(process.cwd(), "src/core/lib/HTMLEntities.mjs"), code);
137
+ console.log(`generateHTMLEntities: ${Object.keys(forward).length} encode names, ` +
138
+ `${Object.keys(reverse).length} decode names, ${Object.keys(aliases).length} aliases, ` +
139
+ `${Object.keys(HTML_ENTITY_CANONICAL_OVERRIDES).length} overrides applied.`);
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Canonical entity-name overrides for generateHTMLEntities.mjs.
3
+ *
4
+ * The WHATWG named character reference set assigns MANY names to some code
5
+ * points (e.g. U+2211 is both &sum; and &Sum;), but does not designate a
6
+ * canonical one. The generator therefore needs a rule to pick a single name per
7
+ * code point for ENCODING. It uses a deterministic tiebreak (prefer a
8
+ * lower-case name, then the shortest, then alphabetical), which reproduces the
9
+ * historically-emitted name for ~1355 of the ~1414 encodable code points.
10
+ *
11
+ * This file pins the canonical name for the code points where the tiebreak
12
+ * would otherwise change the emitted entity. Every value here is still a valid
13
+ * WHATWG name for that code point (the generator asserts this) — these are
14
+ * editorial choices, not correctness fixes, kept so "To HTML Entity" output
15
+ * stays stable. Trim an entry to let the tiebreak decide instead.
16
+ *
17
+ * @author roberson-io [michaelroberson@gmail.com]
18
+ * @copyright Crown Copyright 2026
19
+ * @license Apache-2.0
20
+ */
21
+
22
+ /**
23
+ * @constant
24
+ * @type {Object.<number, string>}
25
+ */
26
+ export const HTML_ENTITY_CANONICAL_OVERRIDES = {
27
+ 124: "verbar",
28
+ 168: "uml",
29
+ 177: "plusmn",
30
+ 189: "frac12",
31
+ 247: "divide",
32
+ 711: "caron",
33
+ 728: "breve",
34
+ 937: "Omega",
35
+ 949: "epsilon",
36
+ 965: "upsilon",
37
+ 977: "thetasym",
38
+ 978: "upsih",
39
+ 981: "straightphi",
40
+ 8208: "hyphen",
41
+ 8214: "Verbar",
42
+ 8230: "hellip",
43
+ 8289: "ApplyFunction",
44
+ 8290: "InvisibleTimes",
45
+ 8291: "InvisibleComma",
46
+ 8459: "hamilt",
47
+ 8461: "quaternions",
48
+ 8463: "planck",
49
+ 8465: "image",
50
+ 8472: "weierp",
51
+ 8474: "rationals",
52
+ 8476: "real",
53
+ 8477: "reals",
54
+ 8484: "integers",
55
+ 8492: "bernou",
56
+ 8499: "phmmat",
57
+ 8500: "order",
58
+ 8501: "alefsym",
59
+ 8518: "DifferentialD",
60
+ 8519: "ExponentialE",
61
+ 8520: "ImaginaryI",
62
+ 8612: "LeftTeeArrow",
63
+ 8613: "UpTeeArrow",
64
+ 8615: "DownTeeArrow",
65
+ 8624: "lsh",
66
+ 8625: "rsh",
67
+ 8660: "hArr",
68
+ 8704: "forall",
69
+ 8711: "nabla",
70
+ 8712: "isin",
71
+ 8721: "sum",
72
+ 8723: "mnplus",
73
+ 8730: "radic",
74
+ 8750: "conint",
75
+ 8768: "wreath",
76
+ 8776: "asymp",
77
+ 8781: "asympeq",
78
+ 8784: "esdot",
79
+ 8788: "colone",
80
+ 8869: "perp",
81
+ 8896: "xwedge",
82
+ 8897: "xvee",
83
+ 8902: "sstarf",
84
+ 10536: "nesear",
85
+ 10537: "seswar"
86
+ };
@@ -108,19 +108,35 @@ export function mean(data) {
108
108
  * @returns {BigNumber}
109
109
  */
110
110
  export function median(data) {
111
- if ((data.length % 2) === 0 && data.length > 0) {
111
+ if (data.length > 0) {
112
112
  data.sort(function(a, b) {
113
113
  return a.minus(b);
114
114
  });
115
- const first = data[Math.floor(data.length / 2)];
116
- const second = data[Math.floor(data.length / 2) - 1];
117
- return mean([first, second]);
118
- } else {
115
+
116
+ if ((data.length % 2) === 0) {
117
+ const first = data[Math.floor(data.length / 2)];
118
+ const second = data[Math.floor(data.length / 2) - 1];
119
+ return mean([first, second]);
120
+ }
121
+
119
122
  return data[Math.floor(data.length / 2)];
120
123
  }
121
124
  }
122
125
 
123
126
 
127
+ /**
128
+ * Computes modulo of two numbers and returns the value.
129
+ *
130
+ * @param {BigNumber[]} data
131
+ * @returns {BigNumber}
132
+ */
133
+ export function mod(data) {
134
+ if (data.length > 0) {
135
+ return data.reduce((acc, curr) => acc.mod(curr));
136
+ }
137
+ }
138
+
139
+
124
140
  /**
125
141
  * Computes standard deviation of a number array and returns the value.
126
142
  *
@@ -70,4 +70,3 @@ export function modPow(base, exponent, modulus) {
70
70
 
71
71
  return result;
72
72
  }
73
-
@@ -0,0 +1,86 @@
1
+ /**
2
+ * @author Imantas Lukenskas [imantas@lukenskas.dev]
3
+ * @copyright Imantas Lukenskas 2026
4
+ * @license Apache-2.0
5
+ */
6
+
7
+ import OperationError from "../errors/OperationError.mjs";
8
+
9
+ /**
10
+ * COBS-encode a byte array
11
+ * @param {Uint8Array} data
12
+ * @return {Uint8Array}
13
+ */
14
+ export function toCobs(data) {
15
+ if (!data || data.length === 0) {
16
+ return new Uint8Array();
17
+ }
18
+
19
+ const output = [];
20
+ data = [0, ...data];
21
+
22
+ while (data.length > 0) {
23
+ const endIndex = data.findIndex((value, index) => value === 0 && index > 0);
24
+
25
+ if ((endIndex < 0 || endIndex > 254) && data.length > 254) {
26
+ output.push(255);
27
+ output.push(...data.slice(1, 255));
28
+ data = data.slice(255);
29
+ if (data.length !== 0) {
30
+ data = [0, ...data];
31
+ }
32
+ } else if (endIndex < 0) {
33
+ output.push(data.length);
34
+ output.push(...data.slice(1));
35
+ data = [];
36
+ } else {
37
+ output.push(endIndex);
38
+ output.push(...data.slice(1, endIndex));
39
+ data = data.slice(endIndex);
40
+ }
41
+ }
42
+
43
+ return output;
44
+ }
45
+
46
+ /**
47
+ * COBS-decode a byte array
48
+ * @param {Uint8Array} data
49
+ * @return {Uint8Array}
50
+ */
51
+ export function fromCobs(data) {
52
+ if (!data || data.length === 0) {
53
+ return new Uint8Array();
54
+ }
55
+
56
+ if (data.findIndex((value) => value === 0) >= 0) {
57
+ throw new OperationError("Could not decode from COBS: payload must not contain a 0x00 byte");
58
+ }
59
+
60
+ const output = [];
61
+
62
+ while (data.length > 0) {
63
+ if (data[0] === 0xFF) {
64
+ output.push(...data.slice(1, 255));
65
+ data = data.slice(255);
66
+ } else {
67
+ const nextZeroIndex = data[0];
68
+ output.push(...data.slice(1, nextZeroIndex));
69
+ data = data.slice(nextZeroIndex);
70
+
71
+ let blockSize = data[0];
72
+ while (data.length > 0) {
73
+ output.push(0, ...data.slice(1, blockSize));
74
+ data = data.slice(blockSize);
75
+
76
+ if (blockSize === 0xFF) {
77
+ break;
78
+ }
79
+
80
+ blockSize = data[0];
81
+ }
82
+ }
83
+ }
84
+
85
+ return output;
86
+ }
@@ -24,12 +24,12 @@ import Utils from "../Utils.mjs";
24
24
  * fromDecimal("10:20:30", "Colon");
25
25
  */
26
26
  export function fromDecimal(data, delim="Auto") {
27
- delim = Utils.charRep(delim);
28
- const output = [];
29
- let byteStr = data.split(delim);
30
- if (byteStr[byteStr.length-1] === "")
31
- byteStr = byteStr.slice(0, byteStr.length-1);
27
+ const delimRegex = delim === "Auto" ? /[^\d-]+/ : Utils.regexRep(delim);
28
+ let byteStr = data.split(delimRegex);
29
+
30
+ byteStr = byteStr.filter(str => str !== "");
32
31
 
32
+ const output = [];
33
33
  for (let i = 0; i < byteStr.length; i++) {
34
34
  output[i] = parseInt(byteStr[i], 10);
35
35
  }