2
0
mirror of https://github.com/gchq/CyberChef synced 2026-01-06 10:33:18 +00:00

Compare commits

..

35 Commits

Author SHA1 Message Date
n1474335
0fc1c37e65 9.10.0 2019-11-06 12:17:41 +00:00
n1474335
6b4efb420e Updated CHANGELOG 2019-11-06 12:16:35 +00:00
n1474335
9ed2b26933 Tidied up Lorenz operation and created new Bletchley module for WW2-era ciphers 2019-11-06 12:14:22 +00:00
n1474335
70665534b8 Merge branch 'master' of https://github.com/VirtualColossus/CyberChef 2019-11-06 12:00:37 +00:00
n1474335
7244d4d343 9.9.0 2019-11-01 14:57:46 +00:00
n1474335
980c1e8681 Updated CHANGELOG 2019-11-01 14:57:41 +00:00
n1474335
e1378860d6 Added support for 109 more character encodings 2019-11-01 14:56:18 +00:00
VirtualColossus
b9571db9f1 Merge branch 'master' into master 2019-10-31 15:33:54 +00:00
n1474335
734962ac22 9.8.0 2019-10-31 14:21:03 +00:00
n1474335
35103bf155 Updated CHANGELOG 2019-10-31 14:20:55 +00:00
n1474335
4c4d7b5d26 Merge branch 'jarrodconnolly-avro-to-json' 2019-10-31 14:17:55 +00:00
n1474335
daad633195 Tidied up Avro to JSON operation 2019-10-31 14:17:07 +00:00
VirtualColossus
d5cfe9f262 removed duplicate test 2019-10-31 13:54:52 +00:00
n1474335
a2c46b3f66 Merge branch 'avro-to-json' of https://github.com/jarrodconnolly/CyberChef into jarrodconnolly-avro-to-json 2019-10-31 13:54:00 +00:00
n1474335
6a1d11b9b5 Argument hints are not tooltips instead of bmd-help elements 2019-10-31 13:39:06 +00:00
VirtualColossus
c0e02451a1 Fixed bug using KT option, added tests 2019-10-31 07:28:33 +00:00
Jarrod Connolly
2d12a16771 Add Avro to JSON data format conversion 2019-10-30 22:09:42 -07:00
VirtualColossus
ab524fff15 Mixed tabs & spaces 2019-10-29 21:52:18 +00:00
VirtualColossus
55eae9910f Tidied run function, added some tests 2019-10-29 21:39:29 +00:00
VirtualColossus
d3138a7fdf Merge remote-tracking branch 'upstream/master' 2019-10-28 22:23:28 +00:00
Martin Gillow
8ece8ebec2 Updated description 2019-04-01 13:40:53 +01:00
martin gillow
4d39c3bbd2 Fixed code spacing and formatting 2019-03-30 13:42:29 +00:00
martin gillow
23ddb87c9f Fixed code spacing and formatting 2019-03-30 13:02:14 +00:00
martin gillow
db662a7662 Removed debug. Final testing 2019-03-30 10:13:25 +00:00
martin gillow
39f3383709 Renamed option 2019-03-27 20:57:04 +00:00
martin gillow
4f8fc8d65e Fixed p5 limitation 2019-03-27 20:44:57 +00:00
Martin Gillow
0397ba857f Fixed motor wheel movement 2019-03-27 13:02:18 +00:00
martin gillow
444fb4555b Custom wheel settings 2019-03-25 21:10:47 +00:00
martin gillow
294f890a92 Merge branch 'master' of https://github.com/VirtualColossus/CyberChef 2019-03-25 19:47:50 +00:00
martin gillow
578502187d Added custom lug option 2019-03-25 19:37:20 +00:00
Martin Gillow
786082a9d0 Adding Lorenz SZ40/42 operation 2019-03-25 13:43:34 +00:00
Martin Gillow
b6eb851a13 Added Lorenz SZ40/42 operation 2019-03-25 13:34:25 +00:00
Martin Gillow
93c41f044c Added Lorenz SZ40/42 operation 2019-03-25 13:31:13 +00:00
VirtualColossus
a7f61397f7 Added Lorenz SZ40/42 Operation 2019-03-25 13:26:26 +00:00
VirtualColossus
0f5f20247a Added Lorenz SZ40/42 operation 2019-03-25 13:25:13 +00:00
28 changed files with 1229 additions and 2553 deletions

View File

@@ -2,6 +2,15 @@
All major and minor version changes will be documented in this file. Details of patch-level version changes can be found in [commit messages](https://github.com/gchq/CyberChef/commits/master).
### [9.10.0] - 2019-11-06
- 'Lorenz' operation added [@VirtualColossus] | [#528]
### [9.9.0] - 2019-11-01
- Added support for 109 more character encodings [@n1474335]
### [9.8.0] - 2019-10-31
- 'Avro to JSON' operation added [@jarrodconnolly] | [#865]
### [9.7.0] - 2019-09-13
- 'Optical Character Recognition' operation added [@MShwed] [@n1474335] | [#632]
@@ -185,6 +194,9 @@ All major and minor version changes will be documented in this file. Details of
[9.10.0]: https://github.com/gchq/CyberChef/releases/tag/v9.10.0
[9.9.0]: https://github.com/gchq/CyberChef/releases/tag/v9.9.0
[9.8.0]: https://github.com/gchq/CyberChef/releases/tag/v9.8.0
[9.7.0]: https://github.com/gchq/CyberChef/releases/tag/v9.7.0
[9.6.0]: https://github.com/gchq/CyberChef/releases/tag/v9.6.0
[9.5.0]: https://github.com/gchq/CyberChef/releases/tag/v9.5.0
@@ -262,6 +274,8 @@ All major and minor version changes will be documented in this file. Details of
[@Ge0rg3]: https://github.com/Ge0rg3
[@MShwed]: https://github.com/MShwed
[@kassi]: https://github.com/kassi
[@jarrodconnolly]: https://github.com/jarrodconnolly
[@VirtualColossus]: https://github.com/VirtualColossus
[#95]: https://github.com/gchq/CyberChef/pull/299
[#173]: https://github.com/gchq/CyberChef/pull/173
@@ -308,6 +322,7 @@ All major and minor version changes will be documented in this file. Details of
[#515]: https://github.com/gchq/CyberChef/pull/515
[#516]: https://github.com/gchq/CyberChef/pull/516
[#525]: https://github.com/gchq/CyberChef/pull/525
[#528]: https://github.com/gchq/CyberChef/pull/528
[#530]: https://github.com/gchq/CyberChef/pull/530
[#531]: https://github.com/gchq/CyberChef/pull/531
[#533]: https://github.com/gchq/CyberChef/pull/533
@@ -322,3 +337,4 @@ All major and minor version changes will be documented in this file. Details of
[#625]: https://github.com/gchq/CyberChef/pull/625
[#627]: https://github.com/gchq/CyberChef/pull/627
[#632]: https://github.com/gchq/CyberChef/pull/632
[#865]: https://github.com/gchq/CyberChef/pull/865

28
package-lock.json generated
View File

@@ -1,6 +1,6 @@
{
"name": "cyberchef",
"version": "9.7.20",
"version": "9.10.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -2149,6 +2149,11 @@
}
}
},
"avsc": {
"version": "5.4.16",
"resolved": "https://registry.npmjs.org/avsc/-/avsc-5.4.16.tgz",
"integrity": "sha512-Z85B8ZaEU2PWNPRJYuMSp5Hg7Nw3KPKW47lW/Kus7AcwV7fr6uJG3UckagqIPLydIeO/Cm+yjnJG7g0tliICOg=="
},
"aws-sign2": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
@@ -3246,6 +3251,22 @@
"integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
"dev": true
},
"codepage": {
"version": "1.14.0",
"resolved": "https://registry.npmjs.org/codepage/-/codepage-1.14.0.tgz",
"integrity": "sha1-jL4lSBMjVZ19MHVxsP/5HnodL5k=",
"requires": {
"commander": "~2.14.1",
"exit-on-epipe": "~1.0.1"
},
"dependencies": {
"commander": {
"version": "2.14.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.14.1.tgz",
"integrity": "sha512-+YR16o3rK53SmWHU3rEM3tPAh2rwb1yPcQX5irVn7mb0gXbwuCCrnkbV5+PBfETdfg1vui07nM6PCG1zndcjQw=="
}
}
},
"coffeescript": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/coffeescript/-/coffeescript-1.10.0.tgz",
@@ -5326,6 +5347,11 @@
"integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=",
"dev": true
},
"exit-on-epipe": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz",
"integrity": "sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw=="
},
"expand-brackets": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",

View File

@@ -1,6 +1,6 @@
{
"name": "cyberchef",
"version": "9.7.20",
"version": "9.10.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",
@@ -86,6 +86,7 @@
"@babel/polyfill": "^7.4.4",
"@babel/runtime": "^7.5.5",
"arrive": "^2.4.1",
"avsc": "^5.4.16",
"babel-plugin-transform-builtin-extend": "1.1.2",
"bcryptjs": "^2.4.3",
"bignumber.js": "^9.0.0",
@@ -95,6 +96,7 @@
"bootstrap-material-design": "^4.1.2",
"bson": "^4.0.2",
"chi-squared": "^1.1.0",
"codepage": "^1.14.0",
"core-js": "^3.2.1",
"crypto-api": "^0.8.5",
"crypto-js": "^3.1.9-1",

View File

@@ -59,7 +59,8 @@
"From Braille",
"Parse TLV",
"CSV to JSON",
"JSON to CSV"
"JSON to CSV",
"Avro to JSON"
]
},
{
@@ -108,7 +109,8 @@
"Enigma",
"Bombe",
"Multiple Bombe",
"Typex"
"Typex",
"Lorenz"
]
},
{

View File

@@ -12,16 +12,65 @@
export const IO_FORMAT = {
"UTF-8 (65001)": 65001,
"UTF-7 (65000)": 65000,
"UTF16LE (1200)": 1200,
"UTF16BE (1201)": 1201,
"UTF16 (1201)": 1201,
"UTF-16LE (1200)": 1200,
"UTF-16BE (1201)": 1201,
"UTF-32LE (12000)": 12000,
"UTF-32BE (12001)": 12001,
"IBM EBCDIC International (500)": 500,
"IBM EBCDIC US-Canada (37)": 37,
"IBM EBCDIC Multilingual/ROECE (Latin 2) (870)": 870,
"IBM EBCDIC Greek Modern (875)": 875,
"IBM EBCDIC French (1010)": 1010,
"IBM EBCDIC Turkish (Latin 5) (1026)": 1026,
"IBM EBCDIC Latin 1/Open System (1047)": 1047,
"IBM EBCDIC Lao (1132/1133/1341)": 1132,
"IBM EBCDIC US-Canada (037 + Euro symbol) (1140)": 1140,
"IBM EBCDIC Germany (20273 + Euro symbol) (1141)": 1141,
"IBM EBCDIC Denmark-Norway (20277 + Euro symbol) (1142)": 1142,
"IBM EBCDIC Finland-Sweden (20278 + Euro symbol) (1143)": 1143,
"IBM EBCDIC Italy (20280 + Euro symbol) (1144)": 1144,
"IBM EBCDIC Latin America-Spain (20284 + Euro symbol) (1145)": 1145,
"IBM EBCDIC United Kingdom (20285 + Euro symbol) (1146)": 1146,
"IBM EBCDIC France (20297 + Euro symbol) (1147)": 1147,
"IBM EBCDIC International (500 + Euro symbol) (1148)": 1148,
"IBM EBCDIC Icelandic (20871 + Euro symbol) (1149)": 1149,
"IBM EBCDIC Germany (20273)": 20273,
"IBM EBCDIC Denmark-Norway (20277)": 20277,
"IBM EBCDIC Finland-Sweden (20278)": 20278,
"IBM EBCDIC Italy (20280)": 20280,
"IBM EBCDIC Latin America-Spain (20284)": 20284,
"IBM EBCDIC United Kingdom (20285)": 20285,
"IBM EBCDIC Japanese Katakana Extended (20290)": 20290,
"IBM EBCDIC France (20297)": 20297,
"IBM EBCDIC Arabic (20420)": 20420,
"IBM EBCDIC Greek (20423)": 20423,
"IBM EBCDIC Hebrew (20424)": 20424,
"IBM EBCDIC Korean Extended (20833)": 20833,
"IBM EBCDIC Thai (20838)": 20838,
"IBM EBCDIC Icelandic (20871)": 20871,
"IBM EBCDIC Cyrillic Russian (20880)": 20880,
"IBM EBCDIC Turkish (20905)": 20905,
"IBM EBCDIC Latin 1/Open System (1047 + Euro symbol) (20924)": 20924,
"IBM EBCDIC Cyrillic Serbian-Bulgarian (21025)": 21025,
"OEM United States (437)": 437,
"OEM Greek (formerly 437G); Greek (DOS) (737)": 737,
"OEM Baltic; Baltic (DOS) (775)": 775,
"OEM Russian; Cyrillic + Euro symbol (808)": 808,
"OEM Multilingual Latin 1; Western European (DOS) (850)": 850,
"OEM Latin 2; Central European (DOS) (852)": 852,
"OEM Cyrillic (primarily Russian) (855)": 855,
"OEM Turkish; Turkish (DOS) (857)": 857,
"OEM Multilingual Latin 1 + Euro symbol (858)": 858,
"OEM Portuguese; Portuguese (DOS) (860)": 860,
"OEM Icelandic; Icelandic (DOS) (861)": 861,
"OEM Hebrew; Hebrew (DOS) (862)": 862,
"OEM French Canadian; French Canadian (DOS) (863)": 863,
"OEM Arabic; Arabic (864) (864)": 864,
"OEM Nordic; Nordic (DOS) (865)": 865,
"OEM Russian; Cyrillic (DOS) (866)": 866,
"OEM Modern Greek; Greek, Modern (DOS) (869)": 869,
"OEM Cyrillic (primarily Russian) + Euro Symbol (872)": 872,
"Windows-874 Thai (874)": 874,
"Japanese Shift-JIS (932)": 932,
"Simplified Chinese GBK (936)": 936,
"Korean (949)": 949,
"Traditional Chinese Big5 (950)": 950,
"Windows-1250 Central European (1250)": 1250,
"Windows-1251 Cyrillic (1251)": 1251,
"Windows-1252 Latin (1252)": 1252,
@@ -31,10 +80,6 @@ export const IO_FORMAT = {
"Windows-1256 Arabic (1256)": 1256,
"Windows-1257 Baltic (1257)": 1257,
"Windows-1258 Vietnam (1258)": 1258,
"US-ASCII (20127)": 20127,
"Simplified Chinese GB2312 (20936)": 20936,
"KOI8-R Russian Cyrillic (20866)": 20866,
"KOI8-U Ukrainian Cyrillic (21866)": 21866,
"ISO-8859-1 Latin 1 Western European (28591)": 28591,
"ISO-8859-2 Latin 2 Central European (28592)": 28592,
"ISO-8859-3 Latin 3 South European (28593)": 28593,
@@ -43,6 +88,7 @@ export const IO_FORMAT = {
"ISO-8859-6 Latin/Arabic (28596)": 28596,
"ISO-8859-7 Latin/Greek (28597)": 28597,
"ISO-8859-8 Latin/Hebrew (28598)": 28598,
"ISO 8859-8 Hebrew (ISO-Logical) (38598)": 38598,
"ISO-8859-9 Latin 5 Turkish (28599)": 28599,
"ISO-8859-10 Latin 6 Nordic (28600)": 28600,
"ISO-8859-11 Latin/Thai (28601)": 28601,
@@ -50,9 +96,71 @@ export const IO_FORMAT = {
"ISO-8859-14 Latin 8 Celtic (28604)": 28604,
"ISO-8859-15 Latin 9 (28605)": 28605,
"ISO-8859-16 Latin 10 (28606)": 28606,
"ISO-2022 JIS Japanese (50222)": 50222,
"ISO 2022 JIS Japanese with no halfwidth Katakana (50220)": 50220,
"ISO 2022 JIS Japanese with halfwidth Katakana (50221)": 50221,
"ISO 2022 Japanese JIS X 0201-1989 (1 byte Kana-SO/SI) (50222)": 50222,
"ISO 2022 Korean (50225)": 50225,
"ISO 2022 Simplified Chinese (50227)": 50227,
"ISO 6937 Non-Spacing Accent (20269)": 20269,
"EUC Japanese (51932)": 51932,
"EUC Simplified Chinese (51936)": 51936,
"EUC Korean (51949)": 51949,
"ISCII Devanagari (57002)": 57002,
"ISCII Bengali (57003)": 57003,
"ISCII Tamil (57004)": 57004,
"ISCII Telugu (57005)": 57005,
"ISCII Assamese (57006)": 57006,
"ISCII Oriya (57007)": 57007,
"ISCII Kannada (57008)": 57008,
"ISCII Malayalam (57009)": 57009,
"ISCII Gujarati (57010)": 57010,
"ISCII Punjabi (57011)": 57011,
"Japanese Shift-JIS (932)": 932,
"Simplified Chinese GBK (936)": 936,
"Korean (949)": 949,
"Traditional Chinese Big5 (950)": 950,
"US-ASCII (7-bit) (20127)": 20127,
"Simplified Chinese GB2312 (20936)": 20936,
"KOI8-R Russian Cyrillic (20866)": 20866,
"KOI8-U Ukrainian Cyrillic (21866)": 21866,
"Mazovia (Polish) MS-DOS (620)": 620,
"Arabic (ASMO 708) (708)": 708,
"Arabic (Transparent ASMO); Arabic (DOS) (720)": 720,
"Kamenický (Czech) MS-DOS (895)": 895,
"Korean (Johab) (1361)": 1361,
"MAC Roman (10000)": 10000,
"Japanese (Mac) (10001)": 10001,
"MAC Traditional Chinese (Big5) (10002)": 10002,
"Korean (Mac) (10003)": 10003,
"Arabic (Mac) (10004)": 10004,
"Hebrew (Mac) (10005)": 10005,
"Greek (Mac) (10006)": 10006,
"Cyrillic (Mac) (10007)": 10007,
"MAC Simplified Chinese (GB 2312) (10008)": 10008,
"Romanian (Mac) (10010)": 10010,
"Ukrainian (Mac) (10017)": 10017,
"Thai (Mac) (10021)": 10021,
"MAC Latin 2 (Central European) (10029)": 10029,
"Icelandic (Mac) (10079)": 10079,
"Turkish (Mac) (10081)": 10081,
"Croatian (Mac) (10082)": 10082,
"CNS Taiwan (Chinese Traditional) (20000)": 20000,
"TCA Taiwan (20001)": 20001,
"ETEN Taiwan (Chinese Traditional) (20002)": 20002,
"IBM5550 Taiwan (20003)": 20003,
"TeleText Taiwan (20004)": 20004,
"Wang Taiwan (20005)": 20005,
"Western European IA5 (IRV International Alphabet 5) (20105)": 20105,
"IA5 German (7-bit) (20106)": 20106,
"IA5 Swedish (7-bit) (20107)": 20107,
"IA5 Norwegian (7-bit) (20108)": 20108,
"T.61 (20261)": 20261,
"Japanese (JIS 0208-1990 and 0212-1990) (20932)": 20932,
"Korean Wansung (20949)": 20949,
"Extended/Ext Alpha Lowercase (21027)": 21027,
"Europa 3 (29001)": 29001,
"Atari ST/TT (47451)": 47451,
"HZ-GB2312 Simplified Chinese (52936)": 52936,
"Simplified Chinese GB18030 (54936)": 54936,
};

View File

@@ -0,0 +1,76 @@
/**
* @author jarrodconnolly [jarrod@nestedquotes.ca]
* @copyright Crown Copyright 2019
* @license Apache-2.0
*/
import Operation from "../Operation.mjs";
import OperationError from "../errors/OperationError.mjs";
import avro from "avsc";
/**
* Avro to JSON operation
*/
class AvroToJSON extends Operation {
/**
* AvroToJSON constructor
*/
constructor() {
super();
this.name = "Avro to JSON";
this.module = "Serialise";
this.description = "Converts Avro encoded data into JSON.";
this.infoURL = "https://wikipedia.org/wiki/Apache_Avro";
this.inputType = "ArrayBuffer";
this.outputType = "string";
this.args = [
{
name: "Force Valid JSON",
type: "boolean",
value: true
}
];
}
/**
* @param {ArrayBuffer} input
* @param {Object[]} args
* @returns {string}
*/
run(input, args) {
if (input.byteLength <= 0) {
throw new OperationError("Please provide an input.");
}
const forceJSON = args[0];
return new Promise((resolve, reject) => {
const result = [];
const inpArray = new Uint8Array(input);
const decoder = new avro.streams.BlockDecoder();
decoder
.on("data", function (obj) {
result.push(obj);
})
.on("error", function () {
reject(new OperationError("Error parsing Avro file."));
})
.on("end", function () {
if (forceJSON) {
resolve(result.length === 1 ? JSON.stringify(result[0], null, 4) : JSON.stringify(result, null, 4));
} else {
const data = result.reduce((result, current) => result + JSON.stringify(current) + "\n", "");
resolve(data);
}
});
decoder.write(inpArray);
decoder.end();
});
}
}
export default AvroToJSON;

View File

@@ -20,7 +20,7 @@ class BSONDeserialise extends Operation {
super();
this.name = "BSON deserialise";
this.module = "BSON";
this.module = "Serialise";
this.description = "BSON is a computer data interchange format used mainly as a data storage and network transfer format in the MongoDB database. It is a binary form for representing simple data structures, associative arrays (called objects or documents in MongoDB), and various data types of specific interest to MongoDB. The name 'BSON' is based on the term JSON and stands for 'Binary JSON'.<br><br>Input data should be in a raw bytes format.";
this.infoURL = "https://wikipedia.org/wiki/BSON";
this.inputType = "ArrayBuffer";

View File

@@ -20,7 +20,7 @@ class BSONSerialise extends Operation {
super();
this.name = "BSON serialise";
this.module = "BSON";
this.module = "Serialise";
this.description = "BSON is a computer data interchange format used mainly as a data storage and network transfer format in the MongoDB database. It is a binary form for representing simple data structures, associative arrays (called objects or documents in MongoDB), and various data types of specific interest to MongoDB. The name 'BSON' is based on the term JSON and stands for 'Binary JSON'.<br><br>Input data should be valid JSON.";
this.infoURL = "https://wikipedia.org/wiki/BSON";
this.inputType = "string";

View File

@@ -23,7 +23,7 @@ class Bombe extends Operation {
super();
this.name = "Bombe";
this.module = "Default";
this.module = "Bletchley";
this.description = "Emulation of the Bombe machine used at Bletchley Park to attack Enigma, based on work by Polish and British cryptanalysts.<br><br>To run this you need to have a 'crib', which is some known plaintext for a chunk of the target ciphertext, and know the rotors used. (See the 'Bombe (multiple runs)' operation if you don't know the rotors.) The machine will suggest possible configurations of the Enigma. Each suggestion has the rotor start positions (left to right) and known plugboard pairs.<br><br>Choosing a crib: First, note that Enigma cannot encrypt a letter to itself, which allows you to rule out some positions for possible cribs. Secondly, the Bombe does not simulate the Enigma's middle rotor stepping. The longer your crib, the more likely a step happened within it, which will prevent the attack working. However, other than that, longer cribs are generally better. The attack produces a 'menu' which maps ciphertext letters to plaintext, and the goal is to produce 'loops': for example, with ciphertext ABC and crib CAB, we have the mappings A&lt;-&gt;C, B&lt;-&gt;A, and C&lt;-&gt;B, which produces a loop A-B-C-A. The more loops, the better the crib. The operation will output this: if your menu has too few loops or is too short, a large number of incorrect outputs will usually be produced. Try a different crib. If the menu seems good but the right answer isn't produced, your crib may be wrong, or you may have overlapped the middle rotor stepping - try a different crib.<br><br>Output is not sufficient to fully decrypt the data. You will have to recover the rest of the plugboard settings by inspection. And the ring position is not taken into account: this affects when the middle rotor steps. If your output is correct for a bit, and then goes wrong, adjust the ring and start position on the right-hand rotor together until the output improves. If necessary, repeat for the middle rotor.<br><br>By default this operation runs the checking machine, a manual process to verify the quality of Bombe stops, on each stop, discarding stops which fail. If you want to see how many times the hardware actually stops for a given input, disable the checking machine.<br><br>More detailed descriptions of the Enigma, Typex and Bombe operations <a href='https://github.com/gchq/CyberChef/wiki/Enigma,-the-Bombe,-and-Typex'>can be found here</a>.";
this.infoURL = "https://wikipedia.org/wiki/Bombe";
this.inputType = "string";

View File

@@ -6,7 +6,7 @@
import Operation from "../Operation.mjs";
import OperationError from "../errors/OperationError.mjs";
import cptable from "../vendor/js-codepage/cptable.js";
import cptable from "codepage";
/**
* Citrix CTX1 Decode operation

View File

@@ -5,7 +5,7 @@
*/
import Operation from "../Operation.mjs";
import cptable from "../vendor/js-codepage/cptable.js";
import cptable from "codepage";
/**
* Citrix CTX1 Encode operation

View File

@@ -5,7 +5,7 @@
*/
import Operation from "../Operation.mjs";
import cptable from "../vendor/js-codepage/cptable.js";
import cptable from "codepage";
import {IO_FORMAT} from "../lib/ChrEnc.mjs";
/**

View File

@@ -5,7 +5,7 @@
*/
import Operation from "../Operation.mjs";
import cptable from "../vendor/js-codepage/cptable.js";
import cptable from "codepage";
import {IO_FORMAT} from "../lib/ChrEnc.mjs";
/**

View File

@@ -21,7 +21,7 @@ class Enigma extends Operation {
super();
this.name = "Enigma";
this.module = "Default";
this.module = "Bletchley";
this.description = "Encipher/decipher with the WW2 Enigma machine.<br><br>Enigma was used by the German military, among others, around the WW2 era as a portable cipher machine to protect sensitive military, diplomatic and commercial communications.<br><br>The standard set of German military rotors and reflectors are provided. To configure the plugboard, enter a string of connected pairs of letters, e.g. <code>AB CD EF</code> connects A to B, C to D, and E to F. This is also used to create your own reflectors. To create your own rotor, enter the letters that the rotor maps A to Z to, in order, optionally followed by <code>&lt;</code> then a list of stepping points.<br>This is deliberately fairly permissive with rotor placements etc compared to a real Enigma (on which, for example, a four-rotor Enigma uses only the thin reflectors and the beta or gamma rotor in the 4th slot).<br><br>More detailed descriptions of the Enigma, Typex and Bombe operations <a href='https://github.com/gchq/CyberChef/wiki/Enigma,-the-Bombe,-and-Typex'>can be found here</a>.";
this.infoURL = "https://wikipedia.org/wiki/Enigma_machine";
this.inputType = "string";

View File

@@ -0,0 +1,759 @@
/**
* Emulation of the Lorenz SZ40/42a/42b cipher attachment.
*
* @author VirtualColossus [martin@virtualcolossus.co.uk]
* @copyright Crown Copyright 2019
* @license Apache-2.0
*/
import Operation from "../Operation";
import OperationError from "../errors/OperationError";
/**
* Lorenz operation
*/
class Lorenz extends Operation {
/**
* Lorenz constructor
*/
constructor() {
super();
this.name = "Lorenz";
this.module = "Bletchley";
this.description = "The Lorenz SZ40/42 cipher attachment was a WW2 German rotor cipher machine with twelve rotors which attached in-line between remote teleprinters.<br><br>It used the Vernam cipher with two groups of five rotors (named the psi(ψ) wheels and chi(χ) wheels at Bletchley Park) to create two pseudorandom streams of five bits, encoded in ITA2, which were XOR added to the plaintext. Two other rotors, dubbed the mu(μ) or motor wheels, could hold up the stepping of the psi wheels meaning they stepped intermittently.<br><br>Each rotor has a different number of cams/lugs around their circumference which could be set active or inactive changing the key stream.<br><br>Three models of the Lorenz are emulated, SZ40, SZ42a and SZ42b and three example wheel patterns (the lug settings) are included (KH, ZMUG & BREAM) with the option to set a custom set using the letter 'x' for active or '.' for an inactive lug.<br><br>The input can either be plaintext or ITA2 when sending and ITA2 when receiving.<br><br>To learn more, Virtual Lorenz, an online, browser based simulation of the Lorenz SZ40/42 is available at <a href='https://lorenz.virtualcolossus.co.uk' target='_blank'>https://lorenz.virtualcolossus.co.uk</a>.";
this.infoURL = "https://wikipedia.org/wiki/Lorenz_cipher";
this.inputType = "string";
this.outputType = "string";
this.args = [
{
name: "Model",
type: "option",
value: ["SZ40", "SZ42a", "SZ42b"]
},
{
name: "Wheel Pattern",
type: "argSelector",
value: [
{
name: "KH Pattern",
off: [19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]
},
{
name: "ZMUG Pattern",
off: [19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]
},
{
name: "BREAM Pattern",
off: [19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]
},
{
name: "No Pattern",
off: [19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]
},
{
name: "Custom",
on: [19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]
}
]
},
{
name: "KT-Schalter",
type: "boolean"
},
{
name: "Mode",
type: "argSelector",
value: [
{
name: "Send",
on: [4],
off: [5]
},
{
name: "Receive",
off: [4],
on: [5]
}
]
},
{
name: "Input Type",
type: "option",
value: ["Plaintext", "ITA2"]
},
{
name: "Output Type",
type: "option",
value: ["Plaintext", "ITA2"]
},
{
name: "ITA2 Format",
type: "option",
value: ["5/8/9", "+/-/."]
},
{
name: "Ψ1 start (1-43)",
type: "number",
value: 1
},
{
name: "Ψ2 start (1-47)",
type: "number",
value: 1
},
{
name: "Ψ3 start (1-51)",
type: "number",
value: 1
},
{
name: "Ψ4 start (1-53)",
type: "number",
value: 1
},
{
name: "Ψ5 start (1-59)",
type: "number",
value: 1
},
{
name: "Μ37 start (1-37)",
type: "number",
value: 1
},
{
name: "Μ61 start (1-61)",
type: "number",
value: 1
},
{
name: "Χ1 start (1-41)",
type: "number",
value: 1
},
{
name: "Χ2 start (1-31)",
type: "number",
value: 1
},
{
name: "Χ3 start (1-29)",
type: "number",
value: 1
},
{
name: "Χ4 start (1-26)",
type: "number",
value: 1
},
{
name: "Χ5 start (1-23)",
type: "number",
value: 1
},
{
name: "Ψ1 lugs (43)",
type: "string",
value: ".x...xx.x.x..xxx.x.x.xxxx.x.x.x.x.x..x.xx.x"
},
{
name: "Ψ2 lugs (47)",
type: "string",
value: ".xx.x.xxx..x.x.x..x.xx.x.xxx.x....x.xx.x.x.x..x"
},
{
name: "Ψ3 lugs (51)",
type: "string",
value: ".x.x.x..xxx....x.x.xx.x.x.x..xxx.x.x..x.x.xx..x.x.x"
},
{
name: "Ψ4 lugs (53)",
type: "string",
value: ".xx...xxxxx.x.x.xx...x.xx.x.x..x.x.xx.x..x.x.x.x.x.x."
},
{
name: "Ψ5 lugs (59)",
type: "string",
value: "xx...xx.x..x.xx.x...x.x.x.x.x.x.x.x.xx..xxxx.x.x...xx.x..x."
},
{
name: "Μ37 lugs (37)",
type: "string",
value: "x.x.x.x.x.x...x.x.x...x.x.x...x.x...."
},
{
name: "Μ61 lugs (61)",
type: "string",
value: ".xxxx.xxxx.xxx.xxxx.xx....xxx.xxxx.xxxx.xxxx.xxxx.xxx.xxxx..."
},
{
name: "Χ1 lugs (41)",
type: "string",
value: ".x...xxx.x.xxxx.x...x.x..xxx....xx.xxxx.."
},
{
name: "Χ2 lugs (31)",
type: "string",
value: "x..xxx...x.xxxx..xx..x..xx.xx.."
},
{
name: "Χ3 lugs (29)",
type: "string",
value: "..xx..x.xxx...xx...xx..xx.xx."
},
{
name: "Χ4 lugs (26)",
type: "string",
value: "xx..x..xxxx..xx.xxx....x.."
},
{
name: "Χ5 lugs (23)",
type: "string",
value: "xx..xx....xxxx.x..x.x.."
}
];
}
/**
* @param {string} input
* @param {Object[]} args
* @returns {string}
*/
run(input, args) {
const model = args[0],
pattern = args[1],
kt = args[2],
mode = args[3],
intype = args[4],
outtype = args[5],
format = args[6],
lugs1 = args[19],
lugs2 = args[20],
lugs3 = args[21],
lugs4 = args[22],
lugs5 = args[23],
lugm37 = args[24],
lugm61 = args[25],
lugx1 = args[26],
lugx2 = args[27],
lugx3 = args[28],
lugx4 = args[29],
lugx5 = args[30];
let s1 = args[7],
s2 = args[8],
s3 = args[9],
s4 = args[10],
s5 = args[11],
m37 = args[12],
m61 = args[13],
x1 = args[14],
x2 = args[15],
x3 = args[16],
x4 = args[17],
x5 = args[18];
this.reverseTable();
if (s1<1 || s1>43) throw new OperationError("Ψ1 start must be between 1 and 43");
if (s2<1 || s2>47) throw new OperationError("Ψ2 start must be between 1 and 47");
if (s3<1 || s3>51) throw new OperationError("Ψ3 start must be between 1 and 51");
if (s4<1 || s4>53) throw new OperationError("Ψ4 start must be between 1 and 53");
if (s5<1 || s5>59) throw new OperationError("Ψ5 start must be between 1 and 59");
if (m37<1 || m37>37) throw new OperationError("Μ37 start must be between 1 and 37");
if (m61<1 || m61>61) throw new OperationError("Μ61 start must be between 1 and 61");
if (x1<1 || x1>41) throw new OperationError("Χ1 start must be between 1 and 41");
if (x2<1 || x2>31) throw new OperationError("Χ2 start must be between 1 and 31");
if (x3<1 || x3>29) throw new OperationError("Χ3 start must be between 1 and 29");
if (x4<1 || x4>26) throw new OperationError("Χ4 start must be between 1 and 26");
if (x5<1 || x5>23) throw new OperationError("Χ5 start must be between 1 and 23");
// Initialise chosen wheel pattern
let chosenSetting = "";
if (pattern === "Custom") {
const re = new RegExp("^[.xX]*$");
if (lugs1.length !== 43 || !re.test(lugs1)) throw new OperationError("Ψ1 custom lugs must be 43 long and can only include . or x ");
if (lugs2.length !== 47 || !re.test(lugs2)) throw new OperationError("Ψ2 custom lugs must be 47 long and can only include . or x");
if (lugs3.length !== 51 || !re.test(lugs3)) throw new OperationError("Ψ3 custom lugs must be 51 long and can only include . or x");
if (lugs4.length !== 53 || !re.test(lugs4)) throw new OperationError("Ψ4 custom lugs must be 53 long and can only include . or x");
if (lugs5.length !== 59 || !re.test(lugs5)) throw new OperationError("Ψ5 custom lugs must be 59 long and can only include . or x");
if (lugm37.length !== 37 || !re.test(lugm37)) throw new OperationError("M37 custom lugs must be 37 long and can only include . or x");
if (lugm61.length !== 61 || !re.test(lugm61)) throw new OperationError("M61 custom lugs must be 61 long and can only include . or x");
if (lugx1.length !== 41 || !re.test(lugx1)) throw new OperationError("Χ1 custom lugs must be 41 long and can only include . or x");
if (lugx2.length !== 31 || !re.test(lugx2)) throw new OperationError("Χ2 custom lugs must be 31 long and can only include . or x");
if (lugx3.length !== 29 || !re.test(lugx3)) throw new OperationError("Χ3 custom lugs must be 29 long and can only include . or x");
if (lugx4.length !== 26 || !re.test(lugx4)) throw new OperationError("Χ4 custom lugs must be 26 long and can only include . or x");
if (lugx5.length !== 23 || !re.test(lugx5)) throw new OperationError("Χ5 custom lugs must be 23 long and can only include . or x");
chosenSetting = INIT_PATTERNS["No Pattern"];
chosenSetting.S[1] = this.readLugs(lugs1);
chosenSetting.S[2] = this.readLugs(lugs2);
chosenSetting.S[3] = this.readLugs(lugs3);
chosenSetting.S[4] = this.readLugs(lugs4);
chosenSetting.S[5] = this.readLugs(lugs5);
chosenSetting.M[1] = this.readLugs(lugm37);
chosenSetting.M[2] = this.readLugs(lugm61);
chosenSetting.X[1] = this.readLugs(lugx1);
chosenSetting.X[2] = this.readLugs(lugx2);
chosenSetting.X[3] = this.readLugs(lugx3);
chosenSetting.X[4] = this.readLugs(lugx4);
chosenSetting.X[5] = this.readLugs(lugx5);
} else {
chosenSetting = INIT_PATTERNS[pattern];
}
const chiSettings = chosenSetting.X; // Pin settings for Chi links (X)
const psiSettings = chosenSetting.S; // Pin settings for Psi links (S)
const muSettings = chosenSetting.M; // Pin settings for Motor links (M)
// Convert input text to ITA2 (including figure/letter shifts)
const ita2Input = this.convertToITA2(input, intype, mode);
let thisPsi = [];
let thisChi = [];
let m61lug = muSettings[1][m61-1];
let m37lug = muSettings[2][m37-1];
const p5 = [0, 0, 0];
const self = this;
const letters = Array.prototype.map.call(ita2Input, function(character) {
const letter = character.toUpperCase();
// Store lugs used in limitations, need these later
let x2bptr = x2+1;
if (x2bptr===32) x2bptr=1;
let s1bptr = s1+1;
if (s1bptr===44) s1bptr=1;
thisChi = [
chiSettings[1][x1-1],
chiSettings[2][x2-1],
chiSettings[3][x3-1],
chiSettings[4][x4-1],
chiSettings[5][x5-1]
];
thisPsi = [
psiSettings[1][s1-1],
psiSettings[2][s2-1],
psiSettings[3][s3-1],
psiSettings[4][s4-1],
psiSettings[5][s5-1]
];
if (typeof ITA2_TABLE[letter] == "undefined") {
return "";
}
// The encipher calculation
// We calculate Bitwise XOR for each of the 5 bits across our input ( K XOR Psi XOR Chi )
const xorSum = [];
for (let i=0;i<=4;i++) {
xorSum[i] = ITA2_TABLE[letter][i] ^ thisPsi[i] ^ thisChi[i];
}
const resultStr = xorSum.join("");
// Wheel movement
// Chi wheels always move one back after each letter
if (--x1 < 1) x1 = 41;
if (--x2 < 1) x2 = 31;
if (--x3 < 1) x3 = 29;
if (--x4 < 1) x4 = 26;
if (--x5 < 1) x5 = 23;
// Motor wheel (61 pin) also moves one each letter
if (--m61 < 1) m61 = 61;
// If M61 is set, we also move M37
if (m61lug === 1) {
if (--m37 < 1) m37 = 37;
}
// Psi wheels only move sometimes, dependent on M37 current setting and limitations
const basicmotor = m37lug;
let totalmotor = basicmotor;
let lim = 0;
p5[2] = p5[1];
p5[1] = p5[0];
if (mode==="Send") {
p5[0] = parseInt(ITA2_TABLE[letter][4], 10);
} else {
p5[0] = parseInt(xorSum[4], 10);
}
// Limitations here
if (model==="SZ42a") {
// Chi 2 one back lim - The active character of Chi 2 (2nd Chi wheel) in the previous position
lim = parseInt(chiSettings[2][x2bptr-1], 10);
if (kt) {
//p5 back 2
if (lim===p5[2]) {
lim = 0;
} else {
lim=1;
}
}
// If basic motor = 0 and limitation = 1, Total motor = 0 [no move], otherwise, total motor = 1 [move]
if (basicmotor===0 && lim===1) {
totalmotor = 0;
} else {
totalmotor = 1;
}
} else if (model==="SZ42b") {
// Chi 2 one back + Psi 1 one back.
const x2b1lug = parseInt(chiSettings[2][x2bptr-1], 10);
const s1b1lug = parseInt(psiSettings[1][s1bptr-1], 10);
lim = 1;
if (x2b1lug===s1b1lug) lim=0;
if (kt) {
//p5 back 2
if (lim===p5[2]) {
lim=0;
} else {
lim=1;
}
}
// If basic motor = 0 and limitation = 1, Total motor = 0 [no move], otherwise, total motor = 1 [move]
if (basicmotor===0 && lim===1) {
totalmotor = 0;
} else {
totalmotor = 1;
}
} else if (model==="SZ40") {
// SZ40 - just move based on the M37 motor wheel
totalmotor = basicmotor;
} else {
throw new OperationError("Lorenz model type not recognised");
}
// Move the Psi wheels when current totalmotor active
if (totalmotor === 1) {
if (--s1 < 1) s1 = 43;
if (--s2 < 1) s2 = 47;
if (--s3 < 1) s3 = 51;
if (--s4 < 1) s4 = 53;
if (--s5 < 1) s5 = 59;
}
m61lug = muSettings[1][m61-1];
m37lug = muSettings[2][m37-1];
let rtnstr = self.REVERSE_ITA2_TABLE[resultStr];
if (format==="5/8/9") {
if (rtnstr==="+") rtnstr="5"; // + or 5 used to represent figure shift
if (rtnstr==="-") rtnstr="8"; // - or 8 used to represent letter shift
if (rtnstr===".") rtnstr="9"; // . or 9 used to represent space
}
return rtnstr;
});
const ita2output = letters.join("");
return this.convertFromITA2(ita2output, outtype, mode);
}
/**
* Reverses the ITA2 Code lookup table
*/
reverseTable() {
this.REVERSE_ITA2_TABLE = {};
this.REVERSE_FIGSHIFT_TABLE = {};
for (const letter in ITA2_TABLE) {
const code = ITA2_TABLE[letter];
this.REVERSE_ITA2_TABLE[code] = letter;
}
for (const letter in figShiftArr) {
const ltr = figShiftArr[letter];
this.REVERSE_FIGSHIFT_TABLE[ltr] = letter;
}
}
/**
* Read lugs settings - convert to 0|1
*/
readLugs(lugstr) {
const arr = Array.prototype.map.call(lugstr, function(lug) {
if (lug===".") {
return 0;
} else {
return 1;
}
});
return arr;
}
/**
* Convert input plaintext to ITA2
*/
convertToITA2(input, intype, mode) {
let result = "";
let figShifted = false;
for (const character of input) {
const letter = character.toUpperCase();
// Convert input text to ITA2 (including figure/letter shifts)
if (intype === "ITA2" || mode === "Receive") {
if (validITA2.indexOf(letter) === -1) {
let errltr = letter;
if (errltr==="\n") errltr = "Carriage Return";
if (errltr===" ") errltr = "Space";
throw new OperationError("Invalid ITA2 character : "+errltr);
}
result += letter;
} else {
if (validChars.indexOf(letter) === -1) throw new OperationError("Invalid Plaintext character : "+letter);
if (!figShifted && figShiftedChars.indexOf(letter) !== -1) {
// in letters mode and next char needs to be figure shifted
figShifted = true;
result += "55" + figShiftArr[letter];
} else if (figShifted) {
// in figures mode and next char needs to be letter shifted
if (letter==="\n") {
result += "34";
} else if (letter==="\r") {
result += "4";
} else if (figShiftedChars.indexOf(letter) === -1) {
figShifted = false;
result += "88" + letter;
} else {
result += figShiftArr[letter];
}
} else {
if (letter==="\n") {
result += "34";
} else if (letter==="\r") {
result += "4";
} else {
result += letter;
}
}
}
}
return result;
}
/**
* Convert final result ITA2 to plaintext
*/
convertFromITA2(input, outtype, mode) {
let result = "";
let figShifted = false;
for (const letter of input) {
if (mode === "Receive") {
// Convert output ITA2 to plaintext (including figure/letter shifts)
if (outtype === "Plaintext") {
if (letter === "5" || letter === "+") {
figShifted = true;
} else if (letter === "8" || letter === "-") {
figShifted = false;
} else if (letter === "9") {
result += " ";
} else if (letter === "3") {
result += "\n";
} else if (letter === "4") {
result += "";
} else if (letter === "/") {
result += "/";
} else {
if (figShifted) {
result += this.REVERSE_FIGSHIFT_TABLE[letter];
} else {
result += letter;
}
}
} else {
result += letter;
}
} else {
result += letter;
}
}
return result;
}
}
const ITA2_TABLE = {
"A": "11000",
"B": "10011",
"C": "01110",
"D": "10010",
"E": "10000",
"F": "10110",
"G": "01011",
"H": "00101",
"I": "01100",
"J": "11010",
"K": "11110",
"L": "01001",
"M": "00111",
"N": "00110",
"O": "00011",
"P": "01101",
"Q": "11101",
"R": "01010",
"S": "10100",
"T": "00001",
"U": "11100",
"V": "01111",
"W": "11001",
"X": "10111",
"Y": "10101",
"Z": "10001",
"3": "00010",
"4": "01000",
"9": "00100",
"/": "00000",
" ": "00100",
".": "00100",
"8": "11111",
"5": "11011",
"-": "11111",
"+": "11011"
};
const validChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890+-'()/:=?,. \n\r";
const validITA2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ34589+-./";
const figShiftedChars = "1234567890+-'()/:=?,.";
const figShiftArr = {
"1": "Q",
"2": "W",
"3": "E",
"4": "R",
"5": "T",
"6": "Y",
"7": "U",
"8": "I",
"9": "O",
"0": "P",
" ": "9",
"-": "A",
"?": "B",
":": "C",
"#": "D",
"%": "F",
"@": "G",
"£": "H",
"": "J",
"(": "K",
")": "L",
".": "M",
",": "N",
"'": "S",
"=": "V",
"/": "X",
"+": "Z",
"\n": "3",
"\r": "4"
};
const INIT_PATTERNS = {
"No Pattern": {
"X": {
1: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
2: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
3: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
4: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
},
"S": {
1: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
2: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
3: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
4: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
},
"M": {
1: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
2: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
}
},
"KH Pattern": {
"X": {
1: [0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0],
2: [1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0],
3: [0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0],
4: [1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0],
5: [1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0]
},
"S": {
1: [0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1],
2: [0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1],
3: [0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1],
4: [0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0],
5: [1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0]
},
"M": {
1: [0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0],
2: [1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0]
}
},
"ZMUG Pattern": {
"X": {
1: [0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0],
2: [1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0],
3: [0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0],
4: [1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1],
5: [0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1]
},
"S": {
1: [1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0],
2: [0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1],
3: [0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1],
4: [0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1],
5: [1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0]
},
"M": {
1: [1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1],
2: [0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1]
}
},
"BREAM Pattern": {
"X": {
1: [0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0],
2: [0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1],
3: [1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0],
4: [1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0],
5: [0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0]
},
"S": {
1: [0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0],
2: [1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0],
3: [1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
4: [0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1],
5: [1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0]
},
"M": {
1: [1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1],
2: [0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1]
}
}
};
export default Lorenz;

View File

@@ -54,7 +54,7 @@ class MultipleBombe extends Operation {
super();
this.name = "Multiple Bombe";
this.module = "Default";
this.module = "Bletchley";
this.description = "Emulation of the Bombe machine used to attack Enigma. This version carries out multiple Bombe runs to handle unknown rotor configurations.<br><br>You should test your menu on the single Bombe operation before running it here. See the description of the Bombe operation for instructions on choosing a crib.<br><br>More detailed descriptions of the Enigma, Typex and Bombe operations <a href='https://github.com/gchq/CyberChef/wiki/Enigma,-the-Bombe,-and-Typex'>can be found here</a>.";
this.infoURL = "https://wikipedia.org/wiki/Bombe";
this.inputType = "string";

View File

@@ -7,7 +7,7 @@
import Operation from "../Operation.mjs";
import Utils from "../Utils.mjs";
import cptable from "../vendor/js-codepage/cptable.js";
import cptable from "codepage";
import {IO_FORMAT} from "../lib/ChrEnc.mjs";
/**

View File

@@ -22,7 +22,7 @@ class Typex extends Operation {
super();
this.name = "Typex";
this.module = "Default";
this.module = "Bletchley";
this.description = "Encipher/decipher with the WW2 Typex machine.<br><br>Typex was originally built by the British Royal Air Force prior to WW2, and is based on the Enigma machine with some improvements made, including using five rotors with more stepping points and interchangeable wiring cores. It was used across the British and Commonwealth militaries. A number of later variants were produced; here we simulate a WW2 era Mark 22 Typex with plugboards for the reflector and input. Typex rotors were changed regularly and none are public: a random example set are provided.<br><br>To configure the reflector plugboard, enter a string of connected pairs of letters in the reflector box, e.g. <code>AB CD EF</code> connects A to B, C to D, and E to F (you'll need to connect every letter). There is also an input plugboard: unlike Enigma's plugboard, it's not restricted to pairs, so it's entered like a rotor (without stepping). To create your own rotor, enter the letters that the rotor maps A to Z to, in order, optionally followed by <code>&lt;</code> then a list of stepping points.<br><br>More detailed descriptions of the Enigma, Typex and Bombe operations <a href='https://github.com/gchq/CyberChef/wiki/Enigma,-the-Bombe,-and-Typex'>can be found here</a>.";
this.infoURL = "https://wikipedia.org/wiki/Typex";
this.inputType = "string";

File diff suppressed because it is too large Load Diff

View File

@@ -1,515 +0,0 @@
/* cputils.js (C) 2013-present SheetJS -- http://sheetjs.com */
/* vim: set ft=javascript: */
/*jshint newcap: false */
(function(root, factory) {
"use strict";
if(typeof cptable === "undefined") {
if(typeof require !== "undefined"){
var cpt = require('./cptable');
if (typeof module !== 'undefined' && module.exports) module.exports = factory(cpt);
else root.cptable = factory(cpt);
} else throw new Error("cptable not found");
} else cptable = factory(cptable);
}(this, function(cpt){
"use strict";
var magic = {
"1200":"utf16le",
"1201":"utf16be",
"12000":"utf32le",
"12001":"utf32be",
"16969":"utf64le",
"20127":"ascii",
"65000":"utf7",
"65001":"utf8"
};
var sbcs_cache = [874,1250,1251,1252,1253,1254,1255,1256,10000];
var dbcs_cache = [932,936,949,950];
var magic_cache = [65001];
var magic_decode = {};
var magic_encode = {};
var cpdcache = {};
var cpecache = {};
var sfcc = function sfcc(x) { return String.fromCharCode(x); };
var cca = function cca(x) { return x.charCodeAt(0); };
var has_buf = (typeof Buffer !== 'undefined');
if(has_buf) {
var mdl = 1024, mdb = new Buffer(mdl);
var make_EE = function make_EE(E){
var EE = new Buffer(65536);
for(var i = 0; i < 65536;++i) EE[i] = 0;
var keys = Object.keys(E), len = keys.length;
for(var ee = 0, e = keys[ee]; ee < len; ++ee) {
if(!(e = keys[ee])) continue;
EE[e.charCodeAt(0)] = E[e];
}
return EE;
};
var sbcs_encode = function make_sbcs_encode(cp) {
var EE = make_EE(cpt[cp].enc);
return function sbcs_e(data, ofmt) {
var len = data.length;
var out, i=0, j=0, D=0, w=0;
if(typeof data === 'string') {
out = new Buffer(len);
for(i = 0; i < len; ++i) out[i] = EE[data.charCodeAt(i)];
} else if(Buffer.isBuffer(data)) {
out = new Buffer(2*len);
j = 0;
for(i = 0; i < len; ++i) {
D = data[i];
if(D < 128) out[j++] = EE[D];
else if(D < 224) { out[j++] = EE[((D&31)<<6)+(data[i+1]&63)]; ++i; }
else if(D < 240) { out[j++] = EE[((D&15)<<12)+((data[i+1]&63)<<6)+(data[i+2]&63)]; i+=2; }
else {
w = ((D&7)<<18)+((data[i+1]&63)<<12)+((data[i+2]&63)<<6)+(data[i+3]&63); i+=3;
if(w < 65536) out[j++] = EE[w];
else { w -= 65536; out[j++] = EE[0xD800 + ((w>>10)&1023)]; out[j++] = EE[0xDC00 + (w&1023)]; }
}
}
out = out.slice(0,j);
} else {
out = new Buffer(len);
for(i = 0; i < len; ++i) out[i] = EE[data[i].charCodeAt(0)];
}
if(!ofmt || ofmt === 'buf') return out;
if(ofmt !== 'arr') return out.toString('binary');
return [].slice.call(out);
};
};
var sbcs_decode = function make_sbcs_decode(cp) {
var D = cpt[cp].dec;
var DD = new Buffer(131072), d=0, c="";
for(d=0;d<D.length;++d) {
if(!(c=D[d])) continue;
var w = c.charCodeAt(0);
DD[2*d] = w&255; DD[2*d+1] = w>>8;
}
return function sbcs_d(data) {
var len = data.length, i=0, j=0;
if(2 * len > mdl) { mdl = 2 * len; mdb = new Buffer(mdl); }
if(Buffer.isBuffer(data)) {
for(i = 0; i < len; i++) {
j = 2*data[i];
mdb[2*i] = DD[j]; mdb[2*i+1] = DD[j+1];
}
} else if(typeof data === "string") {
for(i = 0; i < len; i++) {
j = 2*data.charCodeAt(i);
mdb[2*i] = DD[j]; mdb[2*i+1] = DD[j+1];
}
} else {
for(i = 0; i < len; i++) {
j = 2*data[i];
mdb[2*i] = DD[j]; mdb[2*i+1] = DD[j+1];
}
}
return mdb.slice(0, 2 * len).toString('ucs2');
};
};
var dbcs_encode = function make_dbcs_encode(cp) {
var E = cpt[cp].enc;
var EE = new Buffer(131072);
for(var i = 0; i < 131072; ++i) EE[i] = 0;
var keys = Object.keys(E);
for(var ee = 0, e = keys[ee]; ee < keys.length; ++ee) {
if(!(e = keys[ee])) continue;
var f = e.charCodeAt(0);
EE[2*f] = E[e] & 255; EE[2*f+1] = E[e]>>8;
}
return function dbcs_e(data, ofmt) {
var len = data.length, out = new Buffer(2*len), i=0, j=0, jj=0, k=0, D=0;
if(typeof data === 'string') {
for(i = k = 0; i < len; ++i) {
j = data.charCodeAt(i)*2;
out[k++] = EE[j+1] || EE[j]; if(EE[j+1] > 0) out[k++] = EE[j];
}
out = out.slice(0,k);
} else if(Buffer.isBuffer(data)) {
for(i = k = 0; i < len; ++i) {
D = data[i];
if(D < 128) j = D;
else if(D < 224) { j = ((D&31)<<6)+(data[i+1]&63); ++i; }
else if(D < 240) { j = ((D&15)<<12)+((data[i+1]&63)<<6)+(data[i+2]&63); i+=2; }
else { j = ((D&7)<<18)+((data[i+1]&63)<<12)+((data[i+2]&63)<<6)+(data[i+3]&63); i+=3; }
if(j<65536) { j*=2; out[k++] = EE[j+1] || EE[j]; if(EE[j+1] > 0) out[k++] = EE[j]; }
else { jj = j-65536;
j=2*(0xD800 + ((jj>>10)&1023)); out[k++] = EE[j+1] || EE[j]; if(EE[j+1] > 0) out[k++] = EE[j];
j=2*(0xDC00 + (jj&1023)); out[k++] = EE[j+1] || EE[j]; if(EE[j+1] > 0) out[k++] = EE[j];
}
}
out = out.slice(0,k);
} else {
for(i = k = 0; i < len; i++) {
j = data[i].charCodeAt(0)*2;
out[k++] = EE[j+1] || EE[j]; if(EE[j+1] > 0) out[k++] = EE[j];
}
}
if(!ofmt || ofmt === 'buf') return out;
if(ofmt !== 'arr') return out.toString('binary');
return [].slice.call(out);
};
};
var dbcs_decode = function make_dbcs_decode(cp) {
var D = cpt[cp].dec;
var DD = new Buffer(131072), d=0, c, w=0, j=0, i=0;
for(i = 0; i < 65536; ++i) { DD[2*i] = 0xFF; DD[2*i+1] = 0xFD;}
for(d = 0; d < D.length; ++d) {
if(!(c=D[d])) continue;
w = c.charCodeAt(0);
j = 2*d;
DD[j] = w&255; DD[j+1] = w>>8;
}
return function dbcs_d(data) {
var len = data.length, out = new Buffer(2*len), i=0, j=0, k=0;
if(Buffer.isBuffer(data)) {
for(i = 0; i < len; i++) {
j = 2*data[i];
if(DD[j]===0xFF && DD[j+1]===0xFD) { j=2*((data[i]<<8)+data[i+1]); ++i; }
out[k++] = DD[j]; out[k++] = DD[j+1];
}
} else if(typeof data === "string") {
for(i = 0; i < len; i++) {
j = 2*data.charCodeAt(i);
if(DD[j]===0xFF && DD[j+1]===0xFD) { j=2*((data.charCodeAt(i)<<8)+data.charCodeAt(i+1)); ++i; }
out[k++] = DD[j]; out[k++] = DD[j+1];
}
} else {
for(i = 0; i < len; i++) {
j = 2*data[i];
if(DD[j]===0xFF && DD[j+1]===0xFD) { j=2*((data[i]<<8)+data[i+1]); ++i; }
out[k++] = DD[j]; out[k++] = DD[j+1];
}
}
return out.slice(0,k).toString('ucs2');
};
};
magic_decode[65001] = function utf8_d(data) {
if(typeof data === "string") return utf8_d(data.split("").map(cca));
var len = data.length, w = 0, ww = 0;
if(4 * len > mdl) { mdl = 4 * len; mdb = new Buffer(mdl); }
var i = 0;
if(len >= 3 && data[0] == 0xEF) if(data[1] == 0xBB && data[2] == 0xBF) i = 3;
for(var j = 1, k = 0, D = 0; i < len; i+=j) {
j = 1; D = data[i];
if(D < 128) w = D;
else if(D < 224) { w=(D&31)*64+(data[i+1]&63); j=2; }
else if(D < 240) { w=((D&15)<<12)+(data[i+1]&63)*64+(data[i+2]&63); j=3; }
else { w=(D&7)*262144+((data[i+1]&63)<<12)+(data[i+2]&63)*64+(data[i+3]&63); j=4; }
if(w < 65536) { mdb[k++] = w&255; mdb[k++] = w>>8; }
else {
w -= 65536; ww = 0xD800 + ((w>>10)&1023); w = 0xDC00 + (w&1023);
mdb[k++] = ww&255; mdb[k++] = ww>>>8; mdb[k++] = w&255; mdb[k++] = (w>>>8)&255;
}
}
return mdb.slice(0,k).toString('ucs2');
};
magic_encode[65001] = function utf8_e(data, ofmt) {
if(has_buf && Buffer.isBuffer(data)) {
if(!ofmt || ofmt === 'buf') return data;
if(ofmt !== 'arr') return data.toString('binary');
return [].slice.call(data);
}
var len = data.length, w = 0, ww = 0, j = 0;
var direct = typeof data === "string";
if(4 * len > mdl) { mdl = 4 * len; mdb = new Buffer(mdl); }
for(var i = 0; i < len; ++i) {
w = direct ? data.charCodeAt(i) : data[i].charCodeAt(0);
if(w <= 0x007F) mdb[j++] = w;
else if(w <= 0x07FF) {
mdb[j++] = 192 + (w >> 6);
mdb[j++] = 128 + (w&63);
} else if(w >= 0xD800 && w <= 0xDFFF) {
w -= 0xD800; ++i;
ww = (direct ? data.charCodeAt(i) : data[i].charCodeAt(0)) - 0xDC00 + (w << 10);
mdb[j++] = 240 + ((ww>>>18) & 0x07);
mdb[j++] = 144 + ((ww>>>12) & 0x3F);
mdb[j++] = 128 + ((ww>>>6) & 0x3F);
mdb[j++] = 128 + (ww & 0x3F);
} else {
mdb[j++] = 224 + (w >> 12);
mdb[j++] = 128 + ((w >> 6)&63);
mdb[j++] = 128 + (w&63);
}
}
if(!ofmt || ofmt === 'buf') return mdb.slice(0,j);
if(ofmt !== 'arr') return mdb.slice(0,j).toString('binary');
return [].slice.call(mdb, 0, j);
};
}
var encache = function encache() {
if(has_buf) {
if(cpdcache[sbcs_cache[0]]) return;
var i=0, s=0;
for(i = 0; i < sbcs_cache.length; ++i) {
s = sbcs_cache[i];
if(cpt[s]) {
cpdcache[s] = sbcs_decode(s);
cpecache[s] = sbcs_encode(s);
}
}
for(i = 0; i < dbcs_cache.length; ++i) {
s = dbcs_cache[i];
if(cpt[s]) {
cpdcache[s] = dbcs_decode(s);
cpecache[s] = dbcs_encode(s);
}
}
for(i = 0; i < magic_cache.length; ++i) {
s = magic_cache[i];
if(magic_decode[s]) cpdcache[s] = magic_decode[s];
if(magic_encode[s]) cpecache[s] = magic_encode[s];
}
}
};
var null_enc = function(data, ofmt) { return ""; };
var cp_decache = function cp_decache(cp) { delete cpdcache[cp]; delete cpecache[cp]; };
var decache = function decache() {
if(has_buf) {
if(!cpdcache[sbcs_cache[0]]) return;
sbcs_cache.forEach(cp_decache);
dbcs_cache.forEach(cp_decache);
magic_cache.forEach(cp_decache);
}
last_enc = null_enc; last_cp = 0;
};
var cache = {
encache: encache,
decache: decache,
sbcs: sbcs_cache,
dbcs: dbcs_cache
};
encache();
var BM = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
var SetD = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'(),-./:?";
var last_enc = null_enc, last_cp = 0;
var encode = function encode(cp, data, ofmt) {
if(cp === last_cp && last_enc) { return last_enc(data, ofmt); }
if(cpecache[cp]) { last_enc = cpecache[last_cp=cp]; return last_enc(data, ofmt); }
if(has_buf && Buffer.isBuffer(data)) data = data.toString('utf8');
var len = data.length;
var out = has_buf ? new Buffer(4*len) : [], w=0, i=0, j = 0, ww=0;
var C = cpt[cp], E, M = "";
var isstr = typeof data === 'string';
if(C && (E=C.enc)) for(i = 0; i < len; ++i, ++j) {
w = E[isstr? data.charAt(i) : data[i]];
if(w > 255) {
out[j] = w>>8;
out[++j] = w&255;
} else out[j] = w&255;
}
else if((M=magic[cp])) switch(M) {
case "utf8":
if(has_buf && isstr) { out = new Buffer(data, M); j = out.length; break; }
for(i = 0; i < len; ++i, ++j) {
w = isstr ? data.charCodeAt(i) : data[i].charCodeAt(0);
if(w <= 0x007F) out[j] = w;
else if(w <= 0x07FF) {
out[j] = 192 + (w >> 6);
out[++j] = 128 + (w&63);
} else if(w >= 0xD800 && w <= 0xDFFF) {
w -= 0xD800;
ww = (isstr ? data.charCodeAt(++i) : data[++i].charCodeAt(0)) - 0xDC00 + (w << 10);
out[j] = 240 + ((ww>>>18) & 0x07);
out[++j] = 144 + ((ww>>>12) & 0x3F);
out[++j] = 128 + ((ww>>>6) & 0x3F);
out[++j] = 128 + (ww & 0x3F);
} else {
out[j] = 224 + (w >> 12);
out[++j] = 128 + ((w >> 6)&63);
out[++j] = 128 + (w&63);
}
}
break;
case "ascii":
if(has_buf && typeof data === "string") { out = new Buffer(data, M); j = out.length; break; }
for(i = 0; i < len; ++i, ++j) {
w = isstr ? data.charCodeAt(i) : data[i].charCodeAt(0);
if(w <= 0x007F) out[j] = w;
else throw new Error("bad ascii " + w);
}
break;
case "utf16le":
if(has_buf && typeof data === "string") { out = new Buffer(data, M); j = out.length; break; }
for(i = 0; i < len; ++i) {
w = isstr ? data.charCodeAt(i) : data[i].charCodeAt(0);
out[j++] = w&255;
out[j++] = w>>8;
}
break;
case "utf16be":
for(i = 0; i < len; ++i) {
w = isstr ? data.charCodeAt(i) : data[i].charCodeAt(0);
out[j++] = w>>8;
out[j++] = w&255;
}
break;
case "utf32le":
for(i = 0; i < len; ++i) {
w = isstr ? data.charCodeAt(i) : data[i].charCodeAt(0);
if(w >= 0xD800 && w <= 0xDFFF) w = 0x10000 + ((w - 0xD800) << 10) + (data[++i].charCodeAt(0) - 0xDC00);
out[j++] = w&255; w >>= 8;
out[j++] = w&255; w >>= 8;
out[j++] = w&255; w >>= 8;
out[j++] = w&255;
}
break;
case "utf32be":
for(i = 0; i < len; ++i) {
w = isstr ? data.charCodeAt(i) : data[i].charCodeAt(0);
if(w >= 0xD800 && w <= 0xDFFF) w = 0x10000 + ((w - 0xD800) << 10) + (data[++i].charCodeAt(0) - 0xDC00);
out[j+3] = w&255; w >>= 8;
out[j+2] = w&255; w >>= 8;
out[j+1] = w&255; w >>= 8;
out[j] = w&255;
j+=4;
}
break;
case "utf7":
for(i = 0; i < len; i++) {
var c = isstr ? data.charAt(i) : data[i].charAt(0);
if(c === "+") { out[j++] = 0x2b; out[j++] = 0x2d; continue; }
if(SetD.indexOf(c) > -1) { out[j++] = c.charCodeAt(0); continue; }
var tt = encode(1201, c);
out[j++] = 0x2b;
out[j++] = BM.charCodeAt(tt[0]>>2);
out[j++] = BM.charCodeAt(((tt[0]&0x03)<<4) + ((tt[1]||0)>>4));
out[j++] = BM.charCodeAt(((tt[1]&0x0F)<<2) + ((tt[2]||0)>>6));
out[j++] = 0x2d;
}
break;
default: throw new Error("Unsupported magic: " + cp + " " + magic[cp]);
}
else throw new Error("Unrecognized CP: " + cp);
out = out.slice(0,j);
if(!has_buf) return (ofmt == 'str') ? (out).map(sfcc).join("") : out;
if(!ofmt || ofmt === 'buf') return out;
if(ofmt !== 'arr') return out.toString('binary');
return [].slice.call(out);
};
var decode = function decode(cp, data) {
var F; if((F=cpdcache[cp])) return F(data);
if(typeof data === "string") return decode(cp, data.split("").map(cca));
var len = data.length, out = new Array(len), s="", w=0, i=0, j=1, k=0, ww=0;
var C = cpt[cp], D, M="";
if(C && (D=C.dec)) {
for(i = 0; i < len; i+=j) {
j = 2;
s = D[(data[i]<<8)+ data[i+1]];
if(!s) {
j = 1;
s = D[data[i]];
}
if(!s) throw new Error('Unrecognized code: ' + data[i] + ' ' + data[i+j-1] + ' ' + i + ' ' + j + ' ' + D[data[i]]);
out[k++] = s;
}
}
else if((M=magic[cp])) switch(M) {
case "utf8":
if(len >= 3 && data[0] == 0xEF) if(data[1] == 0xBB && data[2] == 0xBF) i = 3;
for(; i < len; i+=j) {
j = 1;
if(data[i] < 128) w = data[i];
else if(data[i] < 224) { w=(data[i]&31)*64+(data[i+1]&63); j=2; }
else if(data[i] < 240) { w=((data[i]&15)<<12)+(data[i+1]&63)*64+(data[i+2]&63); j=3; }
else { w=(data[i]&7)*262144+((data[i+1]&63)<<12)+(data[i+2]&63)*64+(data[i+3]&63); j=4; }
if(w < 65536) { out[k++] = String.fromCharCode(w); }
else {
w -= 65536; ww = 0xD800 + ((w>>10)&1023); w = 0xDC00 + (w&1023);
out[k++] = String.fromCharCode(ww); out[k++] = String.fromCharCode(w);
}
}
break;
case "ascii":
if(has_buf && Buffer.isBuffer(data)) return data.toString(M);
for(i = 0; i < len; i++) out[i] = String.fromCharCode(data[i]);
k = len; break;
case "utf16le":
if(len >= 2 && data[0] == 0xFF) if(data[1] == 0xFE) i = 2;
if(has_buf && Buffer.isBuffer(data)) return data.toString(M);
j = 2;
for(; i+1 < len; i+=j) {
out[k++] = String.fromCharCode((data[i+1]<<8) + data[i]);
}
break;
case "utf16be":
if(len >= 2 && data[0] == 0xFE) if(data[1] == 0xFF) i = 2;
j = 2;
for(; i+1 < len; i+=j) {
out[k++] = String.fromCharCode((data[i]<<8) + data[i+1]);
}
break;
case "utf32le":
if(len >= 4 && data[0] == 0xFF) if(data[1] == 0xFE && data[2] === 0 && data[3] === 0) i = 4;
j = 4;
for(; i < len; i+=j) {
w = (data[i+3]<<24) + (data[i+2]<<16) + (data[i+1]<<8) + (data[i]);
if(w > 0xFFFF) {
w -= 0x10000;
out[k++] = String.fromCharCode(0xD800 + ((w >> 10) & 0x3FF));
out[k++] = String.fromCharCode(0xDC00 + (w & 0x3FF));
}
else out[k++] = String.fromCharCode(w);
}
break;
case "utf32be":
if(len >= 4 && data[3] == 0xFF) if(data[2] == 0xFE && data[1] === 0 && data[0] === 0) i = 4;
j = 4;
for(; i < len; i+=j) {
w = (data[i]<<24) + (data[i+1]<<16) + (data[i+2]<<8) + (data[i+3]);
if(w > 0xFFFF) {
w -= 0x10000;
out[k++] = String.fromCharCode(0xD800 + ((w >> 10) & 0x3FF));
out[k++] = String.fromCharCode(0xDC00 + (w & 0x3FF));
}
else out[k++] = String.fromCharCode(w);
}
break;
case "utf7":
if(len >= 4 && data[0] == 0x2B && data[1] == 0x2F && data[2] == 0x76) {
if(len >= 5 && data[3] == 0x38 && data[4] == 0x2D) i = 5;
else if(data[3] == 0x38 || data[3] == 0x39 || data[3] == 0x2B || data[3] == 0x2F) i = 4;
}
for(; i < len; i+=j) {
if(data[i] !== 0x2b) { j=1; out[k++] = String.fromCharCode(data[i]); continue; }
j=1;
if(data[i+1] === 0x2d) { j = 2; out[k++] = "+"; continue; }
while(String.fromCharCode(data[i+j]).match(/[A-Za-z0-9+\/]/)) j++;
var dash = 0;
if(data[i+j] === 0x2d) { ++j; dash=1; }
var tt = [];
var o64 = "";
var c1=0, c2=0, c3=0;
var e1=0, e2=0, e3=0, e4=0;
for(var l = 1; l < j - dash;) {
e1 = BM.indexOf(String.fromCharCode(data[i+l++]));
e2 = BM.indexOf(String.fromCharCode(data[i+l++]));
c1 = e1 << 2 | e2 >> 4;
tt.push(c1);
e3 = BM.indexOf(String.fromCharCode(data[i+l++]));
if(e3 === -1) break;
c2 = (e2 & 15) << 4 | e3 >> 2;
tt.push(c2);
e4 = BM.indexOf(String.fromCharCode(data[i+l++]));
if(e4 === -1) break;
c3 = (e3 & 3) << 6 | e4;
if(e4 < 64) tt.push(c3);
}
o64 = decode(1201, tt);
for(l = 0; l < o64.length; ++l) out[k++] = o64.charAt(l);
}
break;
default: throw new Error("Unsupported magic: " + cp + " " + magic[cp]);
}
else throw new Error("Unrecognized CP: " + cp);
return out.slice(0,k).join("");
};
var hascp = function hascp(cp) { return !!(cpt[cp] || magic[cp]); };
cpt.utils = { decode: decode, encode: encode, hascp: hascp, magic: magic, cache:cache };
return cpt;
}));

View File

@@ -54,7 +54,9 @@ class HTMLIngredient {
case "binaryString":
case "byteArray":
html += `<div class="form-group">
<label for="${this.id}" class="bmd-label-floating">${this.name}</label>
<label for="${this.id}"
${this.hint ? `data-toggle="tooltip" title="${this.hint}"` : ""}
class="bmd-label-floating">${this.name}</label>
<input type="text"
class="form-control arg"
id="${this.id}"
@@ -62,13 +64,14 @@ class HTMLIngredient {
arg-name="${this.name}"
value="${this.value}"
${this.disabled ? "disabled" : ""}>
${this.hint ? "<span class='bmd-help'>" + this.hint + "</span>" : ""}
</div>`;
break;
case "shortString":
case "binaryShortString":
html += `<div class="form-group inline">
<label for="${this.id}" class="bmd-label-floating inline">${this.name}</label>
<label for="${this.id}"
${this.hint ? `data-toggle="tooltip" title="${this.hint}"` : ""}
class="bmd-label-floating inline">${this.name}</label>
<input type="text"
class="form-control arg inline"
id="${this.id}"
@@ -76,13 +79,14 @@ class HTMLIngredient {
arg-name="${this.name}"
value="${this.value}"
${this.disabled ? "disabled" : ""}>
${this.hint ? "<span class='bmd-help'>" + this.hint + "</span>" : ""}
</div>`;
break;
case "toggleString":
html += `<div class="form-group input-group">
<div class="toggle-string">
<label for="${this.id}" class="bmd-label-floating toggle-string">${this.name}</label>
<label for="${this.id}"
${this.hint ? `data-toggle="tooltip" title="${this.hint}"` : ""}
class="bmd-label-floating toggle-string">${this.name}</label>
<input type="text"
class="form-control arg toggle-string"
id="${this.id}"
@@ -90,7 +94,6 @@ class HTMLIngredient {
arg-name="${this.name}"
value="${this.value}"
${this.disabled ? "disabled" : ""}>
${this.hint ? "<span class='bmd-help'>" + this.hint + "</span>" : ""}
</div>
<div class="input-group-append">
<button class="btn btn-secondary dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">${this.toggleValues[0]}</button>
@@ -105,7 +108,9 @@ class HTMLIngredient {
break;
case "number":
html += `<div class="form-group inline">
<label for="${this.id}" class="bmd-label-floating inline">${this.name}</label>
<label for="${this.id}"
${this.hint ? `data-toggle="tooltip" title="${this.hint}"` : ""}
class="bmd-label-floating inline">${this.name}</label>
<input type="number"
class="form-control arg inline"
id="${this.id}"
@@ -116,13 +121,12 @@ class HTMLIngredient {
max="${this.max}"
step="${this.step}"
${this.disabled ? "disabled" : ""}>
${this.hint ? "<span class='bmd-help'>" + this.hint + "</span>" : ""}
</div>`;
break;
case "boolean":
html += `<div class="form-group inline boolean-arg">
<div class="checkbox">
<label>
<label ${this.hint ? `data-toggle="tooltip" title="${this.hint}"` : ""}>
<input type="checkbox"
class="arg"
id="${this.id}"
@@ -132,13 +136,14 @@ class HTMLIngredient {
${this.disabled ? " disabled" : ""}
value="${this.name}"> ${this.name}
</label>
${this.hint ? "<span class='bmd-help'>" + this.hint + "</span>" : ""}
</div>
</div>`;
break;
case "option":
html += `<div class="form-group inline">
<label for="${this.id}" class="bmd-label-floating inline">${this.name}</label>
<label for="${this.id}"
${this.hint ? `data-toggle="tooltip" title="${this.hint}"` : ""}
class="bmd-label-floating inline">${this.name}</label>
<select
class="form-control arg inline"
id="${this.id}"
@@ -155,13 +160,14 @@ class HTMLIngredient {
}
}
html += `</select>
${this.hint ? "<span class='bmd-help'>" + this.hint + "</span>" : ""}
</div>`;
break;
case "populateOption":
case "populateMultiOption":
html += `<div class="form-group">
<label for="${this.id}" class="bmd-label-floating">${this.name}</label>
<label for="${this.id}"
${this.hint ? `data-toggle="tooltip" title="${this.hint}"` : ""}
class="bmd-label-floating">${this.name}</label>
<select
class="form-control arg no-state-change populate-option"
id="${this.id}"
@@ -181,7 +187,6 @@ class HTMLIngredient {
}
}
html += `</select>
${this.hint ? "<span class='bmd-help'>" + this.hint + "</span>" : ""}
</div>`;
eventFn = this.type === "populateMultiOption" ?
@@ -191,7 +196,9 @@ class HTMLIngredient {
break;
case "editableOption":
html += `<div class="form-group input-group">
<label for="${this.id}" class="bmd-label-floating">${this.name}</label>
<label for="${this.id}"
${this.hint ? `data-toggle="tooltip" title="${this.hint}"` : ""}
class="bmd-label-floating">${this.name}</label>
<input type="text"
class="form-control arg"
id="${this.id}"
@@ -199,7 +206,6 @@ class HTMLIngredient {
arg-name="${this.name}"
value="${this.value[this.defaultIndex].value}"
${this.disabled ? "disabled" : ""}>
${this.hint ? "<span class='bmd-help'>" + this.hint + "</span>" : ""}
<div class="input-group-append">
<button type="button"
class="btn btn-secondary dropdown-toggle dropdown-toggle-split"
@@ -221,7 +227,9 @@ class HTMLIngredient {
break;
case "editableOptionShort":
html += `<div class="form-group input-group inline">
<label for="${this.id}" class="bmd-label-floating inline">${this.name}</label>
<label for="${this.id}"
${this.hint ? `data-toggle="tooltip" title="${this.hint}"` : ""}
class="bmd-label-floating inline">${this.name}</label>
<input type="text"
class="form-control arg inline"
id="${this.id}"
@@ -229,7 +237,6 @@ class HTMLIngredient {
arg-name="${this.name}"
value="${this.value[this.defaultIndex].value}"
${this.disabled ? "disabled" : ""}>
${this.hint ? "<span class='bmd-help'>" + this.hint + "</span>" : ""}
<div class="input-group-append inline">
<button type="button"
class="btn btn-secondary dropdown-toggle dropdown-toggle-split"
@@ -251,7 +258,9 @@ class HTMLIngredient {
break;
case "text":
html += `<div class="form-group">
<label for="${this.id}" class="bmd-label-floating">${this.name}</label>
<label for="${this.id}"
${this.hint ? `data-toggle="tooltip" title="${this.hint}"` : ""}
class="bmd-label-floating">${this.name}</label>
<textarea
class="form-control arg"
id="${this.id}"
@@ -259,12 +268,13 @@ class HTMLIngredient {
arg-name="${this.name}"
rows="${this.rows ? this.rows : 3}"
${this.disabled ? "disabled" : ""}>${this.value}</textarea>
${this.hint ? "<span class='bmd-help'>" + this.hint + "</span>" : ""}
</div>`;
break;
case "argSelector":
html += `<div class="form-group inline">
<label for="${this.id}" class="bmd-label-floating inline">${this.name}</label>
<label for="${this.id}"
${this.hint ? `data-toggle="tooltip" title="${this.hint}"` : ""}
class="bmd-label-floating inline">${this.name}</label>
<select
class="form-control arg inline arg-selector"
id="${this.id}"
@@ -279,7 +289,6 @@ class HTMLIngredient {
</option>`;
}
html += `</select>
${this.hint ? "<span class='bmd-help'>" + this.hint + "</span>" : ""}
</div>`;
this.manager.addDynamicListener(".arg-selector", "change", this.argSelectorChange, this);

View File

@@ -159,10 +159,6 @@ div.toggle-string {
width: calc(100% - 13px);
}
.operation .bmd-form-group .bmd-help {
margin-top: -17px;
}
.input-group .form-control {
border-top-left-radius: 4px !important;
}

View File

@@ -399,6 +399,8 @@ class RecipeWaiter {
this.buildRecipeOperation(item);
document.getElementById("rec-list").appendChild(item);
$(item).find("[data-toggle='tooltip']").tooltip();
item.dispatchEvent(this.manager.operationadd);
return item;
}

View File

@@ -353,10 +353,10 @@ color: white;
it("Decode text", () => {
const encoded = chef.encodeText("Ugly Duckling", {
encoding: "UTF16LE (1200)",
encoding: "UTF-16LE (1200)",
});
const result = chef.decodeText(encoded, {
encoding: "UTF16LE (1200)",
encoding: "UTF-16LE (1200)",
});
assert.strictEqual(result.toString(), "Ugly Duckling");
}),

View File

@@ -91,6 +91,9 @@ import "./tests/Protobuf.mjs";
import "./tests/ParseSSHHostKey.mjs";
import "./tests/DefangIP.mjs";
import "./tests/ParseUDP.mjs";
import "./tests/AvroToJSON.mjs";
import "./tests/Lorenz.mjs";
// Cannot test operations that use the File type yet
// import "./tests/SplitColourChannels.mjs";

View File

@@ -0,0 +1,66 @@
/**
* Avro to JSON tests.
*
* @author jarrodconnolly [jarrod@nestedquotes.ca]
* @copyright Crown Copyright 2019
* @license Apache-2.0
*/
import TestRegister from "../../lib/TestRegister";
TestRegister.addTests([
{
name: "Avro to JSON: no input (force JSON true)",
input: "",
expectedOutput: "Please provide an input.",
recipeConfig: [
{
op: "Avro to JSON",
args: [true]
}
],
},
{
name: "Avro to JSON: no input (force JSON false)",
input: "",
expectedOutput: "Please provide an input.",
recipeConfig: [
{
op: "Avro to JSON",
args: [false]
}
],
},
{
name: "Avro to JSON: small (force JSON true)",
input: "\x4f\x62\x6a\x01\x04\x16\x61\x76\x72\x6f\x2e\x73\x63\x68\x65\x6d\x61\x96\x01\x7b\x22\x74\x79\x70\x65\x22\x3a\x22\x72\x65" +
"\x63\x6f\x72\x64\x22\x2c\x22\x6e\x61\x6d\x65\x22\x3a\x22\x73\x6d\x61\x6c\x6c\x22\x2c\x22\x66\x69\x65\x6c\x64\x73\x22\x3a" +
"\x5b\x7b\x22\x6e\x61\x6d\x65\x22\x3a\x22\x6e\x61\x6d\x65\x22\x2c\x22\x74\x79\x70\x65\x22\x3a\x22\x73\x74\x72\x69\x6e\x67" +
"\x22\x7d\x5d\x7d\x14\x61\x76\x72\x6f\x2e\x63\x6f\x64\x65\x63\x08\x6e\x75\x6c\x6c\x00\x4e\x02\x47\x63\x2e\x37\x02\xe5\xb7" +
"\x5c\xda\xb9\xa6\x2f\x15\x41\x02\x0e\x0c\x6d\x79\x6e\x61\x6d\x65\x4e\x02\x47\x63\x2e\x37\x02\xe5\xb7\x5c\xda\xb9\xa6\x2f" +
"\x15\x41",
expectedOutput: "{\n \"name\": \"myname\"\n}",
recipeConfig: [
{
op: "Avro to JSON",
args: [true]
}
],
},
{
name: "Avro to JSON: small (force JSON false)",
input: "\x4f\x62\x6a\x01\x04\x16\x61\x76\x72\x6f\x2e\x73\x63\x68\x65\x6d\x61\x96\x01\x7b\x22\x74\x79\x70\x65\x22\x3a\x22\x72\x65" +
"\x63\x6f\x72\x64\x22\x2c\x22\x6e\x61\x6d\x65\x22\x3a\x22\x73\x6d\x61\x6c\x6c\x22\x2c\x22\x66\x69\x65\x6c\x64\x73\x22\x3a" +
"\x5b\x7b\x22\x6e\x61\x6d\x65\x22\x3a\x22\x6e\x61\x6d\x65\x22\x2c\x22\x74\x79\x70\x65\x22\x3a\x22\x73\x74\x72\x69\x6e\x67" +
"\x22\x7d\x5d\x7d\x14\x61\x76\x72\x6f\x2e\x63\x6f\x64\x65\x63\x08\x6e\x75\x6c\x6c\x00\x4e\x02\x47\x63\x2e\x37\x02\xe5\xb7" +
"\x5c\xda\xb9\xa6\x2f\x15\x41\x02\x0e\x0c\x6d\x79\x6e\x61\x6d\x65\x4e\x02\x47\x63\x2e\x37\x02\xe5\xb7\x5c\xda\xb9\xa6\x2f" +
"\x15\x41",
expectedOutput: "{\"name\":\"myname\"}\n",
recipeConfig: [
{
op: "Avro to JSON",
args: [false]
}
],
}
]);

View File

@@ -79,7 +79,7 @@ TestRegister.addTests([
},
{
"op": "Decode text",
"args": ["UTF16LE (1200)"]
"args": ["UTF-16LE (1200)"]
},
{
"op": "Encode text",

File diff suppressed because one or more lines are too long