Zum Jahrestag des Welt-IPv6-Tages hat die Internet Society am 6. Juni 2014 eine Kampagne zum einmaligen Deaktivieren von IPv4 veröffentlicht .
IPv6-Adressen können in ihrer langen Form als acht durch Doppelpunkte getrennte 16-Bit-Hexadezimalwerte dargestellt werden. Abhängig von der Adresse können sie auch wie in Punkt 2 von Abschnitt 2.2 Textdarstellung von Adressen von RFC 3513 beschrieben gekürzt werden :
Um das Schreiben von Adressen mit Null-Bits zu vereinfachen, steht eine spezielle Syntax zum Komprimieren der Nullen zur Verfügung. Die Verwendung von "::" gibt eine oder mehrere Gruppen von 16 Bit Nullen an. Das "::" darf in einer Adresse nur einmal vorkommen. Das "::" kann auch verwendet werden, um führende oder nachfolgende Nullen in einer Adresse zu komprimieren.
Beiträge zu dieser Herausforderung sind Programme, die genau eine IPv6-Adresse akzeptieren, die entweder im langen oder im verkürzten Format formatiert ist, und die die gleiche Adresse sowohl im langen als auch im kurzen Format in dieser Reihenfolge anzeigen .
Die Eingabe kann von Befehlszeilenargumenten, STDIN oder einer anderen Eingabequelle stammen, die für Ihre Sprachauswahl geeignet ist.
Bibliotheken oder Dienstprogramme speziell zum Parsen von IPv6-Adressen sind gesperrt (z. B. inet_ {ntop, pton} () ).
Wenn die Eingabeadresse ungültig ist, ist die Ausgabe leer (oder es wird eine geeignete Fehlermeldung ausgegeben, die angibt, dass die Adresse ungültig ist).
In Fällen, in denen eine
::
Verkürzung auftritt, kann für eine bestimmte Adresse nur eine Verkürzungsoperation ausgeführt werden. Wenn es für eine Adresse mehr als eine mögliche Kürzungsoperation gibt, muss die Operation verwendet werden, die die insgesamt kürzeste Adresse angibt. Wenn diesbezüglich ein Gleichstand besteht, wird die erste Operation verwendet. Dies wird in den folgenden Beispielen veranschaulicht.
Beispiele:
Input Output
1080:0:0:0:8:800:200C:417A 1080:0:0:0:8:800:200C:417A
1080::8:800:200C:417A
FF01::101 FF01:0:0:0:0:0:0:101
FF01::101
0:0:0:0:0:0:0:1 0:0:0:0:0:0:0:1
::1
:: 0:0:0:0:0:0:0:0
::
1:0:0:2:0:0:0:3 1:0:0:2:0:0:0:3
1:0:0:2::3
1:0:0:8:8:0:0:3 1:0:0:8:8:0:0:3
1::8:8:0:0:3
1:2:3:4:5:6:7:8 1:2:3:4:5:6:7:8
1:2:3:4:5:6:7:8
ABCD:1234 <Invalid address format - no output>
ABCDE::1234 <Invalid address format - no output>
1:2:3:4:5:6:7:8:9 <Invalid address format - no output>
:::1 <Invalid address format - no output>
codegolf puzzle <Invalid address format - no output>
Dies ist Codegolf , daher wird die kürzeste Antwort in Bytes am 6. Juni 2014 als Gewinner akzeptiert.
quelle
1:0:0:2:2::3
. Wäre die verkürzte Ausgabe identisch mit der oder1::2:2:0:0:3
? Gleiches gilt für nicht optimal verkürzte Eingaben.1::2:0:0:0:3
eine Eingabe möglich?Antworten:
JavaScript (ES6) -
198,183,180,188, 187 ByteUnd eine etwas längere, interaktive Version mit einigen Popups (203 Bytes):
Ungolfed:
Erläuterung:
So berechnen Sie die lange Version der IPv6-Adresse:
8 - str.split(/:+/).length % 9
- berechnen Sie, wie viele Nullen wir einfügen müssen. Sie sind 8 - die Anzahl der Hex-Werte. Hier ist% 9 eine Wache, daher wird es niemals eine negative Zahl sein.replace('::', ':0'.repeat(zeros || 1) + ':')
- Ersetzen Sie das "::" durch durch Doppelpunkte getrennte Nullen. Wenn keine Nullen hinzugefügt werden müssen, wird immer noch eine hinzugefügt, sodass die Adresse am Ende nicht gültig istreplace(/^:0|0:$/g, zeros ? '0:0' : '0')
- Dies behandelt den Sonderfall, wenn die Adresse mit "::" beginnt oder endet, da diesplit
Funktion die Anzahl der Hex-Werte um 1 erhöht (:: 1 -> ["", "1"]).Das ist es! Nun berechnen wir die Kurzform:
replace(/(\b0(:0)*)(?!.*\1:0)/,':')
- Ersetzen Sie die längste Nullenreihe durch Doppelpunkte (egal wie viele).replace(/::+/,'::')
- Entfernen Sie gegebenenfalls die zusätzlichen Doppelpunktereturn /^(:[\da-f]{1,4}){8}$/i.test(':'+longIP) && [longIP, shortIP];
- Testen Sie, ob die lange Version IPv6-gültig ist, und geben Sie beide Versionen zurück, oderfalse
wenn der Test fehlschlägt.Tests in Firefox:
quelle
1:2:3:4::a:b:c:d
Javascript (E6) 246
305 284 292 319Stark überarbeiteter Spezialfall für :: speziell behandelte, komprimierte Phase vermeidet die for-Schleife (aber nicht sehr kürzer)
Ich bin sicher, dass die endgültige komprimierte Phase kürzer gemacht werden kann. Jedenfalls jetzt nichtDanke an nderscore
Als ein Programm
Ein- und Ausgabe über js Popup, grundsätzlich: Beim
p=prompt,p(F(p()))
Umschreiben mit Popup und ohne Funktionsdefinition sollte die Zeichenanzahl unter 260 liegenUngolfed und kommentierte ein bisschen
In Konsole testen
Ausgang testen
quelle
prompt()
. Hier sind einige Optimierungen, die es auf 290 bringen: pastie.org/private/3ccpinzqrvvliu9nkccygPerl - 204
176 190 191 197(202 Zeichen + 2 für
-p
Flagge)Beispiel:
Erläuterung:
quelle
die
einen stillen Ausgang geändert .1:2:3:4::a:b:c:d
. Dies ist ein ärgerlicher Sonderfall, weil die meisten von acht Doppelpunkt - Adressen ungültig sind, aber::2:3:4:a:b:c:d
und1:2:3:4:a:b:c::
sind beide gültig.sed, 276
Ich habe 275 Bytes in ipshorten.sed, plus 1 Byte für die
-r
Umschaltungsed -rf
auf erweiterte reguläre Ausdrücke. Ich habe OpenBSD sed (1) benutzt .Verwendung:
echo ::2:3:4:a:b:c:d | sed -rf ipshorten.sed
Ich benutze 22 reguläre Ausdrücke, da sed keine Zahlen vergleichen oder Arrays erstellen kann. Sed führt für jede Eingabezeile die Befehle aus und gibt die Zeile aus. Während des Tests habe ich mehrere Zeilen angeblicher IP-Adressen in eine Datei geschrieben und diese Datei an sed weitergeleitet. Ein Verweis auf erweiterte reguläre Ausdrücke befindet sich in re_format (7) .
s/^/:/
Fügt am Zeilenanfang einen zusätzlichen Doppelpunkt ein. Ich benutze diesen zusätzlichen Doppelpunkt, um die nächsten zwei Befehle zu spielen./^(:[0-9A-Fa-f]{0,4})*$/!d
prüft, ob die gesamte Zeile mit null oder mehr Doppelpunktgruppen übereinstimmt, gefolgt von null bis vier hexadezimalen Ziffern.!
negiert die Prüfung,d
löscht also Zeilen mit zu großen Hexadezimalzahlen oder mit ungültigen Zeichen. Wennd
eine Zeile gelöscht wird, führt sed in dieser Zeile keine Befehle mehr aus.s/:0*([^:])/:\1/g
löscht führende Nullen von jeder Zahl. Es würde sich ändern:0000:0000:
zu:0:0:
. Ich muss das tun, weil meine Kontraktionsschleife nur mit einstelligen Nullen funktioniert.s/://
löscht den zusätzlichen Doppelpunkt. Es wird nur der erste Doppelpunkt gelöscht.s/::/:=/
ändert die erste::
zu:=
. Dies ist so, dass spätere Befehle=
eher übereinstimmen können als::
und daher=
nicht als Doppelpunkt gelten. Wenn dies nicht der::
Fall ist , führt diese Substitution sicher zu nichts.::
muss mindestens eine 0 gemacht werden, aber es gibt drei verschiedene Fälle, um diese 0 zu platzieren.s/(.:=)(.)/\10:\2/
ist der erste Fall. Wenn::
zwischen zwei anderen Zeichen war,:=
wird:=0:
. Dies ist der einzige Fall, in dem ein Doppelpunkt hinzugefügt wird.s/^:=/0&/
ist der zweite Fall. Wenn::
sich am Zeilenanfang befand, geben Sie dort 0 ein.s/=$/&0/
ist der dritte Fall für::
am Ende der Zeile.:E
ist die Bezeichnung für die Erweiterungsschleife./(.*:){7}/!{/=/!d
Beginnt ein Bedingungsblock, wenn die Zeile weniger als 7 Doppelpunkte enthält./=/!d
löscht Zeilen, die keine::
oder nicht genügend Doppelpunkte enthalten.s//=0:/
fügt einen Doppelpunkt hinzu. Empty//
wiederholt den letzten regulären Ausdruck, das ist also wirklich sos/=/=0:/
.bE
verzweigt nach:E
, um die Schleife fortzusetzen.}
schließt den Block. Jetzt hat die Linie mindestens sieben Doppelpunkte.s/=//
löscht=
./^:|::|:$|(.*:){8}/d
ist eine letzte Prüfung nach der Erweiterung. Es löscht Zeilen mit einem führenden Doppelpunkt, einem::
nicht erweiterten, einem nachgestellten Doppelpunkt oder acht oder mehr Doppelpunkten.p
Gibt die Zeile aus, die eine lange IP-Adresse ist.s/.*/:&:/
schließt die Adresse in zusätzliche Doppelpunkte ein.:0:0:0:
und sie zusammenzuziehen::
.s/:((0:)+)/:<\1>/g
isst jede Gruppe von 0en,:0:0:0:
würde also werden:<0:0:0:>
.:C
ist die Bezeichnung für die Kontraktionsschleife.s/0:>/>0:/g
Bewegt sich eine 0 aus jedem Mund, so:<0:0:0:>
würde es werden:<0:0:>0:
./<0/{s/<>//g
öffnet einen bedingten Block, wenn ein Mund nicht leer ist.s/<>//g
löscht alle leeren Münder, weil diese Gruppen zu kurz sind.bC
setzt die Kontraktionsschleife fort.}
schließt den Block. Jetzt ist jeder Mund leer und markiert die längste Gruppe von Nullen.s/<>(0:)+/:/
Verträge die längste Gruppe, so:<>0:0:0:
würde werden::
. Bei einem Unentschieden nimmt es den leeren Mund auf der linken Seite.s/<>//g
löscht alle anderen leeren Münder./^::/!s/://
löscht den ersten zusätzlichen Doppelpunkt, sofern er nicht Teil von ist::
./::$/!s/:$//
tut dies für den letzten zusätzlichen Doppelpunkt. Anschließend druckt sed die IP-Adresse in Kurzform.quelle
Python 3: 387 Zeichen
Funktioniert auch mit falsch verkürzten Eingaben.
Das doppelte Ersetzen von
':::'
mit'::'
fühlt sich wirklich schlecht an, ist sich aber nicht sicher, wie man sauber mit der längsten Zeichenfolge von Nullen umgeht, wenn sie an einem oder beiden Enden anliegt.Ersetzen Sie das Finale
pass
durch, umraise
zu sehen, wie es beim Schutz vor fehlerhaften Eingabenabstürzt.quelle
1:2:3:4::a:b:c:d
sowohl::2:3:4:a:b:c:d
als auch akzeptiert, aber abgelehnt1:2:3:4:a:b:c::
. Ich glaube, es war alle drei Male falsch.