ops.mjs 34 KB

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