2008-10-20 7 views
8

Por ejemplo, si tengo una especificación de red como 172.20.10.0/24, "24" es la bitcount. ¿Cuál es la mejor manera de convertir eso a una máscara de red como 0xffffff00?¿Cuál es la mejor manera de convertir de bitcount de red a máscara de red?

+0

¿Quiere decir pro gramaticalmente, o en papel? Un poco más de detalle será útil. – Brettski

+0

oops. Quise decir programáticamente.En particular, estoy interesado en hacerlo en Powershell. Pero está interesado en varios enfoques en general. – Choy

+0

las dos partes se llaman prefijo y sufijo. – joeforker

Respuesta

2

Esto no es una pregunta de programación, pero en Linux puedes usar whatmask.

whatmask 72.20.10.0/24 

vuelve

IP Entered = ..................: 72.20.10.0 
CIDR = ........................: /24 
Netmask = .....................: 255.255.255.0 
Netmask (hex) = ...............: 0xffffff00 
Wildcard Bits = ...............: 0.0.0.255 
------------------------------------------------ 
Network Address = .............: 72.20.10.0 
Broadcast Address = ...........: 72.20.10.255 
Usable IP Addresses = .........: 254 
First Usable IP Address = .....: 72.20.10.1 
Last Usable IP Address = ......: 72.20.10.254 
+0

[código fuente de la máscara] (http://www.laffeycomputer.com/whatmask.html) –

0

Usted podría intentar algo simple, como tomar la bitcount y dividiendo por 4. Que te daría el principal F en la máscara. Y luego tome el resto y cambie de 0 a 3 bits.

8

Asumiendo máscara de 32 bits e int de 32 bits.

int keepBits = 24; /* actually get it from somewhere else? */ 

int mask = (0xffffffff >> (32 - keepBits)) << (32 - keepBits); 

Nota: esto no es necesariamente la respuesta a la pregunta "¿Cuál es la mejor manera de obtener la máscara de red para una interfaz?"

+1

Otro que supone keepBits> 0. – bk1e

+0

En realidad, configuro keepBits igual a 24 por lo que es por definición> 0 – tvanfosson

+0

Y menos que 32 ... – tvanfosson

2
int keepbits = 24; 
int mask = keepbits > 0 ? 0x00 - (1<<(32 - keepbits)) : 0xFFFFFFFF; 
+1

¿Qué pasa si keepbits == 0? Ten cuidado, esos desbordamientos de enteros te atraparán. – bk1e

+0

Si keepbits es 0, entonces el '1' cambiará completamente fuera del registro (asumiendo el registro de 32 bits) y la máscara de red será 0. ¿No es esa la respuesta correcta? – Robert

+0

http://en.wikipedia.org/wiki/Bitwise_operation#Shifts_in_C.2C_C.2B.2B_and_Java dice que el desplazamiento a la izquierda no está definido si ocurre un desbordamiento. MSVC y GCC evalúan 1 << 32 como 1, no 0. – bk1e

4

siempre lo hago así (en su caso cidr = 24):

uint32_t ipv4Netmask; 

ipv4Netmask = 0xFFFFFFFF; 
ipv4Netmask <<= 32 - cidr; 
ipv4Netmask = ntohl(ipv4Netmask); 

Esto sólo funcionará con ipv4Netmask para ser realmente uint32_t, no lo hacen int, int como doesn no tiene que ser de 32 bits en todos los sistemas. El resultado se convierte en orden de bytes de red, ya que es lo que la mayoría de las funciones del sistema esperan.

+3

"el resultado se convierte en orden de bytes de red" - Creo que tenía la intención de escribir htonl (ipv4Netmask) –

1

he aquí una solución en VBScript, Fwiw

option explicit 

'whatmask 72.20.10.0/24 
If WScript.Arguments.Unnamed.Count < 1 Then 
    WScript.Echo "WhatMask xxx.xxx.xxx.xxx/xx" 
    Wscript.Quit 
End If 

Dim sToFind 
Dim aParts 
Dim nSubnet 

sToFind = WScript.Arguments(0) 
aParts = Split(sToFind, "/", 2) 
nSubnet = aParts(1) 

if nSubnet < 1 or nSubnet > 32 then 
    WScript.echo "Subnet out of range [1..32]" 
    Wscript.quit 
end if 

Dim sBinary 
sBinary = String(nSubnet, "1") 
sBinary = sBinary & String(32 - nSubnet, "0") 

wscript.echo "0x" & lcase(binary2hexadecimal(sBinary)) 

function binary2hexadecimal(sBin) 
    dim sSlice 
    dim sResult 
    dim i 
    for i = 1 to len(sBin) step 4 
    sSlice = mid(sBin, i, 4) 
    sResult = sResult & hex(binary2decimal(sSlice)) 
    next 
    binary2hexadecimal = sResult 
end function 

function binary2decimal(sFourbits) 
    dim i 
    dim bit 
    dim nResult 
    nResult = 0 
    for i = 4 to 1 step -1 
    bit = mid(sFourbits, i, 1) 
    nResult = nResult * 2 + bit 
    next 
    binary2decimal = nResult 
end function 

Desde la línea de comandos

>whatmask.vbs 123.12.123.17/23 
0xfffff700 
1

qué perder el tiempo con la resta o ternarios declaraciones?

int suffix = 24; 
int mask = 0xffffffff^0xffffffff >> suffix; 

Si conoce su número entero es exactamente 32 bits de largo después, sólo tendrá que escribir una vez 0xffffffff.

int32_t mask = ~(0xffffffff >> suffix); 

Ambos compilan exactamente el mismo código de ensamblaje.

0
/* C# version merging some of the other contributions and corrected for byte order. */ 

int cidr = 24; 

var ipv4Netmask = 0xFFFFFFFF; 

ipv4Netmask <<= 32 - cidr; 

byte[] bytes = BitConverter.GetBytes(ipv4Netmask); 

Array.Reverse(bytes); 

ipv4Netmask = BitConverter.ToUInt32(bytes, 0);  

// mask is now ready for use such as: 

var netmask = new IPAddress(ipv4Netmask); 
1

Tenga cuidado cuando utilice las respuestas anteriores con un código como:

0xFFFFFFFF << 32 - cidr 

o

-1 << 32 - cidr 

En C#, al menos, va a enmascarar el recuento de turno con 0x1F primero. Por lo tanto, para un cidr con el prefijo 0 (es decir, todo el rango de direcciones IPv4):

int cidr=0; 
0xFFFFFFFF << (32 - cidr) == 0xFFFFFFFF 

que no es lo que desea. En su lugar, debe usar:

int cidr=0; 
(int)(0xFFFFFFFFL << (32 - cidr)) == 0 
Cuestiones relacionadas