【问题标题】:How to convert IPv4 to Integer using CoffeScript?如何使用 CoffeeScript 将 IPv4 转换为整数?
【发布时间】:2012-01-13 16:10:03
【问题描述】:

在 CoffeeScript 中,我将如何将 IP(标准 IPv4 127.0.0.1)转换为整数?

编辑:这里有很多很棒的答案,谢谢大家!

【问题讨论】:

  • @RussellDias Err... 这不是很有用(提示:127.0.0.1 的十进制整数表示不是 127001)。
  • @therefromhere 猜我误解了这个问题:)

标签: javascript integer ip coffeescript


【解决方案1】:

编辑:咖啡脚本

ipStringToInteger = (x) ->
  res = 0
  (res = res * 256 + Number(y) for y in x.split("."))
  res

编译成

var ipStringToInteger;
ipStringToInteger = function(x) {
  var res, y, _i, _len, _ref;
  res = 0;
  _ref = x.split(".");
  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
    y = _ref[_i];
    res = res * 256 + Number(y);
  }
  return res;
};

一个简短的纯 Javascript 实现是

var ipV4StringToInteger = function(string) {
  var parts = string.split(".");

  var sum = 0;

  for(var i = 0; i < 4; i++) {
    var partVal = Number(parts[i]);
    sum = (sum << 8) + partVal;
  }

  return sum;
};

一个好的纯Javascript实现是

var ipV4StringToInteger = function(string) {
  var parts = string.split(".");
  if(parts.length != 4)
    throw new Error("IPv4 string does not have 4 parts.");

  var sum = 0;

  for(var i = 0; i < 4; i++) {

    var part = parts[i];
    if(!part.match("^\\d+$"))
      throw new Error("Non-digit, non-period character in IPv4 string.");

    var partVal = Number(part);
    if(partVal > 255)
      throw new Error("IPv4 string contains invalid value.");

    sum = ((sum << 8) + partVal) >>> 0;
  }

  return sum;
};

【讨论】:

  • 我不太喜欢用map来积累。映射值假定没有副作用,但您是通过在函数中累积来创建一个。如果您要使用这样的方法,至少考虑reduce,它旨在管理集合的累积(聚合)。尽管如此,所有浏览器都不支持mapreduce(需要Javascript 1.6)。到那时,您不妨只循环 IMO。
  • 我同意map 的使用是肮脏的。我完全同意循环是完全兼容的正确举措。查看 Array.mapArray.reduce 的 MDN 显示 reduce 是 Javascript 1.8 和 map 是 1.6;两者都在 IE map 在较旧的 FF、Opera 和 Safari 中可用...
  • 是的,我错过了。我原以为 reduce 是 1.6 的一部分...不要误会,我喜欢 map/reduce/filter/etc... 但我宁愿不依赖它们中的任何一个并引入像 Underscore 这样的东西来确保我有能力......但如果我只是实现这样的功能(原始),我更喜欢循环。尤其是因为 CoffeeScript 语法非常干净:)
  • JS 开发只是个奇怪的东西。至于工具和库,我喜欢 Closure 编译器,但 Closure 库中的命名空间有时有点烦人。但是,如果您可以忍受它,它往往会做正确的事情,例如goog.array.map 遵循 map 的浏览器原生实现,如果它存在并且依赖于纯 JS 实现;编译器消除了与 sesquipedalian 命名空间名称相关的膨胀。
【解决方案2】:

要将 ip 转换为整数,您需要公式

(first octet * 256³) + (second octet * 256²) + (third octet * 256) + (fourth octet)

ip = '127.0.0.1',可以写成:

integer = 0
for octet, i in ip.split('.')
    integer += octet * Math.pow 256, 3-i

并且可以使用reduce方法进行简化:

integer = ip.split('.').reduce ((t, n) -> t*256 + parseInt n), 0

【讨论】:

    【解决方案3】:

    我将采用位移方法:

    ip_to_int = (value) ->
      result = 0
    
      for part, i in value.split "."
        result |= part << (3-i) * 8
    
      result
    

    使用很简单:

    alert ip_to_int "127.0.0.1"
    

    【讨论】:

      【解决方案4】:

      我相信@ellisbben 成功了,但我认为我会在另一个 JS 版本上进行更多的错误检查。

      function ip2int(ip){
          // split them in to their own numbers
          var octets = ip.split('.');
      
          // make sure we have a valid IP. (length-wise)
          if (octets.length!=4) return false;
      
          // begin parsing
          var result = 0;
          for (var v = 1; v <= 4; v++){
              var i = parseInt(octets[v-1],10);
      
              // valid number?
              if (isNaN(i) || i < 0 || i > 255) return false;
      
              result += (i * Math.pow(256,(4-v)));
          }
          return result;
      }
      
      alert(ip2int('127.0.0.1'));
      

      【讨论】:

        【解决方案5】:

        这是另一种位移方法。

        addr='192.168.5.253'.split('.');
        ipInt = (+addr[0] << 24) + (+addr[1] << 16) + (+addr[2] << 8) + (+addr[3]);
        

        然后扭转它......

        [ipInt >> 24 & 0xff,ipInt >> 16 & 0xff,ipInt >> 8 & 0xff,ipInt & 0xff].join('.');
        

        【讨论】:

          【解决方案6】:

          抱歉,是 JS 版本,不过转成 CoffeeScript 很简单:

          // 'x.x.x.x' -> number    
          function Ip4ToInt(ip4str) {
          
              var addr = ip4str.split('.');
              if ( addr.length !== 4 || addr.some( (elm) => (parseInt(elm) > 255 || parseInt(elm) < 0 ) ) ) {
                  throw new Error('Invalid ip4 string: ' + ip4str);
              }
              return ((addr[0] << 24) >>> 0) + ((addr[1] << 16) >>> 0) + ((addr[2] << 8) >>> 0) + (addr[3]);
          }
          
          // number -> 'x.x.x.x'
          function IntToIp4(ip4int){
              return [ip4int >> 24 & 0xff,ip4int >> 16 & 0xff,ip4int >> 8 & 0xff,ip4int & 0xff].join('.');
          }
          

          【讨论】:

            【解决方案7】:

            node.js 的最小解决方案:

            function ip2int(ip) {
                var ipint = 0;
                ip.split('.').map(function (e, i) {
                    ipint += Math.pow(256, 3-i) * e;
                });
                return ipint;
            }
            console.log(ip2int('10.1.1.20'));
            

            【讨论】:

              猜你喜欢
              • 2010-10-02
              • 1970-01-01
              • 1970-01-01
              • 2014-03-03
              • 1970-01-01
              • 1970-01-01
              • 2014-04-21
              • 2016-11-26
              • 2012-05-30
              相关资源
              最近更新 更多