ops.mjs 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973
  1. /* eslint no-console: 0 */
  2. /**
  3. * nodeApi.js
  4. *
  5. * Test node api operations
  6. *
  7. * Aim of these tests is to ensure each arg type is
  8. * handled correctly by the wrapper.
  9. *
  10. * Generally just checking operations that use external dependencies to ensure
  11. * it behaves as expected in Node.
  12. *
  13. * @author d98762625 [d98762625@gmail.com]
  14. * @copyright Crown Copyright 2018
  15. * @license Apache-2.0
  16. */
  17. import assert from "assert";
  18. import it from "../assertionHandler";
  19. import fs from "fs";
  20. import {
  21. addLineNumbers,
  22. adler32Checksum,
  23. AESDecrypt,
  24. affineCipherDecode,
  25. affineCipherEncode,
  26. bifidCipherEncode,
  27. bitShiftRight,
  28. cartesianProduct,
  29. CSSMinify,
  30. toBase64,
  31. toHex,
  32. } from "../../../src/node/index";
  33. import chef from "../../../src/node/index";
  34. import TestRegister from "../../TestRegister";
  35. TestRegister.addApiTests([
  36. it("ADD: toggleString argument", () => {
  37. const result = chef.ADD("sample input", {
  38. key: {
  39. string: "some key",
  40. option: "Hex"
  41. }
  42. });
  43. assert.equal(result.toString(), "aO[^ZS\u000eW\\^cb");
  44. }),
  45. it("addLineNumbers: No arguments", () => {
  46. const result = addLineNumbers("sample input");
  47. assert.equal(result.toString(), "1 sample input");
  48. }),
  49. it("adler32Checksum: No args", () => {
  50. const result = adler32Checksum("sample input");
  51. assert.equal(result.toString(), "1f2304d3");
  52. }),
  53. it("AES decrypt: toggleString and option", () => {
  54. const result = AESDecrypt("812c34ae6af353244a63c6ce23b7c34286b60be28ea4645523d4494700e7", {
  55. key: {
  56. string: "some longer key1",
  57. option: "utf8",
  58. },
  59. iv: {
  60. string: "some iv",
  61. option: "utf8",
  62. },
  63. mode: "OFB",
  64. });
  65. assert.equal(result.toString(), "a slightly longer sampleinput?");
  66. }),
  67. it("AffineCipherDecode: number input", () => {
  68. const result = affineCipherDecode("some input", {
  69. a: 7,
  70. b: 4
  71. });
  72. assert.strictEqual(result.toString(), "cuqa ifjgr");
  73. }),
  74. it("affineCipherEncode: number input", () => {
  75. const result = affineCipherEncode("some input", {
  76. a: 11,
  77. b: 6
  78. });
  79. assert.strictEqual(result.toString(), "weiy qtpsh");
  80. }),
  81. it("analyzeHash", () => {
  82. const result = chef.analyseHash(chef.MD5("some input"));
  83. const expected = `Hash length: 32
  84. Byte length: 16
  85. Bit length: 128
  86. Based on the length, this hash could have been generated by one of the following hashing functions:
  87. MD5
  88. MD4
  89. MD2
  90. HAVAL-128
  91. RIPEMD-128
  92. Snefru
  93. Tiger-128`;
  94. assert.strictEqual(result.toString(), expected);
  95. }),
  96. it("AND", () => {
  97. const result = chef.AND("Scot-free", {
  98. key: {
  99. string: "Raining Cats and Dogs",
  100. option: "Hex",
  101. }
  102. });
  103. assert.strictEqual(result.toString(), "\u0000\"M$(D E");
  104. }),
  105. it("atBash Cipher", () => {
  106. const result = chef.atbashCipher("Happy as a Clam");
  107. assert.strictEqual(result.toString(), "Szkkb zh z Xozn");
  108. }),
  109. it("Bcrypt", async () => {
  110. const result = await chef.bcrypt("Put a Sock In It");
  111. assert.strictEqual(result.toString(), "$2a$10$ODeP1.6fMsb.ENk2ngPUCO7qTGVPyHA9TqDVcyupyed8FjsiF65L6");
  112. }),
  113. it("bcryptCompare", async() => {
  114. const result = await chef.bcryptCompare("Put a Sock In It", {
  115. hash: "$2a$10$2rT4a3XnIecBsd1H33dMTuyYE1HJ1n9F.V2rjQtAH73rh1qvOf/ae",
  116. });
  117. assert.strictEqual(result.toString(), "Match: Put a Sock In It");
  118. }),
  119. it("Bcrypt Parse", async () => {
  120. const result = await chef.bcryptParse("$2a$10$ODeP1.6fMsb.ENk2ngPUCO7qTGVPyHA9TqDVcyupyed8FjsiF65L6");
  121. const expected = `Rounds: 10
  122. Salt: $2a$10$ODeP1.6fMsb.ENk2ngPUCO
  123. Password hash: 7qTGVPyHA9TqDVcyupyed8FjsiF65L6
  124. Full hash: $2a$10$ODeP1.6fMsb.ENk2ngPUCO7qTGVPyHA9TqDVcyupyed8FjsiF65L6`;
  125. assert.strictEqual(result.toString(), expected);
  126. }),
  127. it("bifid cipher decode", () => {
  128. const result = chef.bifidCipherDecode("Vhef Qnte Ke Xfhz Mxon Bmgf", {
  129. keyword: "Alpha",
  130. });
  131. assert.strictEqual(result.toString(), "What Goes Up Must Come Down");
  132. }),
  133. it("bifid cipher encode: string option", () => {
  134. const result = bifidCipherEncode("some input", {
  135. keyword: "mykeyword",
  136. });
  137. assert.strictEqual(result.toString(), "nmhs zmsdo");
  138. }),
  139. it("bit shift left", () => {
  140. const result = chef.bitShiftLeft("Keep Your Eyes Peeled");
  141. assert.strictEqual(result.toString(), "–ÊÊà@²Þêä@ŠòÊæ@ ÊÊØÊÈ");
  142. }),
  143. it("bitShiftRight: number and option", () => {
  144. const result = bitShiftRight("some bits to shift", {
  145. type: "Arithmetic shift",
  146. amount: 1,
  147. });
  148. assert.strictEqual(result.toString(), "9762\u001014:9\u0010:7\u00109443:");
  149. }),
  150. it("Blowfish encrypt", () => {
  151. const result = chef.blowfishEncrypt("Fool's Gold", {
  152. key: {
  153. string: "One",
  154. option: "hex",
  155. },
  156. iv: {
  157. string: "Two",
  158. option: "utf8"
  159. }
  160. });
  161. assert.strictEqual(result.toString(), "8999b513bf2ff064b2977dea7e05f1b5");
  162. }),
  163. it("Blowfish decrypt", () => {
  164. const result = chef.blowfishDecrypt("8999b513bf2ff064b2977dea7e05f1b5", {
  165. key: {
  166. string: "One",
  167. option: "hex",
  168. },
  169. iv: {
  170. string: "Two",
  171. option: "utf8",
  172. }
  173. });
  174. assert.strictEqual(result.toString(), "Fool's Gold");
  175. }),
  176. it("BSON Serialise / Deserialise", () => {
  177. const result = chef.BSONDeserialise(chef.BSONSerialise("{\"phrase\": \"Mouth-watering\"}"));
  178. assert.strictEqual(result.toString(), `{
  179. "phrase": "Mouth-watering"
  180. }`);
  181. }),
  182. it("Bzip2 Decompress", () => {
  183. const result = chef.bzip2Decompress(chef.fromBase64("QlpoOTFBWSZTWUdQlt0AAAIVgEAAAQAmJAwAIAAxBkxA0A2pTL6U2CozxdyRThQkEdQlt0A="));
  184. assert.strictEqual(result.toString(), "Fit as a Fiddle");
  185. }),
  186. it("cartesianProduct: binary string", () => {
  187. const result = cartesianProduct("1:2\\n\\n3:4", {
  188. itemDelimiter: ":",
  189. });
  190. assert.strictEqual(result.toString(), "(1,3):(1,4):(2,3):(2,4)");
  191. }),
  192. it("Change IP format", () => {
  193. const result = chef.changeIPFormat("172.20.23.54", {
  194. inputFormat: "Dotted Decimal",
  195. outputFormat: "Hex",
  196. });
  197. assert.strictEqual(result.toString(), "ac141736");
  198. }),
  199. it("Chi square", () => {
  200. const result = chef.chiSquare("Burst Your Bubble");
  201. assert.strictEqual(result.toString(), "433.55399816176475");
  202. }),
  203. it("Compare CTPH Hashes", () => {
  204. const result = chef.compareCTPHHashes("1234\n3456");
  205. assert.strictEqual(result.toString(), "0");
  206. }),
  207. it("Compare SSDEEPHashes", () => {
  208. const result = chef.compareCTPHHashes("1234\n3456");
  209. assert.strictEqual(result.toString(), "0");
  210. }),
  211. it("Convert area", () => {
  212. const result = chef.convertArea("12345", {
  213. inputUnits: "Square metre (sq m)",
  214. outputUnits: "Isle of Wight"
  215. });
  216. assert.strictEqual(result.toString(), "0.00003248684210526316");
  217. }),
  218. it("Convert data units", () => {
  219. const result = chef.convertDataUnits("12345", {
  220. inputUnits: "Bits (b)",
  221. outputUnits: "Kilobytes (KB)",
  222. });
  223. assert.strictEqual(result.toString(), "1.543125");
  224. }),
  225. it("Convert distance", () => {
  226. const result = chef.convertDistance("1234567", {
  227. inputUnits: "Nanometres (nm)",
  228. outputUnits: "Furlongs (fur)",
  229. });
  230. assert.strictEqual(result.toString(), "0.00000613699494949495");
  231. }),
  232. it("Convert mass", () => {
  233. const result = chef.convertMass("123", {
  234. inputUnits: "Earth mass (M⊕)",
  235. outputUnits: "Great Pyramid of Giza (6,000,000 tonnes)",
  236. });
  237. assert.strictEqual(result.toString(), "122429895000000000");
  238. }),
  239. it("Convert speed", () => {
  240. const result = chef.convertSpeed("123", {
  241. inputUnits: "Lunar escape velocity",
  242. outputUnits: "Jet airliner cruising speed",
  243. });
  244. assert.strictEqual(result.toString(), "1168.5");
  245. }),
  246. it("Count occurrences", () => {
  247. const result = chef.countOccurrences("Talk the Talk", {
  248. searchString: {
  249. string: "Tal",
  250. option: "Simple string",
  251. }
  252. });
  253. assert.strictEqual(result.toString(), "2");
  254. }),
  255. it("CRC16 Checksum", () => {
  256. const result = chef.CRC16Checksum("Rain on Your Parade");
  257. assert.strictEqual(result.toString(), "db1c");
  258. }),
  259. it("CRC32 Checksum", () => {
  260. const result = chef.CRC32Checksum("Rain on Your Parade");
  261. assert.strictEqual(result.toString(), "e902f76c");
  262. }),
  263. it("CSS Beautify", () => {
  264. const result = chef.CSSBeautify("header {color:black;padding:3rem;}");
  265. const expected = `header {
  266. \\tcolor:black;
  267. \\tpadding:3rem;
  268. }
  269. `;
  270. assert.strictEqual(result.toString(), expected);
  271. }),
  272. it("CSS minify: boolean", () => {
  273. const input = `header {
  274. // comment
  275. width: 100%;
  276. color: white;
  277. }`;
  278. const result = CSSMinify(input, {
  279. preserveComments: true,
  280. });
  281. assert.strictEqual(result.toString(), "header {// comment width: 100%;color: white;}");
  282. }),
  283. it("CSS Selector", () => {
  284. const result = chef.CSSSelector("<html><header><h1>Hello</h1></header></html>", {
  285. cssSelector: "h1",
  286. });
  287. assert.strictEqual(result.toString(), "<h1>Hello</h1>");
  288. }),
  289. it("CTPH", () => {
  290. const result = chef.CTPH("If You Can't Stand the Heat, Get Out of the Kitchen");
  291. assert.strictEqual(result.toString(), "A:+EgFgBKAA0V0UFfClEs6:+Qk0gUFse");
  292. }),
  293. it("Decode NetBIOS Name", () => {
  294. assert.strictEqual(chef.decodeNetBIOSName("EBGMGMCAEHHCGFGFGLCAFEGPCAENGFCA").toString(), "All Greek To Me");
  295. }),
  296. it("Decode text", () => {
  297. const encoded = chef.encodeText("Ugly Duckling", {
  298. encoding: "UTF16LE (1200)",
  299. });
  300. const result = chef.decodeText(encoded, {
  301. encoding: "UTF16LE (1200)",
  302. });
  303. assert.strictEqual(result.toString(), "Ugly Duckling");
  304. }),
  305. it("Derive EVP Key", () => {
  306. const result = chef.deriveEVPKey("", {
  307. passphrase: {
  308. string: "46 6c 65 61 20 4d 61 72 6b 65 74",
  309. option: "Hex",
  310. },
  311. salt: {
  312. string: "Market",
  313. option: "Hex",
  314. },
  315. });
  316. assert.strictEqual(result.toString(), "7c21a9f5063a4d62fb1050068245c181");
  317. }),
  318. it("Derive PBKDF2 Key", () => {
  319. const result = chef.derivePBKDF2Key("", {
  320. passphrase: {
  321. string: "Jack of All Trades Master of None",
  322. option: "utf8",
  323. },
  324. keySize: 256,
  325. iterations: 2,
  326. hashingFunction: "md5",
  327. salt: {
  328. string: "fruit",
  329. option: "utf8"
  330. }
  331. });
  332. assert.strictEqual(result.toString(), "728a885b209e8b19cbd7430ca32608ff09190f7ccb7ded204e1d4c50f87c47bf");
  333. }),
  334. it("DES Decrypt", () => {
  335. const result = chef.DESDecrypt("713081c66db781c323965ba8f166fd8c230c3bb48504a913", {
  336. key: {
  337. string: "onetwoth",
  338. option: "utf8",
  339. },
  340. iv: {
  341. string: "threetwo",
  342. option: "Hex",
  343. },
  344. mode: "ECB",
  345. });
  346. assert.strictEqual(result.toString(), "Put a Sock In It");
  347. }),
  348. it("DES Encrypt", () => {
  349. const result = chef.DESEncrypt("Put a Sock In It", {
  350. key: {
  351. string: "onetwoth",
  352. option: "utf8",
  353. },
  354. iv: {
  355. string: "threetwo",
  356. option: "Hex",
  357. },
  358. mode: "ECB",
  359. });
  360. assert.strictEqual(result.toString(), "713081c66db781c323965ba8f166fd8c230c3bb48504a913");
  361. }),
  362. it("Diff", () => {
  363. const result = chef.diff("one two\\n\\none two three");
  364. assert.strictEqual(result.toString(), "one two three");
  365. }),
  366. it("Disassemble x86", () => {
  367. const result = chef.disassembleX86(chef.toBase64("one two three"));
  368. const expected = `0000000000000000 0000 ADD BYTE PTR [RAX],AL\r
  369. 0000000000000002 0B250000000B OR ESP,DWORD PTR [000000000B000008]\r
  370. `;
  371. assert.strictEqual(result.toString(), expected);
  372. }),
  373. it("Divide", () => {
  374. assert.strictEqual(chef.divide("4\n7").toString(), "0.57142857142857142857");
  375. }),
  376. it("Drop bytes", () => {
  377. assert.strictEqual(chef.dropBytes("There's No I in Team").toString(), "'s No I in Team");
  378. }),
  379. it("Entropy", () => {
  380. const result = chef.entropy("Ride Him, Cowboy!");
  381. assert.strictEqual(result.toString(), "3.734521664779752");
  382. }),
  383. it("Escape string", () => {
  384. const result = chef.escapeString("Know the Ropes", {
  385. escapeLevel: "Everything",
  386. JSONCompatible: false,
  387. ES6Compatible: true,
  388. uppercaseHex: true,
  389. });
  390. assert.strictEqual(result.toString(), "\\x4B\\x6E\\x6F\\x77\\x20\\x74\\x68\\x65\\x20\\x52\\x6F\\x70\\x65\\x73");
  391. }),
  392. it("Escape unicode characters", () => {
  393. assert.strictEqual(chef.escapeUnicodeCharacters("σου").toString(), "\\u03C3\\u03BF\\u03C5");
  394. }),
  395. it("Expand alphabet range", () => {
  396. assert.strictEqual(
  397. chef.expandAlphabetRange("Fight Fire With Fire", {delimiter: "t"}).toString(),
  398. "Ftitgthttt tFtitrtet tWtitttht tFtitrte");
  399. }),
  400. it("Extract dates", () => {
  401. assert.strictEqual(chef.extractDates("Don't Look a Gift Horse In The Mouth 01/02/1992").toString(), "01/02/1992\n");
  402. }),
  403. it("Filter", () => {
  404. const result = chef.filter(
  405. `I Smell a Rat
  406. Every Cloud Has a Silver Lining
  407. Top Drawer`, {
  408. regex: "Every",
  409. });
  410. const expected = "Every Cloud Has a Silver Lining";
  411. assert.strictEqual(result.toString(), expected);
  412. }),
  413. it("Find / Replace", () => {
  414. assert.strictEqual(
  415. chef.findReplace(
  416. "Curiosity Killed The Cat",
  417. {
  418. find: {
  419. string: "l",
  420. option: "Regex",
  421. },
  422. replace: "s",
  423. }).toString(),
  424. "Curiosity Kissed The Cat");
  425. }),
  426. it("Fletcher8 Checksum", () => {
  427. assert.strictEqual(chef.fletcher8Checksum("Keep Your Eyes Peeled").toString(), "48");
  428. }),
  429. it("Format MAC addresses", () => {
  430. const result = chef.formatMACAddresses("00-01-02-03-04-05");
  431. const expected = `000102030405
  432. 000102030405
  433. 00-01-02-03-04-05
  434. 00-01-02-03-04-05
  435. 00:01:02:03:04:05
  436. 00:01:02:03:04:05
  437. `;
  438. assert.strictEqual(result.toString(), expected);
  439. }),
  440. it("Frequency distribution", () => {
  441. const result = chef.frequencyDistribution("Don't Count Your Chickens Before They Hatch");
  442. const expected = "{\"dataLength\":43,\"percentages\":[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,13.953488372093023,0,0,0,0,0,0,2.3255813953488373,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.3255813953488373,4.651162790697675,2.3255813953488373,0,0,0,2.3255813953488373,0,0,0,0,0,0,0,0,0,0,0,2.3255813953488373,0,0,0,0,2.3255813953488373,0,0,0,0,0,0,0,2.3255813953488373,0,4.651162790697675,0,9.30232558139535,2.3255813953488373,0,6.976744186046512,2.3255813953488373,0,2.3255813953488373,0,0,6.976744186046512,9.30232558139535,0,0,4.651162790697675,2.3255813953488373,6.976744186046512,4.651162790697675,0,0,0,2.3255813953488373,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,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,0,0,0,0,0,0,0,0,0,0,0,0],\"distribution\":[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,6,0,0,0,0,0,0,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,1,2,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,2,0,4,1,0,3,1,0,1,0,0,3,4,0,0,2,1,3,2,0,0,0,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,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,0,0,0,0,0,0,0,0,0,0,0,0],\"bytesRepresented\":22}";
  443. assert.strictEqual(result.toString(), expected);
  444. }),
  445. it("From base", () => {
  446. assert.strictEqual(chef.fromBase("11", {radix: 13}).toString(), "14");
  447. }),
  448. it("From BCD", () => {
  449. assert.strictEqual(chef.fromBCD("1143", { inputFormat: "Raw", scheme: "7 4 2 1"}).toString(), "31313433");
  450. }),
  451. it("From binary", () => {
  452. assert.strictEqual(chef.fromBinary("010101011100101101011010").toString(), "UËZ");
  453. }),
  454. it("From Charcode", () => {
  455. assert.strictEqual(chef.fromCharcode("4c 6f 6e 67 20 49 6e 20 54 68 65 20 54 6f 6f 74 68 0a").toString(), "Long In The Tooth\n");
  456. }),
  457. it("From decimal", () => {
  458. assert.strictEqual(chef.fromDecimal("72 101 108 108 111").toString(), "Hello");
  459. }),
  460. it("From hex", () => {
  461. assert.strictEqual(chef.fromHex("52 69 6e 67 20 41 6e 79 20 42 65 6c 6c 73 3f").toString(), "Ring Any Bells?");
  462. }),
  463. it("From hex content", () => {
  464. assert.strictEqual(chef.fromHexContent("foo|3d|bar").toString(), "foo=bar");
  465. }),
  466. it("To and From hex dump", () => {
  467. assert.strictEqual(chef.fromHexdump(chef.toHexdump("Elephant in the Room")).toString(), "Elephant in the Room");
  468. }),
  469. it("From HTML entity", () => {
  470. assert.strictEqual(chef.fromHTMLEntity("&amp;").toString(), "&");
  471. }),
  472. it("To and From morse code", () => {
  473. assert.strictEqual(chef.fromMorseCode(chef.toMorseCode("Put a Sock In It")).toString(), "PUT A SOCK IN IT");
  474. }),
  475. it("From octal", () => {
  476. assert.strictEqual(chef.fromOctal("113 156 157 167 40 164 150 145 40 122 157 160 145 163").toString(), "Know the Ropes");
  477. }),
  478. it("To, From punycode", () => {
  479. assert.strictEqual(chef.fromPunycode(chef.toPunycode("münchen")).toString(), "münchen");
  480. }),
  481. it("From unix timestamp", () => {
  482. assert.strictEqual(chef.fromUNIXTimestamp("978346800").toString(), "Mon 1 January 2001 11:00:00 UTC");
  483. }),
  484. it("Generate HOTP", () => {
  485. const result = chef.generateHOTP("Cut The Mustard", {
  486. name: "colonel",
  487. });
  488. const expected = `URI: otpauth://hotp/colonel?secret=IN2XIICUNBSSATLVON2GC4TE
  489. Password: 034148`;
  490. assert.strictEqual(result.toString(), expected);
  491. }),
  492. it("Generate PGP Key Pair", async () => {
  493. const result = await chef.generatePGPKeyPair("Back To the Drawing Board", {
  494. keyType: "ECC-256",
  495. });
  496. const expected = `-----BEGIN PGP PRIVATE KEY BLOCK-----
  497. Version: Keybase OpenPGP v2.0.77
  498. Comment: https://keybase.io/crypto
  499. xYgEW3KciQEBAK96Lx9G0WZiw1yhC35IogdumoxEJXsLdAVIjmskXeAfABEBAAEA
  500. AP4wK+OZu3AqojwtRoyIK1pHKU93OAuam1iaLCOGCwCckQCA5PjU0aLNZqy/eKyX
  501. T3rpKQCAxDDT5hHGAUfFPUu73KWABwB/WKpeUp7KwurMSbYVhgr1TijszQDCVAQT
  502. AQoAHgUCW3KciQIbLwMLCQcDFQoIAh4BAheAAxYCAQIZAQAKCRD0VeyUMgmpz3OE
  503. AP9qsnhhoK85Tnu6VKwKm1iMiJAssDQnFztDaMmmVdrN/MeIBFtynIkBAQDDhjIw
  504. fxOprqVMYLk6aC45JyPAA2POzu0Zb/rx0tKeBwARAQABAAD/XAr66oiP9ZORHiT0
  505. XZH4m7vwZt7AHuq4pYtVlMQXk60AgPw2Mno/wStvE/SBa9R7AtsAgMZ2BkJjvNPZ
  506. 9YA6cl4lW0UAgI1+kJVLZ5VR9fPENfJR80EtncKDBBgBCgAPBQJbcpyJBQkPCZwA
  507. AhsuAEgJEPRV7JQyCanPPSAEGQEKAAYFAltynIkACgkQrewgWMQZ/b2blwD/dbwh
  508. /3F9xv+YGAwq8i1mzzswg4qBct6LoSIjGglULT9RIQD/cYd31YfKrEnbSBWD5PLi
  509. zcSsxtBGKphwXiPAlQJ1Q5DHiARbcpyJAQEAs8V418lf1T74PpAwdBTiViEUX9jB
  510. e+ZrAEVaq5nu1C8AEQEAAQAA/iPWhS23hnRTllealR4/H5OofZRwxvIQrxAJp6z1
  511. ICRxAIDayRpCAbK5EC3DzRU2z4VpAIDSWYSs9inI1VTfamJPMWHXAIC3aaukzCP4
  512. GEGeFobX/thnKhnCgwQYAQoADwUCW3KciQUJA8JnAAIbLgBICRD0VeyUMgmpzz0g
  513. BBkBCgAGBQJbcpyJAAoJEB4jzL1hmQIXamUA/0c1M6BSqVtxNowPcOAXKYIxMca1
  514. VFcRWolHnZqdZQ7k/J8A/3HvNLRS3p1HvjQEfXl/qKoRRn843Py09ptDHh+xpGKh
  515. =d+Vp
  516. -----END PGP PRIVATE KEY BLOCK-----
  517. -----BEGIN PGP PUBLIC KEY BLOCK-----
  518. Version: Keybase OpenPGP v2.0.77
  519. Comment: https://keybase.io/crypto
  520. xi0EW3KciQEBAK96Lx9G0WZiw1yhC35IogdumoxEJXsLdAVIjmskXeAfABEBAAHN
  521. AMJUBBMBCgAeBQJbcpyJAhsvAwsJBwMVCggCHgECF4ADFgIBAhkBAAoJEPRV7JQy
  522. CanPc4QA/2qyeGGgrzlOe7pUrAqbWIyIkCywNCcXO0NoyaZV2s38zi0EW3KciQEB
  523. AMOGMjB/E6mupUxguTpoLjknI8ADY87O7Rlv+vHS0p4HABEBAAHCgwQYAQoADwUC
  524. W3KciQUJDwmcAAIbLgBICRD0VeyUMgmpzz0gBBkBCgAGBQJbcpyJAAoJEK3sIFjE
  525. Gf29m5cA/3W8If9xfcb/mBgMKvItZs87MIOKgXLei6EiIxoJVC0/USEA/3GHd9WH
  526. yqxJ20gVg+Ty4s3ErMbQRiqYcF4jwJUCdUOQzi0EW3KciQEBALPFeNfJX9U++D6Q
  527. MHQU4lYhFF/YwXvmawBFWquZ7tQvABEBAAHCgwQYAQoADwUCW3KciQUJA8JnAAIb
  528. LgBICRD0VeyUMgmpzz0gBBkBCgAGBQJbcpyJAAoJEB4jzL1hmQIXamUA/0c1M6BS
  529. qVtxNowPcOAXKYIxMca1VFcRWolHnZqdZQ7k/J8A/3HvNLRS3p1HvjQEfXl/qKoR
  530. Rn843Py09ptDHh+xpGKh
  531. =ySwG
  532. -----END PGP PUBLIC KEY BLOCK-----`;
  533. assert.strictEqual(result.toString(), expected);
  534. }),
  535. it("Generate UUID", () => {
  536. const result = chef.generateUUID();
  537. assert.ok(result.toString());
  538. assert.strictEqual(result.toString().length, 36);
  539. }),
  540. it("Gzip, Gunzip", () => {
  541. assert.strictEqual(chef.gunzip(chef.gzip("Down To The Wire")).toString(), "Down To The Wire");
  542. }),
  543. it("Hex to Object Identifier", () => {
  544. assert.strictEqual(
  545. chef.hexToObjectIdentifier(chef.toHex("You Can't Teach an Old Dog New Tricks")).toString(),
  546. "2.9.111.117.32.67.97.110.39.116.32.84.101.97.99.104.32.97.110.32.79.108.100.32.68.111.103.32.78.101.119.32.84.114.105.99.107.115");
  547. }),
  548. it("Hex to PEM", () => {
  549. const result = chef.hexToPEM(chef.toHex("Yada Yada"));
  550. const expected = `-----BEGIN CERTIFICATE-----\r
  551. WWFkYSBZYWRh\r
  552. -----END CERTIFICATE-----\r\n`;
  553. assert.strictEqual(result.toString(), expected);
  554. }),
  555. it("HMAC", () => {
  556. assert.strictEqual(chef.HMAC("On Cloud Nine", {key: "idea"}).toString(), "b128b48ec0d6b0f1a27220c396d0f3e5");
  557. }),
  558. it("JPathExpression", () => {
  559. assert.strictEqual(chef.JPathExpression("{\"key\" : \"value\"}", {query: "$.key"}).toString(), "\"value\"");
  560. }),
  561. it("JSON Beautify", () => {
  562. assert.strictEqual(
  563. chef.JSONBeautify("{\"key\" : \"value\"}").toString(),
  564. `{
  565. \\t"key": "value"
  566. }`);
  567. }),
  568. it("Keccak", () => {
  569. assert.strictEqual(chef.keccak("Flea Market").toString(), "c2a06880b19e453ee5440e8bd4c2024bedc15a6630096aa3f609acfd2b8f15f27cd293e1cc73933e81432269129ce954a6138889ce87831179d55dcff1cc7587");
  570. }),
  571. it("MD6", () => {
  572. assert.strictEqual(chef.MD6("Head Over Heels", {key: "arty"}).toString(), "d8f7fe4931fbaa37316f76283d5f615f50ddd54afdc794b61da522556aee99ad");
  573. }),
  574. it("Parse ASN.1 Hex string", () => {
  575. assert.strictEqual(chef.parseASN1HexString(chef.toHex("Mouth-watering")).toString(), "UNKNOWN(4d) 7574682d7761746572696e67\n");
  576. }),
  577. it("Parse DateTime", () => {
  578. const result = chef.parseDateTime("06/07/2001 01:59:30");
  579. const expected = `Date: Friday 6th July 2001
  580. Time: 01:59:30
  581. Period: AM
  582. Timezone: UTC
  583. UTC offset: +0000
  584. Daylight Saving Time: false
  585. Leap year: false
  586. Days in this month: 31
  587. Day of year: 187
  588. Week number: 2001
  589. Quarter: 3`;
  590. assert.strictEqual(result.toString(), expected);
  591. }),
  592. it("Parse IPV6 address", () => {
  593. const result = chef.parseIPv6Address("2001:0db8:85a3:0000:0000:8a2e:0370:7334");
  594. const expected = `Longhand: 2001:0db8:85a3:0000:0000:8a2e:0370:7334
  595. Shorthand: 2001:db8:85a3::8a2e:370:7334
  596. This is a documentation IPv6 address. This range should be used whenever an example IPv6 address is given or to model networking scenarios. Corresponds to 192.0.2.0/24, 198.51.100.0/24, and 203.0.113.0/24 in IPv4.
  597. Documentation range: 2001:db8::/32`;
  598. assert.strictEqual(result.toString(), expected);
  599. }),
  600. it("Parse URI", () => {
  601. const result = chef.parseURI("https://www.google.co.uk/search?q=almonds");
  602. const expected = `Protocol: https:
  603. Hostname: www.google.co.uk
  604. Path name: /search
  605. Arguments:
  606. \tq = almonds
  607. `;
  608. assert.strictEqual(result.toString(), expected);
  609. }),
  610. it("Parse user agent", () => {
  611. const result = chef.parseUserAgent("Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0 ");
  612. const expected = `Browser
  613. Name: Mozilla
  614. Version: 5.0
  615. Device
  616. Model: unknown
  617. Type: unknown
  618. Vendor: unknown
  619. Engine
  620. Name: Gecko
  621. Version: 47.0
  622. OS
  623. Name: Windows
  624. Version: 7
  625. CPU
  626. Architecture: amd64`;
  627. assert.strictEqual(result.toString(), expected);
  628. }),
  629. it("PGP Encrypt", async () => {
  630. const pbkey = `-----BEGIN PGP PUBLIC KEY BLOCK-----
  631. Version: GnuPG v1
  632. mI0EVWOihAEEALzwFAVWTrD0KiWCH5tX6q6QsGjlRn4IP2uj/xWsJZDNbCKm+JAe
  633. 1RvIootpW1+PNNMJlIInwUgtCjtJ9gZbGBpXeqwdSn0oYuj9X86ekXOUnZsRoPCj
  634. RwS8kpbrvRVfhWN8hYuXFcXK2J2Ld0ZpVyJzkncpFdpAgzTPMfrO1HS5ABEBAAG0
  635. GmdwZyBuYW1lIChjb21tZW50KSA8ZW1AaWw+iLgEEwECACIFAlVjooQCGwMGCwkI
  636. BwMCBhUIAgkKCwQWAgMBAh4BAheAAAoJEBg8dTRwi4g5I40D/2+uUuQxa3uMrAeI
  637. dXLaJWz3V0cl1rotfBP47apDUGbkm1HVgULJUo8Bo15Ii83ST8TUsyja3XcLutHb
  638. IwYSWo41gEV48+NKoN6Oy3HwqBoHfH06bu0If75vdSjnZpB2dO/Ph7L9kz78gc4y
  639. tZx4bE64MTlL2AYghZxyYpFyydjXuI0EVWOihAEEANE4UU+4iB2hMAXq93hiBzIh
  640. AMtn/DlWbJkpdUgrjKOG6tILs28mrw9rI4PivmT7grkyNW8sa3ATsmWC1xChxGTN
  641. T1guyh0Hhbc3Otfng2BFSWcBkPwUoNaOdrVFpP9J51IYrsQHsjbZlY45ghDBzM6t
  642. sISfkmmFCsp0l7w/XAcvABEBAAGInwQYAQIACQUCVWOihAIbDAAKCRAYPHU0cIuI
  643. OQ2BA/9KWqOhXZW75ac7CuJMfileZR7vRy9CkKyNG21cZtAlqftAX+m8FGdG0duU
  644. jKHiPvjXhSfP3lmrQ7brja9LgSzkiBqQzvPW55G67nGQdUC+mqZNJNlRh+8atf9I
  645. 5nxg2i8zn6F5cLaNWz7cl27m1/mXKcH3gult1PLR4PiYLiC9aw==
  646. =xw3e
  647. -----END PGP PUBLIC KEY BLOCK-----`;
  648. const result = await chef.PGPEncrypt("A Fool and His Money are Soon Parted", {
  649. publicKeyOfRecipient: pbkey,
  650. });
  651. const expected = `-----BEGIN PGP MESSAGE-----
  652. Version: Keybase OpenPGP v2.0.77
  653. Comment: https://keybase.io/crypto
  654. wYwDv1kIXPPNwmABA/4syW+oO+S/mfpjdp83/MZJiKh6XNQoPr/N5/1Is/QXYu9V
  655. /v8/b+eReOpUVC6cVrJ8U5cB19y1Az3NQWHXLEC0jND2wL3cUM4sv87hlvv2PLhc
  656. okv8OHNCitRiweo7NZHVygHGdFvY082G47e1PkyPAuVynvzdD450ta/s/KOxZdJg
  657. ARbZIrC6WmjYNLwhbpRYawKD+3N4I5qliRpU2POKRi9UROAW9dth6egy60TTCvyO
  658. jmPGsv1elXxVzqs58UZLD2c3vBhGkU2BV6kRKh+lj/EcVrzsFhGCz/7DKxPoDHLS
  659. =IBYt
  660. -----END PGP MESSAGE-----
  661. `;
  662. assert.strictEqual(result.toString(), expected);
  663. }),
  664. it("Raw deflate", () => {
  665. assert.strictEqual(chef.rawInflate(chef.rawDeflate("Like Father Like Son", { compressionType: "Fixed Huffman Coding"})).toString(), "Like Father Like Son");
  666. }),
  667. it("RC4", () => {
  668. assert.strictEqual(
  669. chef.RC4("Go Out On a Limb", {passphrase: {string: "Under Your Nose", option: "UTF8"}, inputFormat: "UTF8", outputFormat: "Hex"}).toString(),
  670. "7d17e60d9bc94b7f4095851c729e69a2");
  671. }),
  672. it("RC4 Drop", () => {
  673. assert.strictEqual(
  674. chef.RC4Drop("Go Out On a Limb", {passphrase: {string: "Under Your Nose", option: "UTF8"}, inputFormat: "UTF8", outputFormat: "Hex"}).toString(),
  675. "8fa5f2751d34476a0c857439f43816cf");
  676. }),
  677. it("Regular Expression", () => {
  678. assert.strictEqual(chef.regularExpression("Wouldn't Harm a Fly", {regex: "\\'[a-z]"}).toString(), "Wouldn't Harm a Fly");
  679. }),
  680. it("Remove EXIF", () => {
  681. const result = chef.removeEXIF(fs.readFileSync("test/tests/nodeApi/sampleData/pic.jpg"));
  682. assert.strictEqual(result.toString().length(), 4582);
  683. }),
  684. it("Scan for embedded files", () => {
  685. const result = chef.scanForEmbeddedFiles(fs.readFileSync("test/tests/nodeApi/sampleData/pic.jpg"));
  686. const expected = `Scanning data for 'magic bytes' which may indicate embedded files. The following results may be false positives and should not be treat as reliable. Any suffiently long file is likely to contain these magic bytes coincidentally.
  687. Offset 0 (0x00):
  688. File extension: jpg
  689. MIME type: image/jpeg
  690. Offset 30 (0x1e):
  691. File extension: tif
  692. MIME type: image/tiff
  693. Offset 212 (0xd4):
  694. File extension: txt
  695. MIME type: text/plain
  696. Description: UTF-8 encoded Unicode byte order mark detected, commonly but not exclusively seen in text files.
  697. 16 file types were detected that have common byte sequences. These are likely to be false positives. Run this operation with the 'Ignore common byte sequences' option unchecked to see details.`;
  698. assert.strictEqual(result.toString(), expected);
  699. }),
  700. it("Scrypt", () => {
  701. assert.strictEqual(
  702. chef.scrypt("Playing For Keeps", {salt: {string: "salty", option: "Hex"}}).toString(),
  703. "5446b6d86d88515894a163201765bceed0bc39610b1506cdc4d939ffc638bc46e051bce756e2865165d89d955a43a7eb5504502567dea8bfc9e7d49aaa894c07");
  704. }),
  705. it("SHA3", () => {
  706. assert.strictEqual(
  707. chef.SHA3("benign gravel").toString(),
  708. "2b1e36e0dbe151a89887be08da3bad141908cce62327f678161bcf058627e87abe57e3c5fce6581678714e6705a207acbd5c1f37f7a812280bc2cc558f00bed9");
  709. }),
  710. it("Shake", () => {
  711. assert.strictEqual(
  712. chef.shake("murderous bloodshed").toString(),
  713. "b79b3bb88099330bc6a15122f8dfaededf57a33b51c748d5a94e8122ff18d21e12f83412926b7e4a77a85ba6f36aa4841685e78296036337175e40096b5ac000");
  714. }),
  715. it("Snefru", () => {
  716. assert.strictEqual(
  717. chef.snefru("demeaning milestone").toString(),
  718. "a671b48770fe073ce49e9259cc2f47d345a53712639f8ae23c5ad3fec19540a5");
  719. }),
  720. it("SQL Beautify", () => {
  721. const result = chef.SQLBeautify(`SELECT MONTH, ID, RAIN_I, TEMP_F
  722. FROM STATS;`);
  723. const expected = `SELECT MONTH,
  724. ID,
  725. RAIN_I,
  726. TEMP_F
  727. FROM STATS;`;
  728. assert.strictEqual(result.toString(), expected);
  729. }),
  730. it("SSDEEP", () => {
  731. assert.strictEqual(
  732. chef.SSDEEP("shotgun tyranny snugly").toString(),
  733. "3:DLIXzMQCJc:XERKc");
  734. }),
  735. it("strings", () => {
  736. const result = chef.strings("smothering ampersand abreast", {displayTotal: true});
  737. const expected = `Total found: 1
  738. smothering ampersand abreast
  739. `;
  740. assert.strictEqual(result.toString(), expected);
  741. }),
  742. it("toBase64: editableOption", () => {
  743. const result = toBase64("some input", {
  744. alphabet: {
  745. value: "0-9A-W"
  746. },
  747. });
  748. assert.strictEqual(result.toString(), "SPI1R1T0");
  749. }),
  750. it("toBase64: editableOptions key is value", () => {
  751. const result = toBase64("some input", {
  752. alphabet: "0-9A-W",
  753. });
  754. assert.strictEqual(result.toString(), "SPI1R1T0");
  755. }),
  756. it("toBase64: editableOptions default", () => {
  757. const result = toBase64("some input");
  758. assert.strictEqual(result.toString(), "c29tZSBpbnB1dA==");
  759. }),
  760. it("To BCD", () => {
  761. assert.strictEqual(chef.toBCD("443").toString(), "0100 0100 0011");
  762. }),
  763. it("To CamelCase", () => {
  764. assert.strictEqual(chef.toCamelCase("Quickest Wheel").toString(), "quickestWheel");
  765. }),
  766. it("toHex: accepts args", () => {
  767. const result = toHex("some input", {
  768. delimiter: "Colon",
  769. });
  770. assert.strictEqual(result.toString(), "73:6f:6d:65:20:69:6e:70:75:74");
  771. }),
  772. it("To Kebab case", () => {
  773. assert.strictEqual(chef.toKebabCase("Elfin Gold").toString(), "elfin-gold");
  774. }),
  775. it("To punycode", () => {
  776. assert.strictEqual(chef.toPunycode("♠ ♣ ♥ ♦ ← ↑ ‍ →").toString(), " -m06cw7klao368lfb3aq");
  777. }),
  778. it("to snake case", () => {
  779. assert.strictEqual(chef.toSnakeCase("Abhorrent Grass").value, "abhorrent_grass");
  780. }),
  781. it("to unix timestamp", () => {
  782. assert.strictEqual(chef.toUNIXTimestamp("04-01-2001").toString(), "986083200 (Sun 1 April 2001 00:00:00 UTC)");
  783. }),
  784. it("Translate DateTime format", () => {
  785. assert.strictEqual(chef.translateDateTimeFormat("01/04/1999 22:33:01").toString(), "Thursday 1st April 1999 22:33:01 +00:00 UTC");
  786. }),
  787. it("Triple DES encrypt / decrypt", () => {
  788. assert.strictEqual(
  789. chef.tripleDESDecrypt(
  790. chef.tripleDESEncrypt("Destroy Money", {key: {string: "30 31 2f 30 34 2f 31 39 39 39 20 32 32 3a 33 33 3a 30 3130 31 2f 30 34", option: "Hex"}}),
  791. {key: {string: "30 31 2f 30 34 2f 31 39 39 39 20 32 32 3a 33 33 3a 30 3130 31 2f 30 34", option: "Hex"}}).toString(),
  792. "Destroy Money");
  793. }),
  794. it("UNIX Timestamp to Windows Filetime", () => {
  795. assert.strictEqual(chef.UNIXTimestampToWindowsFiletime("2020735").toString(), "116464943350000000");
  796. }),
  797. it("XML Beautify", () => {
  798. assert.strictEqual(
  799. chef.XMLBeautify("<contact-info><company>abc</company></contact-info>").toString(),
  800. `<contact-info>
  801. \\t<company>abc</company>
  802. </contact-info>`);
  803. }),
  804. it("XPath expression", () => {
  805. assert.strictEqual(
  806. chef.XPathExpression("<contact-info><company>abc</company></contact-info>", {xPath: "contact-info/company"}).toString(),
  807. "<company>abc</company>");
  808. }),
  809. it("Zlib deflate / inflate", () => {
  810. assert.strictEqual(chef.zlibInflate(chef.zlibDeflate("cut homer wile rooky grits dizen")).toString(), "cut homer wile rooky grits dizen");
  811. }),
  812. it("Detect file type", () => {
  813. assert.strictEqual(
  814. chef.detectFileType(fs.readFileSync("test/tests/nodeApi/sampleData/pic.jpg")).toString(),
  815. `File extension: jpg
  816. MIME type: image/jpeg`);
  817. }),
  818. it("extract EXIF", () => {
  819. assert.strictEqual(
  820. chef.extractEXIF(fs.readFileSync("test/tests/nodeApi/sampleData/pic.jpg")).toString(),
  821. `Found 7 tags.
  822. Orientation: 1
  823. XResolution: 72
  824. YResolution: 72
  825. ResolutionUnit: 2
  826. ColorSpace: 1
  827. ExifImageWidth: 57
  828. ExifImageHeight: 57`);
  829. }),
  830. ]);