最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Validate IP address is not 0.0.0.0 or multicast address - Stack Overflow

programmeradmin3浏览0评论

Using JavaScript how would I validate an IP address "x.x.x.x" is a valid IPV4 unicast address e.g. is not 0.0.0.0 or multicast (224.0.0.0 to 224.0.0.255, 224.0.1.0 to 238.255.255.255, 239.0.0.0 to 239.255.255.255)?

Using JavaScript how would I validate an IP address "x.x.x.x" is a valid IPV4 unicast address e.g. is not 0.0.0.0 or multicast (224.0.0.0 to 224.0.0.255, 224.0.1.0 to 238.255.255.255, 239.0.0.0 to 239.255.255.255)?

Share Improve this question asked Oct 1, 2009 at 13:17 AndrewAndrew 3171 gold badge6 silver badges11 bronze badges 0
Add a ment  | 

4 Answers 4

Reset to default 7

First you need to get it into a number, use this function:-

function IPToNumber(s)
{
    var arr = s.split(".");
    var n = 0
    for (var i = 0; i < 4; i++)
    {
        n = n * 256
        n += parseInt(arr[i],10)

    }
    return n;
}

Looking at you spec, whilst you seem to list a series of ranges those ranges appear to be contiguous to me, that is can be simplified to (224.0.0.0 to 239.255.255.255). Hence you can test with:-

var min = IPToNumber("224.0.0.0");
var max = IPToNumber("239.255.255.255");

var ipNum = IPToNumber(sTestIP);

var isValid = (ipNum != 0 && (ipNum < min || ipNum > max))

Note of course that without knowledge of the destinations subnet you can't tell whether the address is the network address or the broadcast address for that subnet.

The dotted quad notation you're seeing is just that: a notation that makes it easier on human eyes. An IP Address is really a 32 bit integer. I suggest you convert your address to that integer and then just check that it's in a valid range (ie, > 0 for the first requirement).

To that end:

function dottedQuadToInt(ip)
{      
    var parts = ip.split('.', 4);
    if(parts.length < 4) return -1;

    var result = 0, base = 1;
    for (var i = 3;i>=0;i--)
    {
       //validation
       if (parts[i].length == 0 || parts[i].length > 3) return -1;

       var segment = parseInt(parts[i],10);
       if (isNaN(segment) || segment<0 || segment > 255) return -1;

       //pute next segment
       result += base * segment;
       base = base << 8;
    }
    return result;
}

and then:

function isValidIP(ip)
{
   ip = dottedQuadToInt(ip);
   if (ip <= 0) return false;

   //mulitcast range:
   if (ip >= 3758096384 && ip <= 4026531839) return false;

   //alternate way to check multicast (slower, but more readable):
   if (ip >= dottedQuadToInt('224.0.0.0') && ip <= dottedQuadToInt('239.255.255.255')) return false;

   return true;
}

Multicast IP addresses are defined as those with 1110 as their high-order four bits (see http://www.iana/assignments/multicast-addresses/multicast-addresses.xhtml and https://www.rfc-editor/rfc/rfc1112). In hex the 1110 is expressed as 0xE (decimal value of 14, remember each hex digit is worth 4 binary bits) so if this value is in the high order 4 bits of 32 bit integer (big endian) the hex would be 0xE0000000. If you first convert the IP address to a 32 bit number and then & it with 0xF0000000, if the resulting value is equal to 0xE0000000 (1110 in the high-order four bits) then it is a multicast IPv4 address (same logic used in Java Inet4Address.isMulticastAddress()).

var ipNum = IPToNumber(sTestIP);
var isMulticast = ((ipNum & 0xF0000000) == 0xE0000000);

Here is a table to prove the point (notice that valid mutlicast IP addresses in hex format all start with 0xE, also the int values are signed 32 bit numbers):

// not a multicast, starts with 0xD
ip [223.000.000.000] hex [0xDF000000] int [-553648128] unsigned [3741319168]
ip [223.255.255.255] hex [0xDFFFFFFF] int [-536870913] unsigned [3758096383]    

// is a multicast, starts with 0xE
ip [224.000.000.000] hex [0xE0000000] int [-536870912] unsigned [3758096384]
ip [224.255.255.255] hex [0xE0FFFFFF] int [-520093697] unsigned [3774873599]
ip [225.000.000.000] hex [0xE1000000] int [-520093696] unsigned [3774873600]
ip [225.255.255.255] hex [0xE1FFFFFF] int [-503316481] unsigned [3791650815]
ip [226.000.000.000] hex [0xE2000000] int [-503316480] unsigned [3791650816]
ip [226.255.255.255] hex [0xE2FFFFFF] int [-486539265] unsigned [3808428031]
ip [227.000.000.000] hex [0xE3000000] int [-486539264] unsigned [3808428032]
ip [227.255.255.255] hex [0xE3FFFFFF] int [-469762049] unsigned [3825205247]
ip [228.000.000.000] hex [0xE4000000] int [-469762048] unsigned [3825205248]
ip [228.255.255.255] hex [0xE4FFFFFF] int [-452984833] unsigned [3841982463]
ip [229.000.000.000] hex [0xE5000000] int [-452984832] unsigned [3841982464]
ip [229.255.255.255] hex [0xE5FFFFFF] int [-436207617] unsigned [3858759679]
ip [230.000.000.000] hex [0xE6000000] int [-436207616] unsigned [3858759680]
ip [230.255.255.255] hex [0xE6FFFFFF] int [-419430401] unsigned [3875536895]
ip [231.000.000.000] hex [0xE7000000] int [-419430400] unsigned [3875536896]
ip [231.255.255.255] hex [0xE7FFFFFF] int [-402653185] unsigned [3892314111]
ip [232.000.000.000] hex [0xE8000000] int [-402653184] unsigned [3892314112]
ip [232.255.255.255] hex [0xE8FFFFFF] int [-385875969] unsigned [3909091327]
ip [233.000.000.000] hex [0xE9000000] int [-385875968] unsigned [3909091328]
ip [233.255.255.255] hex [0xE9FFFFFF] int [-369098753] unsigned [3925868543]
ip [234.000.000.000] hex [0xEA000000] int [-369098752] unsigned [3925868544]
ip [234.255.255.255] hex [0xEAFFFFFF] int [-352321537] unsigned [3942645759]
ip [235.000.000.000] hex [0xEB000000] int [-352321536] unsigned [3942645760]
ip [235.255.255.255] hex [0xEBFFFFFF] int [-335544321] unsigned [3959422975]
ip [236.000.000.000] hex [0xEC000000] int [-335544320] unsigned [3959422976]
ip [236.255.255.255] hex [0xECFFFFFF] int [-318767105] unsigned [3976200191]
ip [237.000.000.000] hex [0xED000000] int [-318767104] unsigned [3976200192]
ip [237.255.255.255] hex [0xEDFFFFFF] int [-301989889] unsigned [3992977407]
ip [238.000.000.000] hex [0xEE000000] int [-301989888] unsigned [3992977408]
ip [238.255.255.255] hex [0xEEFFFFFF] int [-285212673] unsigned [4009754623]
ip [239.000.000.000] hex [0xEF000000] int [-285212672] unsigned [4009754624] 
ip [239.255.255.255] hex [0xEFFFFFFF] int [-268435457] unsigned [4026531839]
    
// not a multicast, starts with 0xF
ip [240.000.000.000] hex [0xF0000000] int [-268435456] unsigned [4026531840]
ip [240.255.255.255] hex [0xF0FFFFFF] int [-251658241] unsigned [4043309055]
/**
 * Converts an IPv4 address to a (signed) 32-bit integer.
 */
function parse_ipv4_address(str) {
    var arr = str.split('.');
    for (var i = 0, val = 0; i < 4; i++) {
        val += parseInt(arr[i], 10) << (8 * (3 - i));
    }

    return val;
}

var min = parse_ipv4_address('224.0.0.0');
var max = parse_ipv4_address('239.255.255.255');

var myIp = parse_ipv4_address(myIpStr);

// because the values are signed ints, min and max will be
// negative and we need to reverse the parison operators :(
if (myIp == 0 || (myIp <= min && myIp >= max)) {
    // multicast!
}
发布评论

评论列表(0)

  1. 暂无评论