2008-10-20 7 views
8

Na przykład, jeśli mam specyfikację sieci, taką jak 172.20.10.0/24, "24" to bitcount. Jaki jest najlepszy sposób przekonwertowania tego na maskę sieci, np. 0xffffff00?Jaki jest najlepszy sposób na konwersję z sieci bitcount na netmask?

+0

Masz na myśli pro gramatycznie lub na papierze? Nieco więcej szczegółów będzie pomocne. – Brettski

+0

oops. Miałem na myśli programowo.W szczególności jestem zainteresowany robieniem tego w Powershell. Ale ogólnie interesuje się różnymi podejściami. – Choy

+0

dwie części nazywane są prefiksem i sufiksem. – joeforker

Odpowiedz

2

To nie jest pytanie programistyczne, ale w Linuksie możesz użyć whatmask.

whatmask 72.20.10.0/24 

powraca

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 source code] (http://www.laffeycomputer.com/whatmask.html) –

0

Można spróbować coś prostego, jak poświęcenie bitcount i dzieląc przez 4. Że daje wiodącym F jest w masce. A następnie weź resztę i przełącz się od 0 bitów do 3 bitów.

8

Zakładając maskę 32-bitową i 32-bitową int.

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

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

Uwaga: nie jest to koniecznie odpowiedź na pytanie "Jaki jest najlepszy sposób uzyskania maski sieci dla interfejsu?"

+1

Kolejny, który zakłada keepBits> 0. – bk1e

+0

Właściwie ustawiam keepBits na 24, więc jest to z definicji> 0 – tvanfosson

+0

I mniej niż 32 ... – tvanfosson

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

Co się stanie, jeśli keepbity == 0? Uważaj, przepełnienia całkowite dostaną ci. – bk1e

+0

Jeśli keepbits ma wartość 0, to "1" przesunie się całkowicie z rejestru (zakładając rejestr 32-bitowy), a maska ​​sieci będzie miała wartość 0. Czy to nie jest właściwa odpowiedź? – Robert

+0

http://en.wikipedia.org/wiki/Bitwise_operation#Shifts_in_C.2C_C.2B.2B_i_Java mówi, że przesunięcie w lewo jest niezdefiniowane, jeśli wystąpi przepełnienie. MSVC i GCC oceniają 1 << 32 jako 1, nie 0. – bk1e

4

zawsze robię to tak (w przypadku CIDR = 24):

uint32_t ipv4Netmask; 

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

Będzie to działać tylko z ipv4Netmask aby być rzeczywiście uint32_t, nie sprawiają, że int, jako int nie robi w każdym systemie musi być 32-bitowy. Wynik jest konwertowany na kolejność bajtów sieciowych, ponieważ tego oczekuje większość funkcji systemowych.

+3

"wynik jest konwertowany na kolejność bajtów sieciowych" - Myślę, że zamierzałeś wpisać htonl (ipv4Netmask) –

1

Oto rozwiązanie w 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 

Z linii poleceń

>whatmask.vbs 123.12.123.17/23 
0xfffff700 
1

co tracić czas z odejmowaniem lub trójskładnikowych stwierdzeniami?

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

Jeśli wiesz, że twoja liczba całkowita ma dokładnie 32 bity, musisz tylko raz wpisać 0xffffffff.

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

Obie kompilują się dokładnie z tym samym kodem zestawu.

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

Należy zachować ostrożność podczas korzystania z poprzednich odpowiedzi z kodem jak:

0xFFFFFFFF << 32 - cidr 

lub

-1 << 32 - cidr 

W języku C# przynajmniej będzie maskować liczyć przesunięcie z 0x1F pierwszy. Tak więc, dla CIDR z prefiksu 0 (czyli cały zakres adres IPv4):

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

który nie jest to, co chcesz. Zamiast tego należy użyć:

int cidr=0; 
(int)(0xFFFFFFFFL << (32 - cidr)) == 0 
Powiązane problemy