Pertanyaan Apa cara terbaik untuk mengkonversi dari bitcount jaringan ke netmask?


Sebagai contoh, jika saya memiliki spesifikasi jaringan seperti 172.20.10.0/24, "24" adalah bitcount. Apa cara terbaik untuk mengubahnya menjadi netmask seperti 0xffffff00?


8
2017-10-20 14:17


asal


Jawaban:


Mengapa membuang waktu dengan pernyataan substraksi atau terner?

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

Jika Anda tahu bilangan bulat Anda persis 32 bit maka Anda hanya perlu mengetik 0xffffffff sekali.

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

Keduanya dikompilasi ke kode assembly yang sama persis.


2
2018-02-24 20:19



Asumsikan mask 32-bit dan int 32-bit.

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

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

Catatan: ini belum tentu jawaban untuk pertanyaan "Apa cara terbaik untuk mendapatkan network mask untuk sebuah antarmuka?"


8
2017-10-20 14:30



Saya selalu melakukannya seperti itu (dalam kasus Anda cidr = 24):

uint32_t ipv4Netmask;

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

Ini hanya akan bekerja dengan ipv4Netmask untuk benar-benar uint32_t, jangan membuatnya int, karena int tidak harus 32 Bit pada setiap sistem. Hasilnya diubah menjadi urutan byte jaringan, karena itulah yang diharapkan oleh sebagian besar fungsi sistem.


4
2017-10-20 15:06



Ini bukan pertanyaan pemrograman, tetapi di linux Anda dapat menggunakan whatmask.

whatmask 72.20.10.0/24

kembali

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

2
2017-10-20 14:23



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

2
2017-10-20 14:33



Ini solusi di 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

Dari baris perintah

>whatmask.vbs 123.12.123.17/23
 0xfffff700

1
2017-10-20 15:30



Hati-hati ketika Anda menggunakan jawaban sebelumnya dengan kode seperti:

0xFFFFFFFF << 32 - cidr

atau

-1 << 32 - cidr

Dalam C # setidaknya, itu akan menutupi jumlah pergeseran dengan 0x1F terlebih dahulu. Jadi, untuk cidr dengan awalan 0 (yaitu seluruh rentang alamat IPv4):

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

yang bukan yang Anda inginkan. Sebagai gantinya, Anda harus menggunakan:

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

1
2017-12-16 15:01



Anda dapat mencoba sesuatu yang sederhana, seperti mengambil bitcount dan membaginya dengan 4. Itu akan memberi Anda F terkemuka di topeng. Dan kemudian ambil sisanya dan beralih dari 0 bit menjadi 3 bit.


0
2017-10-20 14:23



/* 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);

0
2018-04-14 22:22