Xuất tất cả các địa chỉ IPv4 unicast công khai hợp lệ


10

Địa chỉ IPv4 rộng 32 bit và do đó kích thước của không gian địa chỉ là 2 32 , hoặc 4.294.967.296. Tuy nhiên, đây chỉ là một lý thuyết trên giới hạn. Nó không phải là một đại diện chính xác của tất cả các địa chỉ thực sự có thể được sử dụng trên internet công cộng.

Đối với các mục đích của thách thức này, nó được giả định rằng tất cả các địa chỉ là đầy đủ . Trong thực tế, việc phân chia không gian địa chỉ đầy đủ đã được thay thế bởi CIDR (Định tuyến giữa các miền không phân loại và VLSM (Mặt nạ mạng con biến đổi độ dài) , nhưng điều này bị bỏ qua cho thách thức này.

Theo sơ đồ địa chỉ lớp, có 3 lớp:

  • Class A - 0.0.0.0đến 127.255.255.255với /8chiều dài netmask
  • Class B - 128.0.0.0đến 191.255.255.255với /16chiều dài netmask
  • Lớp C - 192.0.0.0để 223.255.255.255với /24chiều dài netmask

Các lớp D (multicast) và E (dành riêng) cũng được định nghĩa, nhưng chúng không được sử dụng cho các địa chỉ unicast công khai.

Mỗi lớp được chia thành các mạng theo netmask cho lớp đó.

Vì vậy, đây 3.0.0.0là một ví dụ về mạng lớp A. Chiều dài mặt nạ mạng cho lớp A là 8, vì vậy không gian địa chỉ đầy đủ cho mạng này là 3.0.0.0để 3.255.255.255. Tuy nhiên, địa chỉ đầu tiên ( 3.0.0.0) được dành riêng làm địa chỉ mạng và địa chỉ cuối cùng ( 3.255.255.255) được dành riêng làm địa chỉ quảng bá cho mạng đó. Do đó, phạm vi thực tế của các địa chỉ có thể sử dụng là 3.0.0.1để 3.255.255.254đó là 2 24 - 2 (= 16.777.214) tổng số địa chỉ.

Tương tự, 200.20.30.0là một ví dụ về mạng Lớp C. Chiều dài mặt nạ mạng cho lớp C là 24, vì vậy không gian địa chỉ đầy đủ cho mạng này là 200.20.30.0để 200.20.30.255. Loại bỏ các địa chỉ mạng và phát sóng lá phạm vi thực tế của các địa chỉ có thể sử dụng là 200.20.30.1để 200.20.30.254đó là 2 8 - 2 (= 254) tổng số địa chỉ.

Có nhiều hạn chế hơn về phạm vi địa chỉ có thể được sử dụng cho unicast công khai. Theo RFC 6890 , các phạm vi không được phép là:

  • 0.0.0.0/8 - Mạng cục bộ
  • 10.0.0.0/8 - Sử dụng cá nhân
  • 100.64.0.0/10 - Không gian địa chỉ dùng chung
  • 127.0.0.0/8 - Vòng lặp
  • 169.254.0.0/16 - Liên kết cục bộ
  • 172.16.0.0/12- Sử dụng cá nhân
  • 192.0.0.0/24 - Bài tập về Giao thức IETF
  • 192.0.2.0/24 - Dành để sử dụng trong tài liệu
  • 192.88.99.0/24 - Anycast Rơle 6to4
  • 192.168.0.0/16 - Sử dụng cá nhân
  • 198.18.0.0/15 - Điểm chuẩn
  • 198.51.100.0/24 - Dành để sử dụng trong tài liệu
  • 203.0.113.0/24 - Dành để sử dụng trong tài liệu

Lưu ý rằng danh sách trên sử dụng mạng lưới VLSR để chỉ định hiệu quả một phạm vi. Trong tất cả trừ một trường hợp, độ dài mặt nạ đã cho có độ đặc hiệu nhỏ hơn hoặc bằng độ dài mặt nạ lớp thông thường để bắt đầu phạm vi. Do đó, mỗi phạm vi VLSR này tương đương với một hoặc nhiều mạng lớp. Ví dụ như 172.16.0.0/12là tương đương với mạng lớp B 172.16.0.0để 172.31.0.0hoặc dải địa chỉ 172.16.0.0để 172.31.255.255.

Ngoại lệ cho quy tắc này là 100.64.0.0/10phạm vi VLSR, cụ thể hơn 100.0.0.0phạm vi chứa Lớp A. Do đó, 100.0.0.0sẽ được xử lý như các phạm vi Hạng A khác với ngoại lệ là nó có một lỗ địa chỉ 4.194.304 ở giữa. Các địa chỉ hợp lệ trong phạm vi lớp A này sẽ 100.0.0.0đến 100.63.255.255100.128.0.0đến 100.255.255.254, tổng cộng 2 24 - 2 22 - 2 (= 12.582.910) tổng số địa chỉ.

Mục tiêu của thách thức này là xuất ra tất cả các địa chỉ IPv4 loại A, B và C có thể được gán hợp lệ cho một máy chủ internet công cộng (nghĩa là không bao gồm các địa chỉ chi tiết ở trên).

  • Không có đầu vào sẽ được đưa ra và không nên được mong đợi.

  • Đầu ra có thể ở bất kỳ dạng nào thuận tiện cho ngôn ngữ của bạn, ví dụ như mảng, danh sách, chuỗi phân tách. Địa chỉ phải được xuất ở định dạng thập phân rải rác tiêu chuẩn.

  • Thứ tự đầu ra không quan trọng.

  • Các nội dung cụ thể cung cấp phạm vi địa chỉ yêu cầu không được phép. Tương tự, bất kỳ phương pháp nào để tự động kiểm tra bảng định tuyến BGP (hoặc giao thức khác) cho internet công cộng đều không được phép.

Địa chỉ thấp nhất về số sẽ là 1.0.0.1và cao nhất về số 223.255.255.254.


Thách thức này tương tự như In ra tất cả các địa chỉ IPv6 , nhưng do các hạn chế nên yêu cầu triển khai không tầm thường.

Câu trả lời:


2

PowerShell, 648 641 625 byte

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}}

Chỉnh sửa 1 - Tôi đã đánh bại tất cả các toán tử hai quyền hạn còn lại, giúp tiết kiệm thêm 7 byte.
Chỉnh sửa 2 - Đã chuyển [uint64]cast sang khai báo đầu tiên trong $ađó loại bỏ hai phôi khác đã lưu 16 byte.

Ba dòng, Class A / Class B / Class C. Còn lại là các dòng riêng biệt để dễ đọc. ;-)

Hai điểm chính để hiểu những gì đang xảy ra:

  • PowerShell có hai nhà khai thác quyền hạn KB, MB, GB. Ví dụ, 4KBsẽ trở lại 4096như một int. Chúng tôi tận dụng điều đó ở nhiều vị trí để cạo hàng chục byte.
  • Lớp .NET [ipaddress]sẽ cố phân tích một giá trị số dưới dạng địa chỉ IP bằng cách lấy biểu diễn nhị phân của số đó. Chúng tôi sử dụng hàm tạo đó với IPAddressToStringđối số cho đầu ra.

Bằng cách ghép hai thứ đó, chúng ta có thể coi địa chỉ IP là số và lặp qua chúng bằng một for()vòng lặp. Ví dụ, vòng lặp đầu tiên cho các mạng con lớp A đi từ 16MBđến 2GB-16MBhoặc từ 16777216đến 2130706432. Biểu diễn nhị phân 167772161000000000000000000000000hoặc 00000001.00000000.00000000.00000000nếu chúng ta chia nó thành các đoạn 8 bit để chúng ta có thể dễ dàng thấy điều đó tương ứng với 1.0.0.0ký hiệu thập phân rải rác. Tương tự như vậy, 2130706432có thể được viết như 01111111000000000000000000000000hoặc 01111111.00000000.00000000.00000000hoặc 127.0.0.0. Mỗi số nguyên, hoặc số nguyên hai, được sử dụng ở đây có thể được viết lại dưới dạng địa chỉ IP theo kiểu này.

Vì vậy, với mỗi lần lặp lại, chúng tôi xây dựng một if()câu lệnh để loại bỏ các địa chỉ bị loại trừ, bằng cách nhân các câu lệnh riêng lẻ lại với nhau. Kể từ khi tuyên bố đầu tiên trong mỗi iflà một số nguyên (nhờ việc thử nghiệm modulo), các giá trị Boolean còn lại được chuyển đổi sang một trong hai 0hoặc 1cho sai / đúng. Nếu bất kỳ một trong các câu lệnh là sai, toàn bộ phép nhân sẽ chuyển sang 0và do đó là sai. Vì vậy, chỉ khi tất cả các câu lệnh là đúng, chúng ta sẽ đưa ra kết quả của việc phân tích cú pháp.

Hơi bất ngờ:

# 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

Batch, 1930 1884 1848 1830 byte

@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

Chỉnh sửa: Đã lưu 46 82 byte bằng cách xóa các khoảng trống không cần thiết. Đã lưu 18 byte bằng cách sử dụng exit/bthay vì goto:eof.


1
Tôi đếm 1872 byte. Về mặt kỹ thuật bạn cũng không cần @echo off.
Addison Crump

@FlagAsSpam Có lẽ là CR; Notepad thích lưu chúng.
Neil

Tôi nghĩ bạn có thể loại bỏ chúng, vì chúng tôi đếm bằng byte UTF-8 của Unix.
Addison Crump
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.