เอาท์พุทที่อยู่ IPv4 สาธารณะแบบ unicast ที่ถูกต้อง


10

ที่อยู่ IPv4กว้าง 32 บิตและขนาดของพื้นที่ที่อยู่คือ 2 32หรือ 4,294,967,296 อย่างไรก็ตามนี่เป็นเพียงขอบเขตทฤษฎีเท่านั้น มันไม่ได้เป็นตัวแทนที่ถูกต้องของที่อยู่ทั้งหมดที่จริงอาจใช้บนอินเทอร์เน็ตสาธารณะ

สำหรับจุดประสงค์ของการท้าทายนี้จะถือว่าการกล่าวอ้างทั้งหมดนั้นมีระดับ ในความเป็นจริงการแบ่งพื้นที่ที่อยู่ในระดับคลาสได้ถูกแทนที่โดยCIDR (การกำหนดเส้นทาง Inter-Domain Classless และ VLSM (Masking Subnet Length Variable Length Variable)แต่สิ่งนี้ไม่สนใจความท้าทายนี้

ตามรูปแบบที่อยู่ที่คลาสมี 3 คลาส:

  • Class A - 0.0.0.0ถึง127.255.255.255ด้วย/8ความยาว netmask
  • Class B - 128.0.0.0ถึง191.255.255.255ด้วย/16ความยาว netmask
  • Class C - 192.0.0.0ถึง223.255.255.255ด้วย/24ความยาว netmask

คลาส D (multicast) และ E (สงวนไว้) ถูกกำหนดด้วยเช่นกัน แต่ไม่ได้ใช้สำหรับที่อยู่ unicast สาธารณะ

แต่ละคลาสจะถูกแบ่งย่อยออกเป็นเครือข่ายตาม netmask สำหรับคลาสนั้น

ดังนั้น3.0.0.0เป็นตัวอย่างของเครือข่าย Class A ความยาว netmask สำหรับ Class 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 (= 16777214) ที่อยู่ทั้งหมด

ในทำนองเดียวกัน200.20.30.0เป็นตัวอย่างของเครือข่าย Class C ความยาว netmask สำหรับ Class C เป็น 24 ดังนั้นพื้นที่ที่อยู่เต็มสำหรับเครือข่ายนี้เป็นไป200.20.30.0 200.20.30.255การถอดใบเครือข่ายและการออกอากาศอยู่ในช่วงที่เกิดขึ้นจริงของที่อยู่ที่ใช้งานได้เป็น200.20.30.1ไป200.20.30.254ซึ่งเป็น 2 8 - 2 (= 254) ที่อยู่ทั้งหมด

มีข้อ จำกัด เพิ่มเติมเกี่ยวกับช่วงที่อยู่ที่อาจใช้สำหรับ unicast สาธารณะ ตาม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 Relay Anycast
  • 192.168.0.0/16 - ใช้งานส่วนตัว
  • 198.18.0.0/15 - การเปรียบเทียบ
  • 198.51.100.0/24 - สงวนไว้สำหรับใช้ในเอกสารประกอบ
  • 203.0.113.0/24 - สงวนไว้สำหรับใช้ในเอกสารประกอบ

โปรดทราบว่ารายการด้านบนใช้ VLSR netmasks เพื่อระบุช่วงได้อย่างมีประสิทธิภาพ ในทุกกรณียกเว้นหนึ่งความยาวหน้ากากที่กำหนดมีความเฉพาะเจาะจงน้อยกว่าหรือเท่ากับความยาวหน้ากากที่มีระดับปกติสำหรับการเริ่มต้นของช่วง ดังนั้นแต่ละช่วง VLSR เหล่านี้จะเทียบเท่ากับเครือข่ายที่ดีงามอย่างน้อยหนึ่งเครือข่าย เช่น172.16.0.0/12เทียบเท่ากับเครือข่าย Class B 172.16.0.0ไป172.31.0.0หรือช่วงที่อยู่ที่จะ172.16.0.0172.31.255.255

ข้อยกเว้นสำหรับกฎนี้คือ100.64.0.0/10ช่วง VLSR ซึ่งเฉพาะเจาะจงมากขึ้นกว่าช่วง100.0.0.0Class A ที่มีอยู่ ดังนั้น100.0.0.0จะได้รับการจัดการเหมือนกับช่วง Class A อื่น ๆ ยกเว้นว่าจะมีช่องที่อยู่ 4,194,304 ที่อยู่ตรงกลาง ที่อยู่ที่ถูกต้องในช่วง Class A นี้จะเป็น 100.0.0.0ไป100.63.255.255และ 100.128.0.0จะ100.255.255.254มีทั้งหมด 2 ตลอด 24 - 2 22 - 2 (= 12582910) ที่อยู่ทั้งหมด

เป้าหมายของความท้าทายนี้คือการส่งออกที่อยู่ IPv4 ใน Class A, B และ C ทั้งหมดที่อาจได้รับมอบหมายอย่างถูกต้องให้กับโฮสต์อินเทอร์เน็ตสาธารณะ (เช่นไม่รวมที่อยู่ด้านบน)

  • จะไม่มีการป้อนข้อมูลใด ๆ และไม่ควรคาดหวัง

  • ผลลัพธ์อาจอยู่ในรูปแบบใดก็ได้ที่สะดวกสำหรับภาษาของคุณเช่นอาร์เรย์รายการสตริงที่คั่นด้วย ที่อยู่จะต้องถูกส่งออกในรูปแบบเลขฐานสิบแบบจุดประ

  • คำสั่งส่งออกไม่สำคัญ

  • Builtins ที่ให้ช่วงของที่อยู่ที่ต้องการโดยเฉพาะจะไม่ได้รับอนุญาต ในทำนองเดียวกันวิธีการใด ๆ ในการตรวจสอบตารางเส้นทางBGP (หรือโปรโตคอลอื่น) แบบไดนามิกสำหรับอินเทอร์เน็ตสาธารณะจะไม่ได้รับอนุญาต

ตัวเลขที่อยู่ต่ำสุดจะเป็นและตัวเลขที่สูงที่สุดจะเป็น1.0.0.1223.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]cast ไปยังการประกาศแรก$aซึ่งจะตัด casts อีกสองอันที่บันทึกไว้ 16 ไบต์

สามบรรทัด, Class A / Class B / Class C ปล่อยให้เป็นเส้นแยกเพื่อความสะดวกในการอ่าน ;-)

สองประเด็นสำคัญสำหรับการทำความเข้าใจว่าเกิดอะไรขึ้น:

  • PowerShell มีโอเปอเรเตอร์สองKB, MB, GBแห่ง ตัวอย่างเช่น4KBจะกลับมา4096เป็น int เราใช้ประโยชน์นั้นในหลาย ๆ สถานที่เพื่อโกนหลายสิบไบต์
  • [ipaddress]ชั้นNET. จะพยายามที่จะแยกค่าตัวเลขเป็นที่อยู่ IP โดยการเป็นตัวแทนไบนารีของตัวเลข เราใช้คอนสตรัคเตอร์นั้นพร้อมIPAddressToStringอาร์กิวเมนต์สำหรับเอาต์พุต

ด้วยการรวมสองสิ่งนี้เข้าด้วยกันเราสามารถจัดการที่อยู่ IP เป็นตัวเลขและวนรอบพวกเขาด้วยการfor()วนซ้ำ ยกตัวอย่างเช่นวงครั้งแรกสำหรับเครือข่ายย่อย Class A ไปจาก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เป็นจริง ดังนั้นเฉพาะถ้างบทั้งหมดเป็นจริงเราจะออกผลลัพธ์ของการแยก

Ungolfed เล็กน้อย:

# 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/bgoto:eof


1
ฉันนับ 1872 ไบต์ ในทางเทคนิคคุณไม่จำเป็นต้อง@echo offเช่นกัน
Addison Crump

@FlagAsSpam อาจเป็นไปได้ว่า CRs; Notepad ชอบที่จะบันทึก
Neil

ฉันคิดว่าคุณสามารถลบออกได้เนื่องจากเรานับด้วย Unix UTF-8 ไบต์
Addison Crump
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.