is-fast-ip.ts 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. /**
  2. * Check if a hostname is an IP. You should be aware that this only works
  3. * because `hostname` is already garanteed to be a valid hostname!
  4. */
  5. export function isProbablyIpv4(hostname: string): boolean {
  6. // Cannot be shorted than 1.1.1.1
  7. if (hostname.length < 7) {
  8. return false;
  9. }
  10. // Cannot be longer than: 255.255.255.255
  11. if (hostname.length > 15) {
  12. return false;
  13. }
  14. let numberOfDots = 0;
  15. for (let i = 0; i < hostname.length; i += 1) {
  16. const code = hostname.charCodeAt(i);
  17. if (code === 46 /* '.' */) {
  18. numberOfDots += 1;
  19. } else if (code < 48 /* '0' */ || code > 57 /* '9' */) {
  20. return false;
  21. }
  22. }
  23. return (
  24. numberOfDots === 3
  25. && hostname.charCodeAt(0) !== 46
  26. && /* '.' */ hostname.charCodeAt(hostname.length - 1) !== 46 /* '.' */
  27. );
  28. }
  29. export function isProbablyIpv6(hostname: string): boolean {
  30. if (hostname.length < 3) {
  31. return false;
  32. }
  33. let start = hostname[0] === '[' ? 1 : 0;
  34. let end = hostname.length;
  35. if (hostname[end - 1] === ']') {
  36. end -= 1;
  37. }
  38. // We only consider the maximum size of a normal IPV6. Note that this will
  39. // fail on so-called "IPv4 mapped IPv6 addresses" but this is a corner-case
  40. // and a proper validation library should be used for these.
  41. if (end - start > 39) {
  42. return false;
  43. }
  44. /* eslint-disable sukka/no-single-return -- here it goes */
  45. let hasColon = false;
  46. for (; start < end; start += 1) {
  47. const code = hostname.charCodeAt(start);
  48. if (code === 58 /* ':' */) {
  49. hasColon = true;
  50. } else if (
  51. !(
  52. (
  53. (code >= 48 && code <= 57) // 0-9
  54. || (code >= 97 && code <= 102) // a-f
  55. || (code >= 65 && code <= 90) // A-F
  56. )
  57. )
  58. ) {
  59. return false;
  60. }
  61. }
  62. return hasColon;
  63. /* eslint-enable sukka/no-single-return -- here it goes */
  64. }