유효한 모든 클래스 공용 퍼블릭 유니 캐스트 IPv4 주소 출력


10

IPv4 주소의 폭은 32 비트이므로 주소 공간의 크기는 2 32 또는 4,294,967,296입니다. 그러나 이것은 이론적 인 상한 일뿐입니다. 공용 인터넷에서 실제로 사용될 수있는 모든 주소를 정확하게 나타내는 것은 아닙니다.

이 과제의 목적을 위해 모든 주소 지정이 분류 된 것으로 가정합니다 . 실제로, 주소 공간의 분류 된 세분화는 CIDR (Classless Inter-Domain Routing 및 VLSM (Variable Length Subnet Masking)) 로 대체 되었지만,이 도전에서는 무시됩니다.

classful address scheme에 따르면 3 가지 클래스가 있습니다.

  • 클래스 A - 0.0.0.0127.255.255.255/8넷 마스크 길이
  • 클래스 B - 128.0.0.0191.255.255.255/16넷 마스크 길이
  • 클래스 C - 192.0.0.0223.255.255.255/24넷 마스크 길이

클래스 D (멀티 캐스트) 및 E (예약 됨)도 정의되지만 공용 유니 캐스트 주소에는 사용되지 않습니다.

각 클래스는 해당 클래스의 넷 마스크에 따라 네트워크로 세분됩니다.

따라서 3.0.0.0클래스 A 네트워크의 예입니다. 이 네트워크의 전체 주소 공간이 그래서 클래스 A에 대한 넷 마스크 길이는 8 3.0.0.03.255.255.255. 그러나 첫 번째 주소 ( 3.0.0.0)는 네트워크 주소로 예약되고 마지막 주소 ( 3.255.255.255)는 해당 네트워크의 브로드 캐스트 주소로 예약됩니다. 따라서, 가능한 주소가 실제의 범위는 다음 3.0.0.13.255.255.2542 인 24 - 2 (= 16,777,214) 전체 주소.

마찬가지로, 200.20.30.0클래스 C 네트워크의 예입니다. 이 네트워크의 전체 주소 공간이 그래서 클래스 C에 대한 넷 마스크 길이는 24이다 200.20.30.0200.20.30.255. 네트워크 및 방송 주소 잎을 가능한 주소의 실제 범위를 분리하는 것은 200.20.30.1200.20.30.254있는 2 8 2 (= 254) 전체 주소 -.

공용 유니 캐스트에 사용될 수있는 주소 범위에 대한 추가 제한이 있습니다. RFC 6890 에 따르면 허용되지 않는 범위는 다음과 같습니다.

  • 0.0.0.0/8 -로컬 네트워킹
  • 10.0.0.0/8 -개인 사용
  • 100.64.0.0/10 -공유 주소 공간
  • 127.0.0.0/8 -루프백
  • 169.254.0.0/16 -로컬 링크
  • 172.16.0.0/12-개인 사용
  • 192.0.0.0/24 -IETF 프로토콜 할당
  • 192.0.2.0/24 -문서에 사용하기 위해 예약 됨
  • 192.88.99.0/24 -6to4 릴레이 애니 캐스트
  • 192.168.0.0/16 -개인 사용
  • 198.18.0.0/15 -벤치마킹
  • 198.51.100.0/24 -문서에 사용하기 위해 예약 됨
  • 203.0.113.0/24 -문서에 사용하기 위해 예약 됨

위의 목록은 VLSR 넷 마스크를 사용하여 범위를 효율적으로 지정합니다. 하나의 경우를 제외한 모든 경우에, 주어진 마스크 ​​길이는 특이성이 범위의 시작에 대한 정상 분류 마스크 길이보다 작거나 같다. 따라서 이러한 VLSR 범위 각각은 하나 이상의 클래스 네트워크에 해당합니다. 예를 들면 172.16.0.0/12클래스 B 망에 해당 172.16.0.0하는 172.31.0.0또는 주소 범위 172.16.0.0172.31.255.255.

이 규칙의 예외는 100.64.0.0/10VLSR 범위이며, 이는 포함 100.0.0.0클래스 A 범위 보다 더 구체적 입니다. 따라서 100.0.0.0중간에 4,194,304 개의 주소 구멍이 있다는 점을 제외하고 다른 클래스 A 범위와 같이 처리됩니다. 이 클래스 A 범위에서 유효 주소는 것 100.0.0.0까지 100.63.255.255100.128.0.0100.255.255.254(2)의 총 24 2 - 22 - 2 (= 12,582,910) 전체 주소.

이 문제의 목표는 퍼블릭 인터넷 호스트에 유효하게 할당 될 수있는 모든 클래스 A, B 및 C 유니 캐스트 IPv4 주소를 출력하는 것입니다 (즉, 위에서 자세히 설명한 것 제외).

  • 입력이 제공되지 않으며 예상해서는 안됩니다.

  • 출력은 배열, 목록, 구분 문자열과 같이 사용자 언어에 편리한 형태 일 수 있습니다. 주소는 표준 점으로 구분 된 10 진수 형식으로 출력되어야합니다.

  • 출력 순서는 중요하지 않습니다.

  • 필요한 주소 범위를 구체적으로 제공하는 기본 제공은 허용되지 않습니다. 마찬가지로 공용 인터넷에 대한 BGP (또는 다른 프로토콜) 라우팅 테이블 을 동적으로 검사하는 방법 도 허용되지 않습니다.

숫자가 가장 낮은 주소는 1.0.0.1이고 숫자가 가장 높은 주소는 223.255.255.254입니다.


이 과제는 모든 IPv6 주소 인쇄 와 유사 하지만 제한 사항 때문에 사소한 다른 구현이 필요합니다.

답변:


2

PowerShell을, 648 641 625 바이트

for([uint64]$a=16MB;$a-lt2GB-16mb;$a++){if(($a%16mb)*(($a+1)%16mb)*($a-lt160MB-or$a-gt176MB)*($a-lt1604MB-or$a-ge1608MB)){([ipaddress]$a).IPAddressToString}}
for($a=2GB;$a-lt3GB;$a++){if(($a%64kb)*(($a+1)%64kb)*($a-lt2785152kb-or$a-gt2720mb)*($a-lt2753mb-or$a-gt2754mb)){([ipaddress]$a).IPAddressToString}}
for($a=3221225728;$a-lt3.5GB;$a++){if(($a%256)*(($a+1)%256)*(($a-lt3221225984-or$a-gt3221226240))*(($a-lt3227017984-or$a-gt3151385kb))*(($a-lt3156480kb-or$a-gt3156544kb))*(($a-lt3245184kb-or$a-gt3245312kb))*(($a-lt3247321kb-or$a-gt3325256959))*(($a-lt3405803776-or$a-gt3405804032))){([ipaddress]$a).IPAddressToString}}

편집 1-나머지 2의 제곱 연산자를 모두 골라서 추가로 7 바이트를 절약했습니다.
편집 2- [uint64]캐스트를 첫 번째 선언으로 이동하여 $a16 바이트를 절약 한 다른 두 개의 재 캐스트를 제거했습니다.

클래스 A / 클래스 B / 클래스 C의 세 줄. 가독성을 위해 별도의 줄로 남겨 둡니다. ;-)

진행 상황을 이해하기위한 두 가지 핵심 사항 :

  • PowerShell에는 2의 거듭 제곱 연산자가 KB, MB, GB있습니다. 예를 들어 int로 4KB반환 4096됩니다. 이를 여러 위치에서 활용하여 수십 바이트를 면도합니다.
  • .NET [ipaddress]클래스는 숫자의 이진 표현을 사용하여 숫자 값을 IP 주소로 구문 분석 합니다. 해당 생성자 IPAddressToString를 출력 인수 와 함께 사용합니다 .

이 두 가지를 결합함으로써 IP 주소를 숫자로 취급하고 루프를 통해 반복 할 수 있습니다 for(). 예를 들어, A 클래스 서브넷에 대한 제 1 루프에서 진행을 16MB2GB-16MB하거나로부터 167772162130706432. 의 이진 표현 16777216이다 1000000000000000000000000또는 00000001.00000000.00000000.00000000우리가 8 비트 청크로 분할하는 경우 우리가 쉽게 해당 대응을 볼 수 있도록 1.0.0.0점으로 구분 된 십진수 표기법으로. 마찬가지로, 2130706432로 쓸 수있다 01111111000000000000000000000000거나 01111111.00000000.00000000.00000000또는 127.0.0.0. 여기서 사용되는 각 정수 또는 2의 제곱은 이러한 방식으로 IP 주소로 다시 쓸 수 있습니다.

따라서 루프 반복마다 if()개별 명령문을 곱하여 제외 된 주소를 제거 하는 명령문을 구성합니다 . 각각의 첫 번째 문이 때문에 if정수 (모듈로 테스트 덕분에)이며, 나머지 부울 값에 어느 변환됩니다 0또는 1참 / 거짓을 위해. 진술 중 하나라도 거짓이면 전체 곱셈이 바뀌어 0거짓이됩니다. 따라서 모든 진술이 참인 경우에만 파싱 결과를 출력 할 것입니다.

약간 골퍼되지 않음 :

# Class A
for($a=16MB;$a-lt2GB-16mb;$a++){
  $b=($a%16mb)                     # x.0.0.0
  $b*=(($a+1)%16mb)                # x.255.255.255
  $b*=($a-lt160MB-or$a-gt176MB)    # 10.0.0.0/8
  $b*=($a-lt1604MB-or$a-ge1608MB)  # 100.64.0.0/10
  if($b){([ipaddress]::Parse($a)).IPAddressToString}
}

# Class B
for($a=2GB;$a-lt3GB;$a++){
  $b=($a%64kb)                           # x.y.0.0
  $b*=(($a+1)%64kb)                      # x.y.255.255
  $b*=(($a-lt2785152kb-or$a-gt2720mb))  # 169.254.0.0/16
  $b*=(($a-lt2753mb-or$a-gt2754mb))      # 172.16.0.0/12
  if($b){([ipaddress]::Parse($a)).IPAddressToString}
}

# Class C
for($a=3221225728;$a-lt3.5GB;$a++){
  $b=($a%256)                               # x.y.z.0
  $b*=(($a+1)%256)                          # x.y.z.255
  $b*=(($a-lt3221225984-or$a-gt3221226240)) # 192.0.2.0/24
  $b*=(($a-lt3227017984-or$a-gt3151385kb)) # 192.88.99.0/24
  $b*=(($a-lt3156480kb-or$a-gt3156544kb)) # 192.168.0.0/16
  $b*=(($a-lt3245184kb-or$a-gt3245312kb)) # 198.18.0.0/15
  $b*=(($a-lt3247321kb-or$a-gt3325256959)) # 198.51.100.0/24
  $b*=(($a-lt3405803776-or$a-gt3405804032)) # 203.0.113.0/24
  if($b){([ipaddress]::Parse($a)).IPAddressToString}
}

1

배치, 1930 1884 1848 1830 바이트

@echo off
for /l %%a in (1,1,9)do call:a1 %%a
for /l %%a in (11,1,99)do call:a1 %%a
for /l %%b in (0,1,63)do call:a2 100 %%b
for /l %%b in (128,1,255)do call:a2 100 %%b
for /l %%a in (101,1,126)do call:a1 %%a
for /l %%a in (128,1,168)do call:b1 %%a
for /l %%b in (0,1,253)do call:b2 169 %%b
call:b2 169 255
call:b1 170
call:b1 171
for /l %%b in (0,1,15)do call:b2 172 %%b
for /l %%b in (32,1,255)do call:b2 172 %%b
for /l %%a in (173,1,191)do call:b1 %%a
call:c3 192 0 1
for /l %%c in (3,1,255)do call:c3 192 0 %%c
for /l %%b in (1,1,87)do call:c2 192 %%b
for /l %%c in (0,1,98)do call:c3 192 88 %%c
for /l %%c in (100,1,255)do call:c3 192 88 %%c
for /l %%b in (89,1,167)do call:c2 192 %%b
for /l %%b in (169,1,255)do call:c2 192 %%b
for /l %%a in (193,1,197)do call:c1 %%a
for /l %%b in (0,1,17)do call:c2 198 %%b
for /l %%b in (20,1,50)do call:c2 198 %%b
for /l %%c in (0,1,99)do call:c3 198 51 %%c
for /l %%c in (101,1,255)do call:c3 198 51 %%c
for /l %%b in (52,1,255)do call:c2 198 %%b
for /l %%a in (199,1,202)do call:c1 %%a
for /l %%c in (0,1,112)do call:c3 203 0 %%c
for /l %%c in (114,1,255)do call:c3 203 0 %%c
for /l %%b in (1,1,255)do call:c2 203 %%b
for /l %%a in (204,1,223)do call:c1 %%a
exit/b
:a1
for /l %%b in (0,1,255)do call:a2 %1 %%b
exit/b
:a2
for /l %%c in (0,1,255)do call:a3 %1 %2 %%c
exit/b
:a3
for /l %%d in (0,1,255)do if not %2%3%%d==000 if not %2%3%%d==255255255 echo %1.%2.%3.%%d
exit/b
:b1
for /l %%b in (0,1,255)do call:b2 %1 %%b
exit/b
:b2
for /l %%c in (0,1,255)do call:b3 %1 %2 %%c
exit/b
:b3
for /l %%d in (0,1,255)do if not %3%%d==00 if not %3%%d==255255 echo %1.%2.%3.%%d
exit/b
:c1
for /l %%b in (0,1,255)do call:c2 %1 %%b
exit/b
:c2
for /l %%c in (0,1,255)do call:c3 %1 %2 %%c
exit/b
:c3
for /l %%d in (1,1,254)do echo %1.%2.%3.%%d

편집 : 불필요한 공간을 제거하여 46 82 바이트를 절약했습니다 . exit/b대신을 사용하여 18 바이트를 절약했습니다 goto:eof.


1
1872 바이트를 셉니다. 당신은 기술적으로 필요하지 않습니다 @echo off뿐만 아니라.
애디슨

@FlagAsSpam 아마도 CRs; 메모장은 저장을 좋아합니다.
Neil

유닉스 UTF-8 바이트로 계산하기 때문에 제거 할 수 있다고 생각합니다.
애디슨 크럼
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.