简体   繁体   中英

Validate IP address is not 0.0.0.0 or multicast address

使用JavaScript如何验证IP地址“xxxx”是有效的IPV4单播地址,例如不是0.0.0.0或多播(224.0.0.0到224.0.0.255,224.0.1.0到238.255.255.255,239.0.0.0到239.255.255.255) )?

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;

       //compute 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.org/assignments/multicast-addresses/multicast-addresses.xhtml and http://tools.ietf.org/html/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 comparison operators :(
if (myIp == 0 || (myIp <= min && myIp >= max)) {
    // multicast!
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM