Was ist der beste Weg vom Netzwerk Bitcount konvertieren zu netmask?
-
03-07-2019 - |
Frage
Zum Beispiel, wenn ich eine Netzwerk-Spezifikation wie 172.20.10.0/24 habe „24“ ist der Bitcount. Was ist der beste Weg, das zu einer Netzmaske wie 0xffffff00 zu konvertieren?
Lösung
Warum Zeit mit Subtraktion oder ternären Aussagen?
int suffix = 24;
int mask = 0xffffffff ^ 0xffffffff >> suffix;
Wenn Sie wissen, Ihre ganze Zahl ist genau 32 Bit lang, dann müssen Sie nur einmal eingeben 0xffffffff.
int32_t mask = ~(0xffffffff >> suffix);
Sowohl auf den exakt gleichen Assembler-Code kompilieren.
Andere Tipps
Unter der Annahme, 32-Bit-Maske und 32-Bit-int.
int keepBits = 24; /* actually get it from somewhere else? */
int mask = (0xffffffff >> (32 - keepBits )) << (32 - keepBits);
Hinweis: „Was ist der beste Weg, um die Netzwerkmaske für eine Schnittstelle zu bekommen“ dies ist nicht unbedingt die Antwort auf die Frage
Ich mache es immer so (in Ihrem Fall cidr = 24):
uint32_t ipv4Netmask;
ipv4Netmask = 0xFFFFFFFF;
ipv4Netmask <<= 32 - cidr;
ipv4Netmask = htonl(ipv4Netmask);
Dies wird nur mit ipv4Netmask tatsächlich arbeitet uint32_t zu sein, nicht es int machen, wie int nicht 32 Bit auf jedem System sein muss. Das Ergebnis wird konvertiert Byte-Reihenfolge zu vernetzen, wie das ist, was die meisten Systemfunktionen erwarten.
Beachten Sie, dass dieser Code wird fehlschlagen, wenn cidr
null ist, wie dann würde der Code eine 32-Bit-Variable Verschiebung von 32 Bit und ob Sie es glauben oder nicht, das ist nicht definiertes Verhalten in C. Ein das Ergebnis immer erwarten würde Null sein, aber der C-Standard sagt, dass dies nicht mit zu beginnen, ist definiert. Wenn Ihr CIDR Null sein kann (was nur in der jede IP-Adresse Platzhalter 0.0.0.0/0 erlaubt sein würde), dann muss der Code Sonderfall fangen.
Dies ist keine Programmierung Frage, aber in Linux können Sie verwenden whatmask.
whatmask 72.20.10.0/24
Rückkehr
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
int keepbits = 24;
int mask = keepbits > 0 ? 0x00 - (1<<(32 - keepbits)) : 0xFFFFFFFF;
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
Von der Befehlszeile
>whatmask.vbs 123.12.123.17/23
0xfffff700
Seien Sie vorsichtig, wenn Sie die vorherigen Antworten mit Code verwenden wie:
0xFFFFFFFF << 32 - cidr
oder
-1 << 32 - cidr
In C # zumindest wird es zunächst die Verschiebung zählt mit 0x1F maskieren. Also, für eine cidr mit dem Präfix 0 (dh des gesamten IPv4-Adressbereiches):
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
Sie könnten versuchen, etwas einfach, wie die Bitcount nehmen und Division durch 4. Das würde Ihnen die führende Fs in der Maske. Und dann den Rest nimmt und hat einen Wechsel von 0 Bits auf 3 Bits.
/* 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);