2011-12-05 14 views
6

In CoffeeScript come farei per convertire un IP (standard IPv4 127.0.0.1) in un numero intero?Come convertire IPv4 in intero usando CoffeScript?

MODIFICA: Un sacco di grandi risposte qui, grazie a tutti!

+0

@RussellDias Err ... questo è non molto utile (suggerimento: la rappresentazione decimale di '127.0.0.1' non è 127001). –

+0

@therefromhere Indovina che ho frainteso la domanda :) –

risposta

3

EDIT: CoffeeScript

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

che raccoglie fino 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; 
}; 

Un'implementazione breve puro 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; 
}; 

una buona implementazione puro 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; 
    } 

    return sum; 
}; 
+1

Non sono un grande fan dell'uso di 'map' per accumulare. I valori di mappatura non assumono alcun effetto collaterale, ma ne stai creando uno accumulando all'interno della funzione. Se hai intenzione di utilizzare un approccio come questo, considera almeno "reduce" che è destinato a gestire l'accumulo (aggregazione) di un insieme. Tuttavia, né 'map' né' reduce' sono supportati in tutti i browser (richiede Javascript 1.6). A quel punto, si potrebbe anche solo ripetere l'IMO. –

+0

Sono d'accordo che l'uso di 'map' è sporco. Sono pienamente d'accordo sul fatto che il ciclo sia la mossa giusta per la piena compatibilità.Guardando MDN per 'Array.map' e' Array.reduce' mostra che 'reduce' è Javascript 1.8 e' map' è 1.6; entrambi non sono disponibili in IE <= 8 ma 'map' è disponibile in FF, Opera e Safari precedenti ... – ellisbben

+0

Sì, l'ho perso. Avevo pensato che ridurre faceva parte di 1.6 ... Non fraintendermi, mi piace la mappa/ridurre/filtro/etc ... ma preferirei non fare affidamento su nessuno di loro e introdurre qualcosa come Underscore per garantire che Ho le capacità ... ma se sto semplicemente implementando una funzione come questa (raw), preferirei semplicemente un ciclo. Soprattutto perché la sintassi CoffeeScript è molto pulita :) –

1

Credo che @ellisbben l'abbia colpito, ma ho pensato di utilizzare un'altra versione di JS con un po 'più di controllo degli errori.

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

mi prenderò l'approccio bit-shifting:

ip_to_int = (value) -> 
    result = 0 

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

    result 

Per usarlo è semplice:

alert ip_to_int "127.0.0.1" 
2

Per convertire un IP a intero è necessario la formula

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

Let ip = '127.0.0.1', che coul d essere scritta come:

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

E può essere semplificato utilizzando il metodo reduce:

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

La soluzione più piccola per 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

Ecco un altro metodo po turno.

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

E per invertire tale tendenza ...

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

Ci dispiace, è la versione JS, ma è molto facile da convertire in 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('.'); 
} 
Problemi correlati