2008-10-20 7 views
8

Par exemple, si j'ai une spécification de réseau comme 172.20.10.0/24, "24" est le bitcount. Quelle est la meilleure façon de convertir cela en un masque de réseau comme 0xffffff00?Quelle est la meilleure façon de convertir du bitcount réseau au masque de réseau?

+0

Voulez-vous dire par ordre grammatical, ou sur papier? Un peu plus de détails sera utile. – Brettski

+0

oups. Je voulais dire par programme.En particulier, je suis intéressé à le faire dans Powershell. Mais intéressé par diverses approches dans l'ensemble. – Choy

+0

les deux parties sont appelées le préfixe et le suffixe. – joeforker

Répondre

2

Ce n'est pas une question de programmation, mais dans Linux, vous pouvez utiliser quel masque.

whatmask 72.20.10.0/24 

retours

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

[code source whatmask] (http://www.laffeycomputer.com/whatmask.html) –

0

Vous pouvez essayer quelque chose de simple, comme prendre la Bitcount et en divisant par 4. Ce serait vous donner de leader F dans le masque. Et puis prenez le reste et passez de 0 bits à 3 bits.

8

En supposant un masque de 32 bits et un int de 32 bits

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

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

Note: ce n'est pas nécessairement la réponse à la question « Quelle est la meilleure façon d'obtenir le masque de réseau pour une interface? »

+1

Un autre qui suppose keepBits> 0. – bk1e

+0

En fait, j'ai défini keepBits égal à 24 donc il est par définition> 0 – tvanfosson

+0

Et moins de 32 ... – tvanfosson

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

Que faire si keepbits == 0? Attention, ces débordements d'entiers vous obtiendront. – bk1e

+0

Si keepbits vaut 0, alors le '1' se déplacera complètement hors du registre (en supposant un registre de 32 bits) et le masque de réseau sera 0. N'est-ce pas la bonne réponse? – Robert

+0

http://en.wikipedia.org/wiki/Bitwise_operation#Shifts_in_C.2C_C.2B.2B_and_Java indique que le décalage vers la gauche est indéfini si un débordement se produit. MSVC et GCC évaluent 1 << 32 comme 1, pas 0. – bk1e

4

je fais toujours comme ça (dans votre cas cidr = 24):

uint32_t ipv4Netmask; 

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

Cela ne fonctionnera avec ipv4Netmask pour être réellement uint32_t, ne font pas int, int doesn Pas besoin d'être 32 bits sur chaque système. Le résultat est converti en ordre d'octets réseau, car c'est ce que la plupart des fonctions système attendent.

+3

"le résultat est converti en ordre d'octets du réseau" - Je pense que vous vouliez taper htonl (ipv4Netmask) –

1

est ici une solution dans 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 

A partir de la ligne de commande

>whatmask.vbs 123.12.123.17/23 
0xfffff700 
1

Pourquoi perdre du temps avec soustraction ou déclarations ternaires?

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

Si vous connaissez votre entier est exactement 32 bits de long alors il vous suffit de taper 0xffffffff fois.

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

Les deux compilent exactement le même code d'assemblage.

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

Soyez prudent lorsque vous utilisez les réponses précédentes avec le code comme:

0xFFFFFFFF << 32 - cidr 

ou

-1 << 32 - cidr 

En C# au moins, il va masquer le décalage compte avec 0x1F premier. Ainsi, pour un cidr avec préfixe 0 (l'ensemble de la plage d'adresses IPv4):

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

qui n'est pas ce que vous voulez. Au lieu de cela, vous devez utiliser:

int cidr=0; 
(int)(0xFFFFFFFFL << (32 - cidr)) == 0 
Questions connexes