isIP.js 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.default = isIP;
  6. var _assertString = _interopRequireDefault(require("./util/assertString"));
  7. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  8. var ipv4Maybe = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/;
  9. var ipv6Block = /^[0-9A-F]{1,4}$/i;
  10. function isIP(str) {
  11. var version = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
  12. (0, _assertString.default)(str);
  13. version = String(version);
  14. if (!version) {
  15. return isIP(str, 4) || isIP(str, 6);
  16. } else if (version === '4') {
  17. if (!ipv4Maybe.test(str)) {
  18. return false;
  19. }
  20. var parts = str.split('.').sort(function (a, b) {
  21. return a - b;
  22. });
  23. return parts[3] <= 255;
  24. } else if (version === '6') {
  25. var blocks = str.split(':');
  26. var foundOmissionBlock = false; // marker to indicate ::
  27. // At least some OS accept the last 32 bits of an IPv6 address
  28. // (i.e. 2 of the blocks) in IPv4 notation, and RFC 3493 says
  29. // that '::ffff:a.b.c.d' is valid for IPv4-mapped IPv6 addresses,
  30. // and '::a.b.c.d' is deprecated, but also valid.
  31. var foundIPv4TransitionBlock = isIP(blocks[blocks.length - 1], 4);
  32. var expectedNumberOfBlocks = foundIPv4TransitionBlock ? 7 : 8;
  33. if (blocks.length > expectedNumberOfBlocks) {
  34. return false;
  35. } // initial or final ::
  36. if (str === '::') {
  37. return true;
  38. } else if (str.substr(0, 2) === '::') {
  39. blocks.shift();
  40. blocks.shift();
  41. foundOmissionBlock = true;
  42. } else if (str.substr(str.length - 2) === '::') {
  43. blocks.pop();
  44. blocks.pop();
  45. foundOmissionBlock = true;
  46. }
  47. for (var i = 0; i < blocks.length; ++i) {
  48. // test for a :: which can not be at the string start/end
  49. // since those cases have been handled above
  50. if (blocks[i] === '' && i > 0 && i < blocks.length - 1) {
  51. if (foundOmissionBlock) {
  52. return false; // multiple :: in address
  53. }
  54. foundOmissionBlock = true;
  55. } else if (foundIPv4TransitionBlock && i === blocks.length - 1) {// it has been checked before that the last
  56. // block is a valid IPv4 address
  57. } else if (!ipv6Block.test(blocks[i])) {
  58. return false;
  59. }
  60. }
  61. if (foundOmissionBlock) {
  62. return blocks.length >= 1;
  63. }
  64. return blocks.length === expectedNumberOfBlocks;
  65. }
  66. return false;
  67. }
  68. module.exports = exports.default;
  69. module.exports.default = exports.default;