2011-12-05 9 views
6

En CoffeeScript, ¿cómo podría hacer para convertir un IP (estándar IPv4 127.0.0.1) en un número entero?¿Cómo convertir IPv4 a Entero usando CoffeScript?

EDITAR: ¡Muchas respuestas excelentes aquí, gracias a todos!

+0

@RussellDias Err ... eso es no muy útil (sugerencia: la representación entera decimal de '127.0.0.1' no es 127001). –

+0

@therefromhere Guess He entendido mal la pregunta :) –

Respuesta

3

EDIT: CoffeeScript

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

que compila a

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

Una breve aplicación pura, JavaScript es

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

Una buena aplicación pura, JavaScript es

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

    return sum; 
}; 
+1

No soy un gran admirador de usar 'map' para acumular. La asignación de valores no supone ningún efecto secundario pero está creando uno al acumularse dentro de la función. Si vas a utilizar un enfoque como este, al menos considera 'reduce' que está destinado a administrar la acumulación (agregación) de un conjunto. Aún así, ni 'map' ni' reduce' son compatibles en todos los navegadores (requiere Javascript 1.6). En ese punto, es mejor que simplemente bucle IMO. –

+0

Acepto que el uso de 'map' está sucio. Estoy completamente de acuerdo en que el ciclo es el movimiento correcto para una compatibilidad total.Mirando a MDN para 'Array.map' y' Array.reduce' muestra que 'reduce' es Javascript 1.8 y' map' es 1.6; ambos no están disponibles en IE <= 8, pero 'map' está disponible en versiones anteriores de FF, Opera y Safari ... – ellisbben

+0

Sí, me lo perdí. Pensé que reducir era parte de 1.6 ... No me malinterpreten, me gusta map/reduce/filter/etc ... pero prefiero no confiar en ninguno de ellos y poner algo así como Underscore para asegurarme de que Tengo las capacidades ... pero si solo estoy implementando una función como esta (en bruto), preferiría un bucle. Especialmente desde que la sintaxis de CoffeeScript es bastante limpia :) –

1

Creo que @ellisbben lo golpeó, pero pensé que sería sobre otra versión de JS con un poco más de comprobación de errores.

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')); 
2

me quedo con el método de desplazamiento de bits:

ip_to_int = (value) -> 
    result = 0 

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

    result 

de utilizarlo es sencilla:

alert ip_to_int "127.0.0.1" 
2

Para convertir una ip a un entero que necesita la fórmula

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

Deje ip = '127.0.0.1', ese coul d escribirse como:

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

Y puede ser simplificado mediante el método reduce:

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

La solución más pequeña para 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')); 
0

Aquí hay otro método de desplazamiento de bits.

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

Y para revertirla ...

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

Lo siento, es la versión JS, pero es muy fácil de convertirlo en 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('.'); 
}