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

新手上路,请多包涵

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

这是我的代码:

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

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

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

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

你们中的任何人都可以解释发生了什么吗?以及可能如何将 -1062731220 解析回字符串 ip?

原文由 JPuge 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 399
2 个回答

为什么转换后的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;
}

为什么要重新发明轮子?来自谷歌:

或者,您可以使用我在这里找到的内容:

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

原文由 evan 发布,翻译遵循 CC BY-SA 3.0 许可协议

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

当您向后移动时,使用“>>>”进行无符号右移。

原文由 Pointy 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题