2008-10-20 2 views
8

Zum Beispiel, wenn ich eine Netzwerkspezifikation wie 172.20.10.0/24 habe, ist "24" der Bitcount. Was ist der beste Weg, um das zu einer Netzmaske wie 0xffffff00 zu konvertieren?Was ist der beste Weg, um von Netzwerk-Bitcount zu Netmask zu konvertieren?

+0

Meinst du pro grammatisch oder auf Papier? Etwas mehr Details werden hilfreich sein. – Brettski

+0

oops. Ich meinte programmatisch.Insbesondere interessiert mich das in Powershell. Aber interessiert an verschiedenen Ansätzen insgesamt. – Choy

+0

Die beiden Teile werden als Präfix und Suffix bezeichnet. – joeforker

Antwort

2

Dies ist keine Programmierfrage, aber in Linux können Sie whatmask verwenden.

whatmask 72.20.10.0/24 

kehrt

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

[Whatmask Quellcode] (http://www.laffeycomputer.com/whatmask.html) –

0

Sie konnten das von 4. etwas einfach, wie wenn man die Bitcount und Dividieren versuchen würde Ihnen die führende Fs in der Maske. Und dann den Rest nehmen und einen Wechsel von 0 Bit auf 3 Bit durchführen.

8

Angenommen 32-Bit-Maske und 32-Bit-Int.

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

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

Hinweis: Dies ist nicht unbedingt die Antwort auf die Frage „Was ist der beste Weg, um die Netzwerkmaske für eine Schnittstelle zu bekommen?“

+1

Eine andere, die KeepBits> 0 annimmt. – bk1e

+0

Eigentlich habe ich KeepBits gleich 24 gesetzt, so ist es per Definition> 0 – tvanfosson

+0

Und weniger als 32 ... – tvanfosson

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

Was wäre, wenn Keepbits == 0? Pass auf, diese Integer-Überläufe werden dir helfen. – bk1e

+0

Wenn "keepbits" 0 ist, dann verschiebt sich die "1" vollständig aus dem Register (angenommen 32-Bit-Register) und die Netzmaske wird 0. Ist das nicht die richtige Antwort? – Robert

+0

http://en.wikipedia.org/wiki/Bitwise_operation#Shifts_in_C.2C_C.2B.2B_and_Java sagt, Linksverschiebung ist nicht definiert, wenn ein Überlauf auftritt. MSVC und GCC bewerten beide 1 << 32 als 1, nicht 0. – bk1e

4

Ich mache es immer so (in Ihrem Fall cidr = 24):

uint32_t ipv4Netmask; 

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

Dies wird nur mit ipv4Netmask tatsächlich arbeiten uint32_t sein, tun es nicht int machen, wie int doesn muss auf jedem System 32 Bit sein. Das Ergebnis wird in die Netzwerkbyte-Reihenfolge konvertiert, da dies von den meisten Systemfunktionen erwartet wird.

+3

"Das Ergebnis wird in die Netzwerk-Byte-Reihenfolge konvertiert" - Ich denke, Sie wollten htonl (ipv4Netmask) eingeben –

1

Hier ist eine Lösung in 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 

in der Befehlszeile

>whatmask.vbs 123.12.123.17/23 
0xfffff700 
1

Warum Zeit mit Subtraktion oder ternären Aussagen?

Wenn Sie wissen, dass Ihre Ganzzahl genau 32 Bit lang ist, müssen Sie nur einmal 0xffffffff eingeben.

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

Beide kompilieren nach dem gleichen Assembly-Code.

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

Seien Sie vorsichtig, wenn Sie die bisherigen Antworten mit Code wie verwenden:

0xFFFFFFFF << 32 - cidr 

oder

-1 << 32 - cidr 

In C# zumindest wird es zunächst die Verschiebung zählen mit 0x1F maskieren. Also, für eine cidr mit dem Präfix 0 (dh der gesamte IPv4-Adressbereich):

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

das ist nicht das, was Sie wollen. Stattdessen sollten Sie verwenden:

int cidr=0; 
(int)(0xFFFFFFFFL << (32 - cidr)) == 0 
Verwandte Themen