【问题标题】:Validate IP address is not 0.0.0.0 or multicast address验证 IP 地址不是 0.0.0.0 或多播地址
【发布时间】:2010-12-02 23:57:42
【问题描述】:

使用 JavaScript 如何验证 IP 地址“x.x.x.x”是有效的 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)?

【问题讨论】:

    标签: javascript


    【解决方案1】:

    首先你需要把它变成一个数字,使用这个函数:-

    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;
    }
    

    查看您的规范,虽然您似乎列出了一系列范围,但这些范围对我来说似乎是连续的,即可以简化为(224.0.0.0 到 239.255.255.255)。因此,您可以使用以下方法进行测试:-

    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))
    

    当然请注意,如果不知道目标子网,您无法判断该地址是该子网的网络地址还是广播地址。

    【讨论】:

    • 您使用* 而不是按位运算符意味着您的数字在任何时候都不应该转换为Int32 - 聪明!
    • 小心这样的事情,它是有效的:70.16.18.015。您的 parseInt 调用可能不会将所有内容都视为十进制。
    • 使用 0.0.0.015 的快速测试确认了该错误。我修复了你的代码。
    • 是的......那些愚蠢的八进制字符串。谁还需要它们?
    【解决方案2】:

    您看到的虚线四边形符号就是这样:一种使人眼更容易理解的符号。 IP 地址实际上是一个 32 位整数。我建议您将地址转换为该整数,然后检查它是否在有效范围内(即,> 0 表示第一个要求)。

    为此:

    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;
    }
    

    然后:

    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;
    }
    

    【讨论】:

    • 哦,是的,我明白了,我没有发现您正在转移基数而不是价值本身。
    【解决方案3】:

    多播 IP 地址定义为以1110 为高四位的地址(请参阅http://www.iana.org/assignments/multicast-addresses/multicast-addresses.xhtmlhttps://www.rfc-editor.org/rfc/rfc1112)。在十六进制中,1110 表示为0xE(十进制值 14,记住每个十六进制数字值 4 个二进制位)所以如果这个值是 32 位整数(大端)的高 4 位,则十六进制将是0xE0000000。如果先将 IP 地址转换为 32 位数字,然后将其与0xF0000000 转换为&amp;,如果结果值等于0xE0000000(高四位为1110),则它是多播IPv4 地址(与 Java Inet4Address.isMulticastAddress() 中使用的逻辑相同)。

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

    这里有一个表格来证明这一点(请注意,十六进制格式的有效多播 IP 地址都以 0xE 开头,int 值也是有符号的 32 位数字):

    // 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]
    

    【讨论】:

    • 迄今为止最好的答案。以最简单的方式直接将规范翻译成代码。
    【解决方案4】:
    /**
     * 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!
    }
    

    【讨论】:

    • 我喜欢我们三个发布的内容几乎完全相同。我会投票给你们两个:)
    猜你喜欢
    • 2013-04-16
    • 1970-01-01
    • 1970-01-01
    • 2011-04-09
    • 2012-02-29
    • 1970-01-01
    • 1970-01-01
    • 2014-03-27
    • 2011-08-01
    相关资源
    最近更新 更多