ByteRepr.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427
  1. /* globals app */
  2. import Utils from "../Utils.js";
  3. /**
  4. * Byte representation operations.
  5. *
  6. * @author n1474335 [n1474335@gmail.com]
  7. * @copyright Crown Copyright 2016
  8. * @license Apache-2.0
  9. *
  10. * @namespace
  11. */
  12. const ByteRepr = {
  13. /**
  14. * @constant
  15. * @default
  16. */
  17. DELIM_OPTIONS: ["Space", "Comma", "Semi-colon", "Colon", "Line feed", "CRLF"],
  18. /**
  19. * @constant
  20. * @default
  21. */
  22. HEX_DELIM_OPTIONS: ["Space", "Comma", "Semi-colon", "Colon", "Line feed", "CRLF", "0x", "\\x", "None"],
  23. /**
  24. * @constant
  25. * @default
  26. */
  27. BIN_DELIM_OPTIONS: ["Space", "Comma", "Semi-colon", "Colon", "Line feed", "CRLF", "None"],
  28. /**
  29. * To Hex operation.
  30. *
  31. * @param {byteArray} input
  32. * @param {Object[]} args
  33. * @returns {string}
  34. */
  35. runToHex: function(input, args) {
  36. const delim = Utils.charRep[args[0] || "Space"];
  37. return Utils.toHex(input, delim, 2);
  38. },
  39. /**
  40. * From Hex operation.
  41. *
  42. * @param {string} input
  43. * @param {Object[]} args
  44. * @returns {byteArray}
  45. */
  46. runFromHex: function(input, args) {
  47. const delim = args[0] || "Space";
  48. return Utils.fromHex(input, delim, 2);
  49. },
  50. /**
  51. * To Octal operation.
  52. *
  53. * @author Matt C [matt@artemisbot.pw]
  54. * @param {byteArray} input
  55. * @param {Object[]} args
  56. * @returns {string}
  57. */
  58. runToOct: function(input, args) {
  59. const delim = Utils.charRep[args[0] || "Space"];
  60. return input.map(val => val.toString(8)).join(delim);
  61. },
  62. /**
  63. * From Octal operation.
  64. *
  65. * @author Matt C [matt@artemisbot.pw]
  66. * @param {string} input
  67. * @param {Object[]} args
  68. * @returns {byteArray}
  69. */
  70. runFromOct: function(input, args) {
  71. const delim = Utils.charRep[args[0] || "Space"];
  72. if (input.length === 0) return [];
  73. return input.split(delim).map(val => parseInt(val, 8));
  74. },
  75. /**
  76. * @constant
  77. * @default
  78. */
  79. CHARCODE_BASE: 16,
  80. /**
  81. * To Charcode operation.
  82. *
  83. * @param {string} input
  84. * @param {Object[]} args
  85. * @returns {string}
  86. */
  87. runToCharcode: function(input, args) {
  88. let delim = Utils.charRep[args[0] || "Space"],
  89. base = args[1],
  90. output = "",
  91. padding = 2,
  92. ordinal;
  93. if (base < 2 || base > 36) {
  94. throw "Error: Base argument must be between 2 and 36";
  95. }
  96. for (let i = 0; i < input.length; i++) {
  97. ordinal = Utils.ord(input[i]);
  98. if (base === 16) {
  99. if (ordinal < 256) padding = 2;
  100. else if (ordinal < 65536) padding = 4;
  101. else if (ordinal < 16777216) padding = 6;
  102. else if (ordinal < 4294967296) padding = 8;
  103. else padding = 2;
  104. if (padding > 2 && app) app.options.attemptHighlight = false;
  105. output += Utils.hex(ordinal, padding) + delim;
  106. } else {
  107. if (app) app.options.attemptHighlight = false;
  108. output += ordinal.toString(base) + delim;
  109. }
  110. }
  111. return output.slice(0, -delim.length);
  112. },
  113. /**
  114. * From Charcode operation.
  115. *
  116. * @param {string} input
  117. * @param {Object[]} args
  118. * @returns {byteArray}
  119. */
  120. runFromCharcode: function(input, args) {
  121. let delim = Utils.charRep[args[0] || "Space"],
  122. base = args[1],
  123. bites = input.split(delim),
  124. i = 0;
  125. if (base < 2 || base > 36) {
  126. throw "Error: Base argument must be between 2 and 36";
  127. }
  128. if (base !== 16 && app) {
  129. app.options.attemptHighlight = false;
  130. }
  131. // Split into groups of 2 if the whole string is concatenated and
  132. // too long to be a single character
  133. if (bites.length === 1 && input.length > 17) {
  134. bites = [];
  135. for (i = 0; i < input.length; i += 2) {
  136. bites.push(input.slice(i, i+2));
  137. }
  138. }
  139. let latin1 = "";
  140. for (i = 0; i < bites.length; i++) {
  141. latin1 += Utils.chr(parseInt(bites[i], base));
  142. }
  143. return Utils.strToByteArray(latin1);
  144. },
  145. /**
  146. * Highlight to hex
  147. *
  148. * @param {Object[]} pos
  149. * @param {number} pos[].start
  150. * @param {number} pos[].end
  151. * @param {Object[]} args
  152. * @returns {Object[]} pos
  153. */
  154. highlightTo: function(pos, args) {
  155. let delim = Utils.charRep[args[0] || "Space"],
  156. len = delim === "\r\n" ? 1 : delim.length;
  157. pos[0].start = pos[0].start * (2 + len);
  158. pos[0].end = pos[0].end * (2 + len) - len;
  159. // 0x and \x are added to the beginning if they are selected, so increment the positions accordingly
  160. if (delim === "0x" || delim === "\\x") {
  161. pos[0].start += 2;
  162. pos[0].end += 2;
  163. }
  164. return pos;
  165. },
  166. /**
  167. * Highlight to hex
  168. *
  169. * @param {Object[]} pos
  170. * @param {number} pos[].start
  171. * @param {number} pos[].end
  172. * @param {Object[]} args
  173. * @returns {Object[]} pos
  174. */
  175. highlightFrom: function(pos, args) {
  176. let delim = Utils.charRep[args[0] || "Space"],
  177. len = delim === "\r\n" ? 1 : delim.length,
  178. width = len + 2;
  179. // 0x and \x are added to the beginning if they are selected, so increment the positions accordingly
  180. if (delim === "0x" || delim === "\\x") {
  181. if (pos[0].start > 1) pos[0].start -= 2;
  182. else pos[0].start = 0;
  183. if (pos[0].end > 1) pos[0].end -= 2;
  184. else pos[0].end = 0;
  185. }
  186. pos[0].start = pos[0].start === 0 ? 0 : Math.round(pos[0].start / width);
  187. pos[0].end = pos[0].end === 0 ? 0 : Math.ceil(pos[0].end / width);
  188. return pos;
  189. },
  190. /**
  191. * To Decimal operation.
  192. *
  193. * @param {byteArray} input
  194. * @param {Object[]} args
  195. * @returns {string}
  196. */
  197. runToDecimal: function(input, args) {
  198. const delim = Utils.charRep[args[0]];
  199. return input.join(delim);
  200. },
  201. /**
  202. * From Decimal operation.
  203. *
  204. * @param {string} input
  205. * @param {Object[]} args
  206. * @returns {byteArray}
  207. */
  208. runFromDecimal: function(input, args) {
  209. const delim = Utils.charRep[args[0]];
  210. let byteStr = input.split(delim), output = [];
  211. if (byteStr[byteStr.length-1] === "")
  212. byteStr = byteStr.slice(0, byteStr.length-1);
  213. for (let i = 0; i < byteStr.length; i++) {
  214. output[i] = parseInt(byteStr[i], 10);
  215. }
  216. return output;
  217. },
  218. /**
  219. * To Binary operation.
  220. *
  221. * @param {byteArray} input
  222. * @param {Object[]} args
  223. * @returns {string}
  224. */
  225. runToBinary: function(input, args) {
  226. let delim = Utils.charRep[args[0] || "Space"],
  227. output = "",
  228. padding = 8;
  229. for (let i = 0; i < input.length; i++) {
  230. output += Utils.pad(input[i].toString(2), padding) + delim;
  231. }
  232. if (delim.length) {
  233. return output.slice(0, -delim.length);
  234. } else {
  235. return output;
  236. }
  237. },
  238. /**
  239. * From Binary operation.
  240. *
  241. * @param {string} input
  242. * @param {Object[]} args
  243. * @returns {byteArray}
  244. */
  245. runFromBinary: function(input, args) {
  246. if (args[0] !== "None") {
  247. const delimRegex = Utils.regexRep[args[0] || "Space"];
  248. input = input.replace(delimRegex, "");
  249. }
  250. const output = [];
  251. const byteLen = 8;
  252. for (let i = 0; i < input.length; i += byteLen) {
  253. output.push(parseInt(input.substr(i, byteLen), 2));
  254. }
  255. return output;
  256. },
  257. /**
  258. * Highlight to binary
  259. *
  260. * @param {Object[]} pos
  261. * @param {number} pos[].start
  262. * @param {number} pos[].end
  263. * @param {Object[]} args
  264. * @returns {Object[]} pos
  265. */
  266. highlightToBinary: function(pos, args) {
  267. const delim = Utils.charRep[args[0] || "Space"];
  268. pos[0].start = pos[0].start * (8 + delim.length);
  269. pos[0].end = pos[0].end * (8 + delim.length) - delim.length;
  270. return pos;
  271. },
  272. /**
  273. * Highlight from binary
  274. *
  275. * @param {Object[]} pos
  276. * @param {number} pos[].start
  277. * @param {number} pos[].end
  278. * @param {Object[]} args
  279. * @returns {Object[]} pos
  280. */
  281. highlightFromBinary: function(pos, args) {
  282. const delim = Utils.charRep[args[0] || "Space"];
  283. pos[0].start = pos[0].start === 0 ? 0 : Math.floor(pos[0].start / (8 + delim.length));
  284. pos[0].end = pos[0].end === 0 ? 0 : Math.ceil(pos[0].end / (8 + delim.length));
  285. return pos;
  286. },
  287. /**
  288. * @constant
  289. * @default
  290. */
  291. HEX_CONTENT_CONVERT_WHICH: ["Only special chars", "Only special chars including spaces", "All chars"],
  292. /**
  293. * @constant
  294. * @default
  295. */
  296. HEX_CONTENT_SPACES_BETWEEN_BYTES: false,
  297. /**
  298. * To Hex Content operation.
  299. *
  300. * @param {byteArray} input
  301. * @param {Object[]} args
  302. * @returns {string}
  303. */
  304. runToHexContent: function(input, args) {
  305. const convert = args[0];
  306. const spaces = args[1];
  307. if (convert === "All chars") {
  308. let result = "|" + Utils.toHex(input) + "|";
  309. if (!spaces) result = result.replace(/ /g, "");
  310. return result;
  311. }
  312. let output = "",
  313. inHex = false,
  314. convertSpaces = convert === "Only special chars including spaces",
  315. b;
  316. for (let i = 0; i < input.length; i++) {
  317. b = input[i];
  318. if ((b === 32 && convertSpaces) || (b < 48 && b !== 32) || (b > 57 && b < 65) || (b > 90 && b < 97) || b > 122) {
  319. if (!inHex) {
  320. output += "|";
  321. inHex = true;
  322. } else if (spaces) output += " ";
  323. output += Utils.toHex([b]);
  324. } else {
  325. if (inHex) {
  326. output += "|";
  327. inHex = false;
  328. }
  329. output += Utils.chr(input[i]);
  330. }
  331. }
  332. if (inHex) output += "|";
  333. return output;
  334. },
  335. /**
  336. * From Hex Content operation.
  337. *
  338. * @param {string} input
  339. * @param {Object[]} args
  340. * @returns {byteArray}
  341. */
  342. runFromHexContent: function(input, args) {
  343. const regex = /\|([a-f\d ]{2,})\|/gi;
  344. let output = [], m, i = 0;
  345. while ((m = regex.exec(input))) {
  346. // Add up to match
  347. for (; i < m.index;)
  348. output.push(Utils.ord(input[i++]));
  349. // Add match
  350. const bytes = Utils.fromHex(m[1]);
  351. if (bytes) {
  352. for (let a = 0; a < bytes.length;)
  353. output.push(bytes[a++]);
  354. } else {
  355. // Not valid hex, print as normal
  356. for (; i < regex.lastIndex;)
  357. output.push(Utils.ord(input[i++]));
  358. }
  359. i = regex.lastIndex;
  360. }
  361. // Add all after final match
  362. for (; i < input.length;)
  363. output.push(Utils.ord(input[i++]));
  364. return output;
  365. },
  366. };
  367. export default ByteRepr;