Виведіть усі дійсні класичні публічні одноадресні IPv4 адреси


10

IPv4 адреси шириною 32 біти, і таким чином розмір адресного простору становить 2 32 , або 4,294,967,296. Однак це лише теоретична верхня межа. Це не точне подання всіх адрес, які фактично можуть використовуватися в загальнодоступному Інтернеті.

Для цілей цього виклику передбачається, що вся адресація є класною . Насправді класичний підрозділ адресного простору витіснив CIDR (безкласовий маршрутизація між доменами та VLSM (маскування підмережі змінної довжини) , але це ігнорується для цього завдання.

Відповідно до схеми класних адрес, існує 3 класи:

  • Клас А - 0.0.0.0щоб 127.255.255.255з /8NETMASK довжиною
  • Клас B - 128.0.0.0щоб 191.255.255.255з /16NETMASK довжиною
  • Клас C - 192.0.0.0щоб 223.255.255.255з /24NETMASK довжиною

Класи D (багатоадресна передача) та E (зарезервовані) також визначені, але вони не використовуються для публічних адрес одноадресної передачі.

Кожен клас підрозділяється на мережі відповідно до маски для цього класу.

Таким чином, 3.0.0.0є прикладом мережі класу A. Довжина мережі маски для класу A становить 8, тому повний адресний простір для цієї мережі повинен 3.0.0.0бути 3.255.255.255. Однак перша адреса ( 3.0.0.0) зарезервована як адреса мережі, а остання адреса ( 3.255.255.255) зарезервована як адреса широкомовної передачі для цієї мережі. Таким чином, фактичний діапазон використовуваних адрес 3.0.0.1для 3.255.255.254якого становить 2 24 - 2 (= 16,777,214) весь адреса.

Аналогічно 200.20.30.0є прикладом мережі класу C. Довжина сітки маски для класу C становить 24, тому повний адресний простір для цієї мережі повинен 200.20.30.0бути 200.20.30.255. Видалення мережі і широкомовні адреси залишають фактичний діапазон використовуваних адрес 200.20.30.1для 200.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 естафета Anycast
  • 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, Еквівалентно мережам класу В 172.16.0.0до 172.31.0.0або діапазону адрес 172.16.0.0до 172.31.255.255.

Виняток із цього правила - 100.64.0.0/10діапазон VLSR, який є більш специфічним, ніж містить 100.0.0.0діапазон класу A. Таким чином, 100.0.0.0буде оброблятися, як і інші діапазони класу A, за винятком того, що він має в центрі отвір 4,194,304. Дійсні адреси в цьому діапазоні класу A будуть 100.0.0.0до 100.63.255.255та 100.128.0.0до 100.255.255.254, загалом 2 24 - 2 22 - 2 (= 12,582,910) загальних адрес.

Мета цього виклику - вивести всі одноадресні IPv4 адреси класів A, B і C, які можуть бути дійсно призначені для загальнодоступного хоста в Інтернеті (тобто виключаючи описані вище).

  • Жодного вводу не буде надано і не слід очікувати.

  • Вихід може бути в будь-якій формі, зручній для вашої мови, наприклад, масив, список, розділений рядок. Адреси повинні виводитися у стандартному крапковому форматі у десятковій формі.

  • Порядок виводу не має значення.

  • Вбудовані, які конкретно дають необхідні діапазони адрес, заборонені. Аналогічно будь-які методи динамічної перевірки таблиці маршрутизації 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 - Я розіграв усі оператори, що залишилися з двома повноваженнями, що дозволило зберегти ще 7 байт.
Редагувати 2 - Перемістив команду [uint64]на перше оголошення, $aяке усунуло два інші повторні касти, які зберегли 16 байт.

Три лінії, клас A / клас B / клас C. Залишилися як окремі лінії для читання. ;-)

Два ключових моменти для розуміння того, що відбувається:

  • PowerShell має повноваження двох операторів KB, MB, GB. Наприклад, 4KBповернеться 4096як int. Ми використовуємо, щоб у кількох місцях голити десятки байтів.
  • Клас .NET [ipaddress]спробує проаналізувати числове значення як IP-адресу, взявши двійкове представлення числа. Ми використовуємо цей конструктор з IPAddressToStringаргументом для виведення.

Поєднуючи ці дві речі, ми можемо просто розглядати IP-адреси як числа і пробирати через них for()цикл. Наприклад, перша петля для підмереж класу А переходить від 16MBдо 2GB-16MBабо від 16777216до 2130706432. Двійкове представлення 16777216є 1000000000000000000000000або 00000001.00000000.00000000.00000000якщо ми розділимо його на 8-бітні відрізки, щоб ми могли легко побачити, що відповідає 1.0.0.0в крапкових десяткових позначеннях. Аналогічно 2130706432можна записати як 01111111000000000000000000000000або 01111111.00000000.00000000.00000000або 127.0.0.0. Кожне ціле ціле число або ціле число двох потужностей, використане тут, може бути переписане в якості 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 байти, видаливши зайві пробіли. Збережено 18 байт за допомогою, exit/bа не goto:eof.


1
Я рахую 1872 байти. Ви технічно не потрібен @echo off, а також.
Аддісон Кримп

@FlagAsSpam Напевно, CR; Блокнот любить їх зберігати.
Ніл

Я думаю, ви можете їх видалити, оскільки ми рахуємо Unix UTF-8 байт.
Аддісон Кримп
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.