ChangeIPFormat.mjs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. /**
  2. * @author n1474335 [n1474335@gmail.com]
  3. * @copyright Crown Copyright 2016
  4. * @license Apache-2.0
  5. */
  6. import Operation from "../Operation.mjs";
  7. import OperationError from "../errors/OperationError.mjs";
  8. import Utils from "../Utils.mjs";
  9. import {fromHex} from "../lib/Hex.mjs";
  10. /**
  11. * Change IP format operation
  12. */
  13. class ChangeIPFormat extends Operation {
  14. /**
  15. * ChangeIPFormat constructor
  16. */
  17. constructor() {
  18. super();
  19. this.name = "Change IP format";
  20. this.module = "Default";
  21. this.description = "Convert an IP address from one format to another, e.g. <code>172.20.23.54</code> to <code>ac141736</code>";
  22. this.inputType = "string";
  23. this.outputType = "string";
  24. this.args = [
  25. {
  26. "name": "Input format",
  27. "type": "option",
  28. "value": ["Dotted Decimal", "Decimal", "Octal", "Hex"]
  29. },
  30. {
  31. "name": "Output format",
  32. "type": "option",
  33. "value": ["Dotted Decimal", "Decimal", "Octal", "Hex"]
  34. }
  35. ];
  36. }
  37. /**
  38. * @param {string} input
  39. * @param {Object[]} args
  40. * @returns {string}
  41. */
  42. run(input, args) {
  43. const [inFormat, outFormat] = args,
  44. lines = input.split("\n");
  45. let output = "",
  46. j = 0;
  47. for (let i = 0; i < lines.length; i++) {
  48. if (lines[i] === "") continue;
  49. let baIp = [];
  50. let octets;
  51. if (inFormat === outFormat) {
  52. output += lines[i] + "\n";
  53. continue;
  54. }
  55. // Convert to byte array IP from input format
  56. switch (inFormat) {
  57. case "Dotted Decimal":
  58. octets = lines[i].split(".");
  59. for (j = 0; j < octets.length; j++) {
  60. baIp.push(parseInt(octets[j], 10));
  61. }
  62. break;
  63. case "Decimal":
  64. baIp = this.fromNumber(lines[i].toString(), 10);
  65. break;
  66. case "Octal":
  67. baIp = this.fromNumber(lines[i].toString(), 8);
  68. break;
  69. case "Hex":
  70. baIp = fromHex(lines[i]);
  71. break;
  72. default:
  73. throw new OperationError("Unsupported input IP format");
  74. }
  75. let ddIp;
  76. let decIp;
  77. let hexIp;
  78. // Convert byte array IP to output format
  79. switch (outFormat) {
  80. case "Dotted Decimal":
  81. ddIp = "";
  82. for (j = 0; j < baIp.length; j++) {
  83. ddIp += baIp[j] + ".";
  84. }
  85. output += ddIp.slice(0, ddIp.length-1) + "\n";
  86. break;
  87. case "Decimal":
  88. decIp = ((baIp[0] << 24) | (baIp[1] << 16) | (baIp[2] << 8) | baIp[3]) >>> 0;
  89. output += decIp.toString() + "\n";
  90. break;
  91. case "Octal":
  92. decIp = ((baIp[0] << 24) | (baIp[1] << 16) | (baIp[2] << 8) | baIp[3]) >>> 0;
  93. output += "0" + decIp.toString(8) + "\n";
  94. break;
  95. case "Hex":
  96. hexIp = "";
  97. for (j = 0; j < baIp.length; j++) {
  98. hexIp += Utils.hex(baIp[j]);
  99. }
  100. output += hexIp + "\n";
  101. break;
  102. default:
  103. throw new OperationError("Unsupported output IP format");
  104. }
  105. }
  106. return output.slice(0, output.length-1);
  107. }
  108. /**
  109. * Constructs an array of IP address octets from a numerical value.
  110. * @param {string} value The value of the IP address
  111. * @param {number} radix The numeral system to be used
  112. * @returns {number[]}
  113. */
  114. fromNumber(value, radix) {
  115. const decimal = parseInt(value, radix);
  116. const baIp = [];
  117. baIp.push(decimal >> 24 & 255);
  118. baIp.push(decimal >> 16 & 255);
  119. baIp.push(decimal >> 8 & 255);
  120. baIp.push(decimal & 255);
  121. return baIp;
  122. }
  123. }
  124. export default ChangeIPFormat;