Network BitCount에서 Netmask로 변환하는 가장 좋은 방법은 무엇입니까?

StackOverflow https://stackoverflow.com/questions/218604

  •  03-07-2019
  •  | 
  •  

문제

예를 들어, 172.20.10.0/24와 같은 네트워크 사양이있는 경우 "24"가 BitCount입니다. 0xffffff00과 같은 넷 마스크로 변환하는 가장 좋은 방법은 무엇입니까?

도움이 되었습니까?

해결책

뺄셈이나 3 차 진술로 시간을 낭비하는 이유는 무엇입니까?

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

정수가 정확히 32 비트라는 것을 알고 있다면 0xffffffff 만 입력하면됩니다.

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

둘 다 정확히 동일한 어셈블리 코드로 컴파일합니다.

다른 팁

32 비트 마스크 및 32 비트 int를 가정합니다.

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

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

참고 : 이것이 반드시 "인터페이스의 네트워크 마스크를 얻는 가장 좋은 방법은 무엇입니까?"라는 질문에 대한 답은 아닙니다.

나는 항상 그렇게한다 (당신의 경우 cidr = 24) :

uint32_t ipv4Netmask;

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

이것은 IPv4netmask에서만 작동하여 실제로 UINT32_T가되며 int가 모든 시스템에서 32 비트 일 필요는 없기 때문에 int를 만들지는 않습니다. 결과는 대부분의 시스템 기능이 기대하는 것과 같이 네트워크 바이트 순서로 변환됩니다.

이 코드는이 코드가 실패합니다 cidr 코드는 32 비트 변수를 32 비트 씩 이동하고 믿거 나 말거나 C에서 정의되지 않은 동작이라고 생각합니다. 결과는 항상 0이 될 것으로 예상하지만 C 표준은 이것이 시작하도록 정의되지 않았다고 말합니다. 와 함께. CIDR이 0이 될 수있는 경우 (모든 IP 주소 자리 표시 자 0.0.0.0/0에서만 허용되는 경우) 코드는 특별한 경우를 포착해야합니다.

이것은 프로그래밍 질문이 아니지만 Linux에서는 Whatmask를 사용할 수 있습니다.

whatmask 72.20.10.0/24

보고

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;

다음은 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

명령 줄에서

>whatmask.vbs 123.12.123.17/23
 0xfffff700

다음과 같은 코드와 함께 이전 답변을 사용할 때주의하십시오.

0xFFFFFFFF << 32 - cidr

또는

-1 << 32 - cidr

C#에서는 최소한 0x1F로 시프트 카운트를 마스킹합니다. 따라서 Prefix 0이있는 CIDR의 경우 (예 : 전체 IPv4 주소 범위) :

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

당신이 원하는 것이 아닙니다. 대신 사용해야합니다.

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

비트 컨트를 가져 가거나 4로 나누는 것과 같은 간단한 것을 시도 할 수 있습니다. 그런 다음 나머지를 가져 와서 0 비트에서 3 비트까지 스위치를 사용하십시오.

/* 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);
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top