存储为int的IP地址会导致溢出?

JPu*_*uge 19 javascript

我正在node.js中编写聊天服务器,我想将连接用户的IP地址存储在mysql数据库中作为(无符号)整数.我编写了一个javascript方法将ip-address转换为字符串为整数.然而,我得到一些奇怪的结果.

这是我的代码:

function ipToInt(ip) {
    var parts = ip.split(".");
    var res = 0;

    res += parseInt(parts[0], 10) << 24;
    res += parseInt(parts[1], 10) << 16;
    res += parseInt(parts[2], 10) << 8;
    res += parseInt(parts[3], 10);

    return res;
}
Run Code Online (Sandbox Code Playgroud)

当我运行调用方法时,ipToInt("192.168.2.44");我得到的结果是-1062731220.看起来好像发生了溢出,这很奇怪,因为预期的输出(3232236076)在javascript(2 ^ 52)的数字范围内.

当我-1062731220以二进制形式检查时,我可以看到它3232236076被保留了,但是充满了前导1.

我不确定,但我认为问题在于有符号和无符号整数.

你们任何人都可以解释发生了什么吗?并可能如何解析-1062731220回字符串IP?

eva*_*van 41

为什么转换后的IP为负数?

这不是溢出.IP地址的第一部分是192,它以二进制形式转换为11000000.然后你将它一直向左移动.当32位数字的最左边位置有1时,它是负数.

你如何转换回字符串?

做同样的事情你从字符串转换,但相反.向右移(和面具)!

function intToIP(int) {
    var part1 = int & 255;
    var part2 = ((int >> 8) & 255);
    var part3 = ((int >> 16) & 255);
    var part4 = ((int >> 24) & 255);

    return part4 + "." + part3 + "." + part2 + "." + part1;
}
Run Code Online (Sandbox Code Playgroud)

为什么重新发明轮子?来自Google:

或者,您可以使用我在此处找到的内容:http:
//javascript.about.com/library/blipconvert.htm

function dot2num(dot) 
{
    var d = dot.split('.');
    return ((((((+d[0])*256)+(+d[1]))*256)+(+d[2]))*256)+(+d[3]);
}

function num2dot(num) 
{
    var d = num%256;
    for (var i = 3; i > 0; i--) 
    { 
        num = Math.floor(num/256);
        d = num%256 + '.' + d;
    }
    return d;
}
Run Code Online (Sandbox Code Playgroud)

  • 非常感谢,这很有帮助!我认为 javascript 总是使用 64 位有符号浮点数,但正如您所说,在转换为 32 位有符号整数后执行位移。那是我错了! (2认同)

Poi*_*nty 6

根据规范,"<<"运算符的结果始终是带符号的32位整数.

当您向后移动时,使用">>>"进行无符号右移.


Guy*_*Guy 6

您可能还会发现此模式很有用:

ip.toLong = function toInt(ip){
  var ipl=0;
  ip.split('.').forEach(function( octet ) {
      ipl<<=8;
      ipl+=parseInt(octet);
  });
  return(ipl >>>0);
};

ip.fromLong = function fromInt(ipl){
  return ( (ipl>>>24) +'.' +
      (ipl>>16 & 255) +'.' +
      (ipl>>8 & 255) +'.' +
      (ipl & 255) );
};
Run Code Online (Sandbox Code Playgroud)

如果你使用像 node.js 这样的东西,你可以通过像 Npm 这样的东西添加功能,那么你可以简单地做:

npm install ip
Run Code Online (Sandbox Code Playgroud)

要从这里的源获取该功能:https :
//github.com/indutny/node-ip/blob/master/lib/ip.js

您还将获得许多其他 IP 实用程序功能。