Korrigieren Sie die fehlenden Punkte meiner IPv4-Adresse

37

Wenn ich eine IPv4-Adresse eingebe, werden manchmal alle Zahlen richtig angezeigt, aber ich vergesse, einen oder mehrere Punkte einzugeben. Ich hätte gerne ein Programm (oder eine Funktion), das meine defekte IPv4-Adresse übernimmt und alle möglichen gültigen Platzierungen der fehlenden Zeiträume ausgibt.

Eingang

Die Eingabe ist immer eine Zeichenfolge, die eine Umwandlung einer gültigen IPv4-Adresse darstellt (siehe Einzelheiten unten). Es wird immer nur durch die Eliminierung eines oder mehrerer Punktzeichen transformiert worden sein.

Ihr Beitrag muss keine Eingaben außerhalb dieses Formats verarbeiten.

Ausgabe

Eine Sammlung oder Liste von Zeichenfolgen, die alle gültigen IPv4-Adressen darstellen, die aus der Eingabe erstellt werden können, indem Punkte in die Eingabe eingefügt werden.

  • Die Ausgabe kann eine Liste in der Sprache oder ein anderer geordneter oder ungeordneter Sammlungstyp sein.
  • Alternativ kann es sich um eine Zeichenfolge von IPv4-Adressen handeln, die auf eine eindeutige Weise abgegrenzt sind.
    • Wenn Sie einen Einzelzeichenbegrenzer zur Begrenzung Ihrer Zeichenfolge verwenden, sind Punkte und Ziffern als dieser Einzelzeichenbegrenzer nicht zulässig. Mir ist klar, dass Punkte als Begrenzer im Gegensatz zu Zahlen nicht mehrdeutig sind (da jeder vierte Punkt notwendigerweise ein Begrenzer sein müsste), aber der Lesbarkeit halber lehne ich dies ab.

IPv4-Adressformat

Während IPv4-Adressen eigentlich nur eine Folge von vier binären Oktetten sind, verwendet diese Herausforderung ein eingeschränktes Punkt-Dezimal-Format.

  • Eine IPv4-Adresse besteht aus vier Dezimalwerten, die durch drei Punkte getrennt sind.
  • Jeder der vier Werte liegt im Bereich 0bis 255einschließlich.
  • Führende Nullen sind in keinem Zahlenwert zulässig . (Standalone eines Zeichen 0erlaubt ist, jede andere Zahl mit einer Null beginnt , ist nicht: 052, 00, etc.)

Testfälle

Die Eingabe erfolgt in der ersten Zeile, die Ausgabe in der zweiten Zeile (hier als durch Kommas getrennte Liste von Zeichenfolgen in Anführungszeichen, die durch Kommas getrennt sind, umgeben von [ ], aber Sie können jedes sinnvolle Format oder jede sinnvolle Struktur wie oben angegeben verwenden). Einige Beispiele haben Anmerkungen in einer dritten Zeile, um die Anwendung einer bestimmten Regel hervorzuheben.

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

(Ich habe diese Beispiele von Hand angefertigt. Bitte benachrichtigen Sie mich über etwaige Fehler.)

Apsillers
quelle
Ausgabereihenfolge ist wichtig?
SIE
@YOU No: " Eine Sammlung oder Liste, in keiner bestimmten Reihenfolge oder Format ... "
Apsillers
Führende Nullen sind nicht erlaubt : Gilt das auch für die Eingabe?
Luis Mendo
3
Also ... "000125" sollte nur eine richtige Lösung zurückgeben ... 0.0.0.125?
Keeta
2
@Keeta Das ist genau richtig. (Ich habe es gerade als Testfall hinzugefügt.)
Apsillers

Antworten:

9

Pyth, 24 Bytes

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

Probieren Sie es online aus

Wie es funktioniert

                      ./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 Bytes, sehr langsam

@FjLL\.,^U256 4./

Warnung. Renne nicht. Benötigt ca. 553 GB RAM.

Wie es funktioniert

       ,             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
quelle
Nett! Nach meinem eigenen Verständnis bedeutet "alle Partitionen der Eingabe" alle möglichen Arten der Segmentierung der Eingabe, oder? Also machst du jede mögliche Trennung und fügst sie dann mit Punkten wieder zusammen, so dass du am Ende eine Menge Kandidaten wie 1.9.2.1.6.8.1.2und 19.2.1.6.8.1.2usw. hast ? (Aber dann werden offensichtlich alle ungültigen herausgefiltert)
Apsillers
@apsillers Richtig.
Anders Kaseorg
16

C (gcc / linux) 125 121 Bytes

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

Durchläuft alle möglichen IPv4-Adressen und führt einen benutzerdefinierten Vergleich durch, bei dem zusätzliche Punkte in der generierten IP-Adresse (jedoch nicht in der Hauptvergleichsadresse) übersprungen werden, um zu entscheiden, ob gedruckt werden soll oder nicht. Sehr langsam, sollte aber innerhalb von 1 Stunde auf einem vernünftigen PC fertig sein .

orlp
quelle
Sie können das entfernen i=0;.
Betseg
@ReleasingHeliumNuclei Ich dachte, ich könnte nicht (eine Funktion muss wiederverwendbar sein), aber jetzt i
merke
6

Perl 5, 91 Bytes

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

Das Programm erwartet eine einzelne Zeile einer einzelnen Eingabe und gibt eine durch Leerzeichen begrenzte Liste von Kandidaten aus.

Erläuterung

Das Programm nutzt die Rückverfolgungsfunktion von Regex, um alle Möglichkeiten der Bildung einer gültigen IPv4-Adresse aus der Eingabezeichenfolge zu durchlaufen.

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

Der IPv4-Regex mit optionalen ., hier nichts Besonderes .

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

Ein Code-Auswertungsausdruck, der den Inhalt der Erfassungsgruppen ausgibt.

^

Stellen Sie sicher, dass das Match fehlschlägt und erzwingen Sie das Backtracking.

Beispiellauf

$ 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̴̖̋ã̷͉h̷̭̿d̷̰̀ĥ̷̳
quelle
5

JavaScript (ES6), 147 141 135 Bytes

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

Bearbeiten: 6 Bytes dank @apsillers gespeichert. Durch Kopieren des Gültigkeitstests von @ YOU wurden weitere 6 Byte gespeichert.

Neil
quelle
Gibt es einen Unterschied zwischen [1-9] | 0 und [0-9] oder \ d ??
SIE
@apsillers Ah ja, eine frühere Version meines Codes könnte ein Trailing erzeugen, .das den Test auslösen würde, aber ich denke, diese Version ist OK.
Neil
@YOU Das Wichtige ist, dass das a 0hat $. (Es fehlt auch ein ^, also danke, dass du mich darauf aufmerksam gemacht
Neil,
@apsillers Funktioniert leider splicenicht so, es ändert das Array und gibt alle entfernten Elemente zurück.
Neil
4

Python 3, 232 Bytes

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

Ganz einfach: Wir setzen überall Punkte und drucken, ob die IP-Adresse mit den gesetzten Punkten gültig ist. Wir überprüfen die Gültigkeit der IP-Adressen mit (ab). Dies ipaddress.ip_addresslöst eine Ausnahme aus, wenn die Eingabe keine gültige IP-Adresse ist. Die Herausforderung definiert einige zusätzliche Regeln, ip_addressdie nicht behandelt werden (dh, dass es keine führenden Nullen geben kann). Wir überprüfen diese also auch mit einem regulären Ausdruck und drucken sie dann aus.

Gibt jede Lösung in einer neuen Zeile aus, gemischt mit einer beliebigen Anzahl von Leerzeilen.

Beispiellauf:

$ 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








_

Hier ist meine ältere 248-Byte-Python-2-Lösung. Die Ebenen für den zweiten und dritten Gedankenstrich sind \t(unformatierter Tabulator) bzw. \t (unformatierter Tabulator plus Leerzeichen). Dies spielt bei Markdown sehr schlecht, daher wurden die Tabulatoren durch zwei Leerzeichen ersetzt.

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

Erfordert die Eingabe in Anführungszeichen (zB "123.456.789"). Gibt jede generierte IP-Adresse in einer neuen Zeile aus.

9 Bytes gespart dank @grawity!

Kupfer
quelle
1
Wäre ipaddress.ip_address()kürzer als aton + manuelle Prüfung?
Grawity
3

Brachylog , 110 Bytes

: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.

Probieren Sie es online!

Undichte Nonne
quelle
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)])

Keine Bibliotheken benutzt, aber spät und länger, vielleicht fehlen mir einige offensichtliche Golftechniken.

Ergebnisse trotzdem.

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']
SIE
quelle
1
Ich dachte, ich würde Ihren Gültigkeitstest kopieren und fragte mich, ob Sie die Klammern um die orKlausel benötigen ?
Neil
@ Neil, danke, brauchte die nicht.
SIE