Hex.mjs 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. /**
  2. * Hexadecimal functions.
  3. *
  4. * @author n1474335 [n1474335@gmail.com]
  5. * @copyright Crown Copyright 2016
  6. * @license Apache-2.0
  7. */
  8. import Utils from "../Utils.mjs";
  9. /**
  10. * Convert a byte array into a hex string.
  11. *
  12. * @param {byteArray|Uint8Array|ArrayBuffer} data
  13. * @param {string} [delim=" "]
  14. * @param {number} [padding=2]
  15. * @returns {string}
  16. *
  17. * @example
  18. * // returns "0a 14 1e"
  19. * toHex([10,20,30]);
  20. *
  21. * // returns "0a:14:1e"
  22. * toHex([10,20,30], ":");
  23. *
  24. * // returns "0x0a,0x14,0x1e"
  25. * toHex([10,20,30], "0x", 2, ",")
  26. */
  27. export function toHex(data, delim=" ", padding=2, extraDelim="", lineSize=0) {
  28. if (!data) return "";
  29. if (data instanceof ArrayBuffer) data = new Uint8Array(data);
  30. let output = "";
  31. const prepend = (delim === "0x" || delim === "\\x");
  32. for (let i = 0; i < data.length; i++) {
  33. const hex = data[i].toString(16).padStart(padding, "0");
  34. output += prepend ? delim + hex : hex + delim;
  35. if (extraDelim) {
  36. output += extraDelim;
  37. }
  38. // Add LF after each lineSize amount of bytes but not at the end
  39. if ((i !== data.length - 1) && ((i + 1) % lineSize === 0)) {
  40. output += "\n";
  41. }
  42. }
  43. // Remove the extraDelim at the end (if there is one)
  44. // and remove the delim at the end, but if it's prepended there's nothing to remove
  45. const rTruncLen = extraDelim.length + (prepend ? 0 : delim.length);
  46. if (rTruncLen) {
  47. // If rTruncLen === 0 then output.slice(0,0) will be returned, which is nothing
  48. return output.slice(0, -rTruncLen);
  49. } else {
  50. return output;
  51. }
  52. }
  53. /**
  54. * Convert a byte array into a hex string as efficiently as possible with no options.
  55. *
  56. * @param {byteArray|Uint8Array|ArrayBuffer} data
  57. * @returns {string}
  58. *
  59. * @example
  60. * // returns "0a141e"
  61. * toHex([10,20,30]);
  62. */
  63. export function toHexFast(data) {
  64. if (!data) return "";
  65. if (data instanceof ArrayBuffer) data = new Uint8Array(data);
  66. const output = [];
  67. for (let i = 0; i < data.length; i++) {
  68. output.push((data[i] >>> 4).toString(16));
  69. output.push((data[i] & 0x0f).toString(16));
  70. }
  71. return output.join("");
  72. }
  73. /**
  74. * Convert a hex string into a byte array.
  75. *
  76. * @param {string} data
  77. * @param {string} [delim]
  78. * @param {number} [byteLen=2]
  79. * @returns {byteArray}
  80. *
  81. * @example
  82. * // returns [10,20,30]
  83. * fromHex("0a 14 1e");
  84. *
  85. * // returns [10,20,30]
  86. * fromHex("0a:14:1e", "Colon");
  87. */
  88. export function fromHex(data, delim="Auto", byteLen=2) {
  89. if (delim !== "None") {
  90. const delimRegex = delim === "Auto" ? /[^a-f\d]|(0x)/gi : Utils.regexRep(delim);
  91. data = data.replace(delimRegex, "");
  92. }
  93. const output = [];
  94. for (let i = 0; i < data.length; i += byteLen) {
  95. output.push(parseInt(data.substr(i, byteLen), 16));
  96. }
  97. return output;
  98. }
  99. /**
  100. * To Hexadecimal delimiters.
  101. */
  102. export const TO_HEX_DELIM_OPTIONS = ["Space", "Percent", "Comma", "Semi-colon", "Colon", "Line feed", "CRLF", "0x", "0x with comma", "\\x", "None"];
  103. /**
  104. * From Hexadecimal delimiters.
  105. */
  106. export const FROM_HEX_DELIM_OPTIONS = ["Auto"].concat(TO_HEX_DELIM_OPTIONS);