Napraw brakujące okresy mojego adresu IPv4

37

Czasami, gdy wpisuję adres IPv4, wszystkie liczby są prawidłowe, ale zapominam o wpisaniu jednego lub więcej kropek. Chciałbym mieć program (lub funkcję), który pobiera mój uszkodzony adres IPv4 i wyświetla wszystkie możliwe prawidłowe miejsca brakujących kropek.

Wkład

Dane wejściowe zawsze będą ciągiem będącym transformacją prawidłowego adresu IPv4 (patrz szczegółowe informacje poniżej). Zawsze będzie transformowany wyłącznie przez wyeliminowanie jednego lub więcej znaków z okresu.

Przesłanie nie wymaga obsługi danych wejściowych poza tym formatem.

Wydajność

Zbiór lub lista ciągów reprezentujących wszystkie prawidłowe adresy IPv4, które nie mogą być tworzone w określonym porządku ani formacie, które można utworzyć z danych wejściowych poprzez wstawienie do nich znaków kropki.

  • Dane wyjściowe mogą być listą natywną dla języka lub innym uporządkowanym lub nieuporządkowanym typem kolekcji.
  • Alternatywnie może to być ciąg znaków adresu IPv4 ograniczony w jakiś wyraźny sposób.
    • Jeśli używasz separatora jednoznakowego do rozgraniczenia łańcucha, kropki i cyfry nie są dozwolone jako separator jednoznakowy. Zdaję sobie sprawę, że w przeciwieństwie do liczb, kropki jako separatory nie są niejednoznaczne (ponieważ co czwarty kropka koniecznie byłby separatorem), ale ze względu na czytelność, nie pozwalam na to.

Format adresu IPv4

Chociaż adresy IPv4 są tak naprawdę tylko sekwencją czterech binarnych oktetów, w tym wyzwaniu zastosowano ograniczony format dziesiętny z kropkami.

  • Adres IPv4 to cztery wartości dziesiętne oddzielone trzema kropkami.
  • Każdy z czterech wartości mieszczą się w przedziale 0do 255włącznie.
  • Zera wiodące nie są dozwolone w żadnej wartości liczbowej. (Standalone jedna postać 0jest dozwolona; każda inna liczba zaczynając od zera nie jest: 052, 00, itd.)

Przypadki testowe

Dane wejściowe znajdują się w pierwszym wierszu, dane wyjściowe w drugim wierszu (tutaj mają strukturę rozdzieloną przecinkami listy ciągów cytowanych, oddzielonych przecinkami, otoczoną przez [ ], ale można użyć dowolnego rozsądnego formatu lub struktury, jak określono powyżej). Niektóre przykłady zawierają uwagi w trzecim wierszu w celu podkreślenia zastosowania określonej reguły.

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"]

(Te przykłady zrobiłem ręcznie, więc proszę powiadamiaj mnie o wszelkich znalezionych błędach).

apsillery
źródło
kolejność produkcji ma znaczenie?
TY
@YOU No: „ Zbiór lub lista, bez określonej kolejności lub formatu ...
apsillers,
Zera wiodące są niedozwolone : czy dotyczy to również danych wejściowych?
Luis Mendo,
3
Więc .... „000125” powinien zwrócić tylko jedno poprawne rozwiązanie ... 0.0.0.125?
Keeta
2
@Keeta To jest dokładnie poprawne. (Właśnie dodałem to jako przypadek testowy.)
apsillers,

Odpowiedzi:

9

Pyth, 24 bajty

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

Wypróbuj online

Jak to działa

                      ./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 bajtów, bardzo wolno

@FjLL\.,^U256 4./

Ostrzeżenie. Nie biegać. Wymaga około 553 GiB pamięci RAM.

Jak to działa

       ,             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
Anders Kaseorg
źródło
Miły! Dla własnego zrozumienia „wszystkie partycje danych wejściowych” oznaczają wszystkie możliwe sposoby segmentacji danych wejściowych, prawda? Więc dołożyć wszelkich możliwych podziału, a następnie wrócić do rozłamów z okresów, więc możesz skończyć z mnóstwem kandydatów jak 1.9.2.1.6.8.1.2i 19.2.1.6.8.1.2itp? (Ale wtedy oczywiście wszystkie nieprawidłowe są odfiltrowywane)
apsillers
@apsillers Prawidłowe.
Anders Kaseorg,
16

C (gcc / linux), 125 121 bajtów

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

Zapętla wszystkie możliwe adresy IPv4 i dokonuje niestandardowego porównania, które pomija dodatkowe kropki w wygenerowanym adresie IP (ale nie w głównym adresie porównania), aby zdecydować, czy wydrukować, czy nie. Bardzo wolno, ale powinien zakończyć się w ciągu 1 godziny na rozsądnym komputerze .

orlp
źródło
Możesz usunąć i=0;.
betseg
@ReleasingHeliumNuclei Myślałem, że nie mogę (funkcja musi nadawać się do ponownego użycia), ale teraz zdaję sobie sprawę, że po tej funkcji iznów jest 0 ...
orlp
6

Perl 5, 91 bajtów

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

Program oczekuje pojedynczego wiersza jednego wejścia i wyświetla listę kandydatów rozdzielaną spacjami.

Wyjaśnienie

Program wykorzystuje funkcję cofania wyrażenia regularnego w celu zapętlenia wszystkich możliwości utworzenia prawidłowego adresu IPv4 z ciągu wejściowego.

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

Wyrażenie regularne IPv4 z opcjonalnym ., nic tu nie warte uwagi.

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

Wyrażenie oceny kodu, które drukuje zawartość grup przechwytujących.

^

Spraw, aby mecz się nie powiódł i wymuś powrót.

Przykładowy przebieg

$ 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
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨d̷̰̀ĥ̷̳
źródło
5

JavaScript (ES6), 147 141 135 bajtów

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

Edycja: zapisano 6 bajtów dzięki @apsillers. Zaoszczędzono kolejne 6 bajtów, kopiując test poprawności @ YOU.

Neil
źródło
czy istnieje różnica między [1-9] | 0 a [0-9] lub \ d ??
TY
@apsillers Ach tak, wcześniejsza wersja mojego kodu mogła generować końcowe, .które rzuciłyby test, ale myślę, że ta wersja jest OK.
Neil,
@YOU Ważne jest to, że 0ma $. (Brakuje również ^, więc dziękuję za zwrócenie na to uwagi.)
Neil
@apsillers Niestety splicetak nie działa, modyfikuje tablicę i zwraca wszelkie usunięte elementy.
Neil,
4

Python 3, 232 bajty

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

Całkiem proste: umieszczamy kropki wszędzie i drukujemy, jeśli adres IP z umieszczonymi kropkami jest prawidłowy. Sprawdzamy ważność adresów IP za pomocą (ab) ipaddress.ip_address, co powoduje wyjątek, jeśli dane wejściowe nie są prawidłowym adresem IP. Wyzwanie określa pewne dodatkowe reguły, które ip_addressnie są obsługiwane (a mianowicie, że nie mogą być zerami wiodącymi), więc sprawdzamy je również za pomocą wyrażeń regularnych, a następnie drukujemy.

Wysyła każde rozwiązanie do nowej linii, zmieszanej z dowolną liczbą pustych linii.

Przykładowy przebieg:

$ 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








_

Oto moje starsze 248-bajtowe rozwiązanie Python 2. Poziomy tiret drugie i trzecie to odpowiednio \t(tabulator surowy) i \t (tabulator raw plus spacja). Gra Markdown działa bardzo źle, więc karty zostały zastąpione dwoma spacjami.

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

Wymaga wprowadzania otoczonego cudzysłowami (np "123.456.789".). Wysyła każdy wygenerowany adres IP w nowej linii.

Zaoszczędź 9 bajtów dzięki @grawity!

Miedź
źródło
1
Czy ipaddress.ip_address()będzie krótszy niż aton + sprawdzenie ręczne?
grawity
3

Brachylog , 110 bajtów

:ef:{".",@N.|.}ac:3f:{@n:"."rz:cacb.}a.
,4yeN,?:N:6i.@nMl4,M:{:7&<256}a
~c[A:B]h:@N:Bc.
:ef:{,"0":"9"y:.m?}ac.

Wypróbuj online!

Leaky Nun
źródło
2

Python 3, 262 260 bajtów

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)])

Żadnych bibliotek, ale późno i dłużej, być może brakuje mi oczywistych technik gry w golfa.

Wyniki mimo wszystko.

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']
TY
źródło
1
Myślałem, że skopiuję test ważności i zastanawiałem się, czy potrzebujesz nawiasów wokół orklauzuli?
Neil,
@Neil, dzięki, nie potrzebowałem ich.
TY