isIP.js 2.5 KB

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