Para conmemorar el aniversario del día mundial de IPv6 , Internet Society ha publicado una campaña para desactivar IPv4 el 6 de junio de 2014 durante un día .
Las direcciones IPv6 pueden representarse en su forma larga como ocho valores hexadecimales de 16 bits separados por dos puntos. Dependiendo de la dirección, también se pueden acortar como se describe en el elemento 2 de la sección 2.2 Representación de texto de direcciones de RFC 3513 :
Para facilitar la escritura de direcciones que contengan cero bits, hay disponible una sintaxis especial para comprimir los ceros. El uso de "::" indica uno o más grupos de 16 bits de ceros. El "::" solo puede aparecer una vez en una dirección. El "::" también se puede utilizar para comprimir ceros iniciales o finales en una dirección.
Las entradas a este reto serán los programas que aceptan exactamente una dirección IPv6 formateado en el formato largo o acortada, y mostrarán la misma dirección en ambos formatos largos y cortos, en ese orden.
La entrada puede provenir de argumentos de línea de comandos, STDIN o cualquier otra fuente de entrada que se adapte a su elección de idioma.
Las bibliotecas o utilidades específicamente para analizar direcciones IPv6 están prohibidas (por ejemplo, inet_ {ntop, pton} () ).
Si la dirección de entrada no es válida, la salida estará vacía (o aparece un mensaje de error adecuado que indica que la dirección no es válida )
En los casos en que se
::
produce el acortamiento, solo puede ocurrir una operación de acortamiento para una dirección determinada. Si hay más de una posible operación de acortamiento para una dirección determinada, se debe utilizar la operación que proporciona la dirección más corta en general. Si hay un empate a este respecto, se utilizará la primera operación. Esto se ilustra en los ejemplos a continuación.
Ejemplos:
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>
Este es codegolf , por lo que la respuesta más corta en bytes del 6 de junio de 2014 será aceptada como ganadora.
fuente
1:0:0:2:2::3
. ¿La salida acortada sería idéntica a esa o1::2:2:0:0:3
? Lo mismo para la entrada no acortada de manera óptima.1::2:0:0:0:3
una entrada posible?Respuestas:
JavaScript (ES6):
198,183,180,188, 187 bytesY, un poco más, versión interactiva con algunas ventanas emergentes (203 bytes):
Sin golf:
Explicación:
Para calcular la versión larga de la dirección IPv6:
8 - str.split(/:+/).length % 9
- Calcule cuántos ceros necesitamos insertar. Son 8, el número de los valores hexadecimales. Aquí% 9 es un guardia, por lo que nunca será un número negativo.replace('::', ':0'.repeat(zeros || 1) + ':')
- reemplace el "::" con ceros separados por dos puntos. Si no hay ceros para agregar, todavía agrega uno, por lo que la dirección no será válida al finalreplace(/^:0|0:$/g, zeros ? '0:0' : '0')
- se trata del caso especial cuando la dirección comienza o termina con "::" ya que lasplit
función agrega 1 al número de valores hexadecimales (:: 1 -> ["", "1"])¡Eso es! Ahora calculemos la forma corta:
replace(/(\b0(:0)*)(?!.*\1:0)/,':')
- Reemplace la fila más larga de ceros con dos puntos (no importa cuántos).replace(/::+/,'::')
- eliminar los dos puntos adicionales si los hayreturn /^(:[\da-f]{1,4}){8}$/i.test(':'+longIP) && [longIP, shortIP];
- pruebe si la versión larga es IPv6 válida y devuelva ambas versiones ofalse
si la prueba falla.Pruebas en Firefox:
fuente
1:2:3:4::a:b:c:d
Javascript (E6)
246305284292319Caso especial muy revisado para :: manejado específicamente, la fase de compresión evita el bucle for (pero no muy corto)
Estoy seguro de que la fase de compresión final se puede acortar. No ahora de todos modosGracias a nderscore
Como un programa
Entrada y salida utilizando js popup, básicamente:
p=prompt,p(F(p()))
reescritura con popup y sin la definición de la función, el recuento de caracteres debe ser inferior a 260Ungolfed y comentó un poco
Prueba en consola
Prueba de salida
fuente
prompt()
. Aquí hay algunas optimizaciones que lo reducen a 290: pastie.org/private/3ccpinzqrvvliu9nkccygPerl - 204
176 190 191 197(202 caracteres + 2 para
-p
bandera)Ejemplo:
Explicación:
fuente
die
a una salida silenciosa.1:2:3:4::a:b:c:d
. Este es un caso especial molesto, porque la mayoría de las direcciones de ocho de colon no son válidos, pero::2:3:4:a:b:c:d
y1:2:3:4:a:b:c::
son ambos válidos.sed, 276
Tengo 275 bytes en ipshorten.sed, más 1 byte para que el
-r
switchsed -rf
use expresiones regulares extendidas. Usé OpenBSD sed (1) .Uso:
echo ::2:3:4:a:b:c:d | sed -rf ipshorten.sed
Utilizo 22 expresiones regulares, ya que sed no puede comparar números o hacer matrices. Para cada línea de entrada, sed ejecuta los comandos e imprime la línea. Durante las pruebas, puse varias líneas de supuestas direcciones IP en un archivo y alimente este archivo a sed. Una referencia a expresiones regulares extendidas está en re_format (7) .
s/^/:/
agrega dos puntos adicionales al comienzo de la línea. Utilizo este colon extra para jugar golf los siguientes dos comandos./^(:[0-9A-Fa-f]{0,4})*$/!d
comprueba si la línea completa coincide con cero o más grupos de dos puntos seguidos de cero a cuatro dígitos hexadecimales.!
niega el cheque, por lo qued
elimina líneas con números hexadecimales demasiado grandes o con caracteres no válidos. Cuandod
elimina una línea, sed no ejecuta más comandos en esta línea.s/:0*([^:])/:\1/g
elimina los ceros a la izquierda de cada número. Cambiaría:0000:0000:
a:0:0:
. Debo hacer esto porque mi ciclo de contracción solo funciona con ceros de un solo dígito.s/://
elimina el colon extra. Solo elimina el primer colon.s/::/:=/
cambia el primero::
a:=
. Esto es para que los comandos posteriores puedan coincidir en=
lugar de::
, y=
no cuentan como dos puntos. Si no hay::
, esta sustitución no hace nada con seguridad.::
debe hacer al menos un 0, pero hay tres casos diferentes para colocar este 0.s/(.:=)(.)/\10:\2/
Es el primer caso. Si::
estaba entre otros dos personajes, entonces se:=
convierte en:=0:
. Este es el único caso que agrega dos puntos.s/^:=/0&/
Es el segundo caso. Si::
estaba al comienzo de la línea, entonces ponga 0 allí.s/=$/&0/
es el tercer caso, para::
al final de la línea.:E
es la etiqueta para el bucle de expansión./(.*:){7}/!{/=/!d
comienza un bloque condicional si la línea tiene menos de 7 puntos./=/!d
elimina líneas que no tenían::
y no tenían suficientes dos puntos.s//=0:/
agrega un colon. Vacío//
repite la última expresión regular, así que esto es realmentes/=/=0:/
.bE
se ramifica para:E
continuar el ciclo.}
Cierra el bloque. Ahora la línea tiene al menos siete colones.s/=//
borra=
./^:|::|:$|(.*:){8}/d
Es un control final después de la expansión. Elimina líneas con un colon inicial, un extra::
que no se expandió, un colon posterior u ocho o más colonias.p
imprime la línea, que es una dirección IP en forma larga.s/.*/:&:/
envuelve la dirección en dos puntos adicionales.:0:0:0:
y contraerlo::
.s/:((0:)+)/:<\1>/g
come cada grupo de ceros, por:0:0:0:
lo que se convertiría:<0:0:0:>
.:C
es la etiqueta para el bucle de contracción.s/0:>/>0:/g
mueve un 0 de cada boca, por:<0:0:0:>
lo que se convertiría:<0:0:>0:
./<0/{s/<>//g
abre un bloque condicional si alguna boca no está vacía.s/<>//g
elimina todas las bocas vacías, porque esos grupos son demasiado cortos.bC
continúa el ciclo de contracción.}
Cierra el bloque. Ahora cualquier boca está vacía y marca el grupo más largo de ceros.s/<>(0:)+/:/
contrata al grupo más largo, por:<>0:0:0:
lo que se convertiría::
. En un empate, recoge la boca vacía a la izquierda.s/<>//g
elimina cualquier otra boca vacía./^::/!s/://
elimina el primer colon extra a menos que sea parte de::
./::$/!s/:$//
lo hace para el último colon extra. Luego sed imprime la dirección IP en forma corta.fuente
Python 3: 387 caracteres
Incluso funciona con entradas incorrectamente acortadas.
El reemplazo doble de
':::'
con se'::'
siente realmente mal, pero no estoy seguro de cómo lidiar limpiamente con la cadena más larga de 0 cuando se topa con uno o ambos extremos.Reemplace el final
pass
conraise
para ver cómo sebloquea laprotección contra entradas mal formadas.fuente
1:2:3:4::a:b:c:d
pero rechazó ambos::2:3:4:a:b:c:d
y1:2:3:4:a:b:c::
. Creo que estuvo mal las tres veces.