แก้ไขช่วงเวลาที่หายไปของที่อยู่ IPv4 ของฉัน


37

บางครั้งเมื่อฉันพิมพ์ที่อยู่ IPv4 ฉันได้รับหมายเลขทั้งหมดถูกต้อง แต่ฉันลืมพิมพ์หนึ่งจุดขึ้นไป ฉันต้องการมีโปรแกรม (หรือฟังก์ชั่น) ที่ใช้ที่อยู่ IPv4 ที่เสียหายของฉันและแสดงตำแหน่งที่ถูกต้องทั้งหมดในช่วงเวลาที่หายไป

อินพุต

ข้อมูลที่ป้อนจะเป็นสตริงที่เป็นการแปลงที่อยู่ IPv4 ที่ถูกต้องเสมอ (ดูรายการด้านล่าง) มันจะถูกแปลงโดยการกำจัดของตัวละครระยะเวลาหนึ่งหรือมากกว่าเท่านั้น

การส่งของคุณไม่จำเป็นต้องจัดการอินพุตนอกรูปแบบนี้

เอาท์พุต

คอลเล็กชันหรือรายการโดยไม่เรียงตามลำดับหรือรูปแบบของสตริงที่แสดงที่อยู่ IPv4 ที่ถูกต้องทั้งหมดที่สามารถสร้างขึ้นจากอินพุตโดยการแทรกอักขระช่วงเวลาลงในอินพุต

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

รูปแบบที่อยู่ IPv4

ในขณะที่ที่อยู่ IPv4 นั้นเป็นเพียงลำดับของ octet ไบนารีสี่ตัวความท้าทายนี้ใช้รูปแบบทศนิยมแบบ จำกัด ที่มีจุด

  • ที่อยู่ IPv4 เป็นค่าทศนิยมสี่ค่าที่คั่นด้วยสามจุด
  • ค่าทั้งสี่นั้นอยู่ในช่วง0ที่255ครอบคลุม
  • ไม่อนุญาตให้นำหน้าศูนย์ในค่าตัวเลขใด ๆ (สแตนด์อโลนหนึ่งตัวละคร0ที่ได้รับอนุญาต; หมายเลขอื่น ๆ ที่เริ่มต้นด้วยศูนย์ไม่ได้: 052, 00ฯลฯ )

กรณีทดสอบ

อินพุตอยู่ในบรรทัดแรกเอาท์พุทในบรรทัดที่สอง (ที่นี่มีโครงสร้างเป็นรายการที่คั่นด้วยเครื่องหมายจุลภาคของสตริงที่ยกมาคั่นด้วยเครื่องหมายจุลภาคล้อมรอบด้วย[ ]แต่คุณอาจใช้รูปแบบหรือโครงสร้างที่เหมาะสมตามที่ระบุไว้ข้างต้น) ตัวอย่างบางส่วนมีหมายเหตุในบรรทัดที่สามเพื่อเน้นแอปพลิเคชันของกฎเฉพาะ

192.168.1234
["192.168.1.234", "192.168.12.34", "192.168.123.4"]

192.1681234
["192.16.81.234", "192.168.1.234", "192.168.12.34", "192.168.123.4"]
(Note: 192.1681.2.34 (etc.) is illegal because 1681 is greater than 255)

1921681.234
["19.216.81.234", "192.16.81.234", "192.168.1.234"]

1921681234
["19.216.81.234", "192.16.81.234", "192.168.1.234", "192.168.12.34", "192.168.123.4"]

192.168.1204
["192.168.1.204", "192.168.120.4"]
(Note: 192.168.12.04 is illegal because of leading zero)

192.168.123
["1.92.168.123", "19.2.168.123", "192.1.68.123", "192.16.8.123", "192.168.1.23", "192.168.12.3"]

192.168.256
["192.168.2.56", "192.168.25.6"]
(Note: Any combination that would leave 256 intact is illegal)

120345
["1.20.3.45", "1.20.34.5", "1.203.4.5", "12.0.3.45", "12.0.34.5", "120.3.4.5"]
(Note: 12.03.4.5 (etc.) is illegal due to leading zero.)

012345
["0.1.23.45", "0.1.234.5", "0.12.3.45", "0.12.34.5", "0.123.4.5"]
(Note: the first segment must be 0, because `01` or `012` would be illegal.)

000123
["0.0.0.123"]

(ฉันทำตัวอย่างเหล่านี้ด้วยมือดังนั้นโปรดแจ้งเตือนฉันถึงข้อผิดพลาดที่คุณอาจพบ)


การส่งออกเป็นเรื่องสำคัญ
คุณ

@YOU ไม่: " คอลเล็กชันหรือรายการโดยไม่เรียงลำดับหรือรูปแบบเฉพาะ ... "
apsillers

ไม่อนุญาตให้นำหน้าด้วย : นำไปใช้กับอินพุตด้วยหรือไม่
Luis Mendo

3
ดังนั้น .... "000125" ควรส่งคืนโซลูชันที่ถูกต้องเพียงวิธีเดียว ... 0.0.0.125
Keeta

2
@Keeta นั่นถูกต้องแน่ ๆ (ฉันเพิ่งเพิ่มมันเป็นกรณีทดสอบ)
apsillers

คำตอบ:


9

Pyth, 24 ไบต์

f&q4lJcT\.!-J`M256jL\../

ลองออนไลน์

มันทำงานอย่างไร

                      ./Q   all partitions of input
                  jL\.      join each on .
f                           filter for results T such that:
      cT\.                    split T on .
     J                        assign to J
    l                         length
  q4                          equals 4
 &                            … and:
           -J`M256              J minus the list of representations of [0, …, 255]
          !                     is false (empty)

Pyth, 17 ไบต์, ช้ามาก

@FjLL\.,^U256 4./

การเตือน อย่าวิ่ง. ต้องการ RAM ประมาณ 553 GiB

มันทำงานอย่างไร

       ,             two-element list of:
        ^U256 4        all four-element lists of [0, …, 255]
               ./Q     all partitions of input
  jLL\.              join each element of both on .
@F                   fold intersection

ดี! เพื่อความเข้าใจของฉันเอง "พาร์ทิชั่นอินพุตทั้งหมด" หมายถึงวิธีที่เป็นไปได้ทั้งหมดของการแบ่งเซกเมนต์อินพุตใช่ไหม ดังนั้นคุณทำให้ทุกการแยกที่เป็นไปได้และจากนั้นเข้าร่วมการแยกด้วยจุดดังนั้นคุณจะจบลงด้วยผู้สมัครจำนวนมากเช่น1.9.2.1.6.8.1.2และ19.2.1.6.8.1.2อื่น ๆ ? (แต่เห็นได้ชัดว่าสิ่งที่ไม่ถูกต้องทั้งหมดจะถูกกรองออกไป)
apsillers

@apsillers ถูกต้อง
Anders Kaseorg

16

C (gcc / linux), 125 121 ไบต์

i;f(char*a){do{char*y=a,s[99],*x=inet_ntop(2,&i,s,99);for(;*x&&!(*x^*y&&*x^46);++x)y+=*x==*y;*x|*y||puts(s);}while(++i);}

วนรอบที่อยู่ IPv4 ที่เป็นไปได้ทั้งหมดและทำการเปรียบเทียบแบบกำหนดเองที่ข้ามจุดพิเศษในที่อยู่ IP ที่สร้างขึ้น (แต่ไม่ใช่ในที่อยู่หลักเปรียบเทียบ) เพื่อตัดสินใจว่าจะพิมพ์หรือไม่ ช้ามาก แต่ควรเสร็จสิ้นภายใน 1 ชั่วโมงบนเครื่องพีซีที่เหมาะสม


i=0;คุณสามารถลบ
betseg

@RelasingHeliumNuclei ฉันคิดว่าฉันไม่สามารถ (ฟังก์ชั่นจะต้องใช้งานได้อีกครั้ง) แต่ตอนนี้ฉันตระหนักว่าหลังจากฟังก์ชั่นiเป็น 0 อีกครั้ง ...
orlp

6

Perl 5, 91 ไบต์

<>=~/^(([1-9]?|1\d|2[0-4])\d|25[0-5])\.?((?1))\.?((?1))\.?((?1))$(?{print"$1.$3.$4.$5 "})^/

โปรแกรมคาดว่าบรรทัดเดียวของอินพุตและเอาต์พุตรายการที่คั่นด้วยช่องว่างของผู้สมัคร

คำอธิบาย

โปรแกรมใช้ประโยชน์จากคุณลักษณะการย้อนรอยของ regex เพื่อวนซ้ำความเป็นไปได้ทั้งหมดของการสร้างที่อยู่ IPv4 ที่ถูกต้องจากสตริงอินพุต

^(([1-9]?|1\d|2[0-4])\d|25[0-5])\.?((?1))\.?((?1))\.?((?1))$

IPv4 regex ที่มี.หรือไม่มีก็ได้ไม่มีอะไรที่นี่

(?{print"$1.$3.$4.$5 "})

นิพจน์การประเมินโค้ดที่พิมพ์เนื้อหาของกลุ่มการดักจับ

^

ทำให้การแข่งขันล้มเหลวและบังคับให้ย้อนรอย

ตัวอย่างการวิ่ง

$ echo "012345" | perl G89503.pl
0.12.34.5 0.12.3.45 0.1.23.45 0.1.234.5 0.123.4.5

5

JavaScript (ES6), 147 141 135 ไบต์

f=(s,n=0)=>(a=s.split`.`)[3]?a.every(s=>s==`0`|s[0]>0&s<256)?s+' ':'':[...s].map((_,i)=>i>n?f(s.slice(0,i)+`.`+s.slice(i),i):``).join``
<input placeholder=Input oninput=o.textContent=f(this.value)><div id=o style=font-family:monospace;width:1em>Output

แก้ไข: บันทึก 6 ไบต์ด้วย @apsillers บันทึกอีก 6 ไบต์โดยคัดลอกการทดสอบความถูกต้องของ @You


มีความแตกต่างระหว่าง [1-9] | 0 และ [0-9] หรือ \ d ??
คุณ

@apsillers อ่าใช่รหัสรุ่นก่อนหน้าของฉันสามารถสร้างส่วนท้าย.ที่จะทดสอบ แต่ฉันคิดว่ารุ่นนี้ตกลง
Neil

@YOU บิตที่สำคัญคือว่ามี0 $(นอกจากนี้ยังขาดหายไป^ดังนั้นขอขอบคุณสำหรับการดึงความสนใจของฉันไปมัน.)
นีล

@apsillers Sadly spliceไม่ทำงานอย่างนั้นมันจะปรับเปลี่ยนอาร์เรย์และส่งกลับองค์ประกอบที่ถูกลบออก
Neil

4

Python 3, 232 ไบต์

import re,itertools as t,ipaddress as k
R=range
i=input()
for d in R(5):
 for p in t.combinations(R(len(i)),d):
  n=i;o=0
  for a in p:n=n[:a+o]+'.'+n[a+o:];o+=1
  try:k.ip_address(n);print(n*(not re.search(r'\D?0\d',n)))
  except:0

ค่อนข้างง่าย: เราวางช่วงเวลาทุกที่และพิมพ์ถ้าที่อยู่ IP ที่มีช่วงเวลาถูกต้อง เราตรวจสอบความถูกต้องของที่อยู่ IP โดย (ab) โดยใช้ipaddress.ip_addressซึ่งจะเพิ่มข้อยกเว้นหากอินพุตไม่ใช่ที่อยู่ IP ที่ถูกต้อง ความท้าทายกำหนดกฎเพิ่มเติมบางอย่างที่ip_addressไม่ได้จัดการ (กล่าวคือไม่มีเลขศูนย์นำหน้า) ดังนั้นเราจึงตรวจสอบกฎเหล่านั้นด้วยนิพจน์ทั่วไปจากนั้นพิมพ์

เอาต์พุตแต่ละโซลูชันบนบรรทัดใหม่ผสมกับจำนวนบรรทัดว่างโดยพลการ

ตัวอย่างการเรียกใช้:

$ echo 012345 | python fixip.py
0.1.23.45
0.1.234.5
0.12.3.45
0.12.34.5
0.123.4.5





$ echo 000123 | python fixip.py
0.0.0.123








_

นี่เป็นโซลูชัน Python 2 รุ่นเก่าของฉันที่ 248 ไบต์ ระดับเยื้องที่สองและสามคือ\t(แท็บดิบ) และ\t (แท็บดิบพร้อมช่องว่าง) ตามลำดับ นี้เล่นจริงๆไม่ดีกับ Markdown เพื่อให้แท็บได้ถูกแทนที่ด้วยสองช่องว่าง

import socket,re,itertools as t
R=range
i=input()
for d in R(5):
 for p in t.combinations(R(len(i)),d):
  n=i;o=0
  for a in p:n=n[:a+o]+'.'+n[a+o:];o+=1
  try:
   socket.inet_aton(n)
   if n.count('.')==3and not re.search(r'\D?0\d',n):print n
  except:0

ต้องการอินพุตที่ล้อมรอบด้วยเครื่องหมายคำพูด (เช่น"123.456.789") ส่งออกแต่ละที่อยู่ IP ที่สร้างขึ้นในบรรทัดใหม่

บันทึกแล้ว 9 ไบต์ขอบคุณ @grawity!


1
จะipaddress.ip_address()สั้นกว่า aton + การตรวจสอบด้วยตนเองหรือไม่
grawity


2

Python 3, 262 260 bytes

p,l,L,T=set(),-1,len,tuple
while l<L(p):l=L(p);p|={T(z[:i]+(y[:j],y[j:])+z[i+1:])for z in set(p)or[T(input().split("."))]for i,y in enumerate(z)for j in range(1,L(y))}
print(['.'.join(x)for x in p if L(x)==4and all(y=='0'or y[0]!='0'and int(y)<256for y in x)])

ไม่มีห้องสมุดที่ใช้ แต่ล่าช้าและนานกว่านี้ฉันอาจจะขาดเทคนิคการตีกอล์ฟที่เห็นได้ชัด

ผลลัพธ์อยู่ดี

for x in 192.168.1234 192.1681234 1921681.234 1921681234 192.168.1204 192.168.123 192.168.256 120345 012345 000123; do
echo $x | python3 ipv4.py
done;

['192.168.123.4', '192.168.1.234', '192.168.12.34']
['192.16.81.234', '192.168.1.234', '192.168.123.4', '192.168.12.34']
['19.216.81.234', '192.168.1.234', '192.16.81.234']
['19.216.81.234', '192.168.123.4', '192.168.12.34', '192.16.81.234', '192.168.1.234']
['192.168.1.204', '192.168.120.4']
['192.16.8.123', '19.2.168.123', '1.92.168.123', '192.168.1.23', '192.168.12.3', '192.1.68.123']
['192.168.25.6', '192.168.2.56']
['1.20.3.45', '1.203.4.5', '12.0.34.5', '120.3.4.5', '1.20.34.5', '12.0.3.45']
['0.1.23.45', '0.12.3.45', '0.12.34.5', '0.123.4.5', '0.1.234.5']
['0.0.0.123']

1
ฉันคิดว่าฉันจะคัดลอกการทดสอบความถูกต้องของคุณและสงสัยว่าคุณต้องการวงเล็บorหรือไม่?
Neil

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