Para marcar o aniversário do dia mundial do IPv6 , a Internet Society publicou uma campanha para desativar o IPv4 em 6 de junho de 2014 por um dia .
Os endereços IPv6 podem ser representados em sua forma longa como oito valores hexadecimais de 16 bits separados por dois pontos. Dependendo do endereço, eles também podem ser reduzidos, conforme descrito no item 2 da seção 2.2 Representação de texto dos endereços da RFC 3513 :
Para facilitar a escrita de endereços contendo zero bits, está disponível uma sintaxe especial para compactar os zeros. O uso de "::" indica um ou mais grupos de 16 bits de zeros. O "::" pode aparecer apenas uma vez em um endereço. O "::" também pode ser usado para compactar zeros à esquerda ou à direita em um endereço.
As entradas para esse desafio serão os programas que aceitarem exatamente um endereço IPv6 formatado no formato longo ou abreviado e exibirão o mesmo endereço nos formatos longo e curto, nessa ordem.
A entrada pode vir de argumentos de linha de comando, STDIN ou qualquer outra fonte de entrada que seja adequada à sua escolha de idioma.
Bibliotecas ou utilitários especificamente para analisar endereços IPv6 são proibidos (por exemplo, inet_ {ntop, pton} () ).
Se o endereço de entrada for inválido, a saída estará vazia (ou será exibida alguma mensagem de erro adequada indicando que o endereço é inválido )
Nos casos em que
::
ocorre encurtamento, apenas uma operação de encurtamento pode ocorrer para um determinado endereço. Se houver mais de uma potencial operação de encurtamento para um determinado endereço, a operação que fornecer o endereço mais curto geral deverá ser usada. Se houver um empate a esse respeito, a primeira operação será usada. Isso é ilustrado nos exemplos abaixo.
Exemplos:
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>
Como é um codegolf , a resposta mais curta em bytes em 6 de junho de 2014 será aceita como vencedor.
fonte
1:0:0:2:2::3
. A saída reduzida seria idêntica a isso ou1::2:2:0:0:3
? O mesmo para entradas encurtadas de maneira não ideal.1::2:0:0:0:3
uma entrada possível?Respostas:
JavaScript (ES6) -
198,183,180,188, 187 bytesE, versão interativa um pouco mais longa, com alguns pop-ups (203 bytes):
Ungolfed:
Explicação:
Para calcular a versão longa do endereço IPv6:
8 - str.split(/:+/).length % 9
- calcule quantos zeros precisamos inserir. Eles são 8 - o número dos valores hexadecimais. Aqui% 9 é um protetor, portanto nunca será um número negativo.replace('::', ':0'.repeat(zeros || 1) + ':')
- substitua o "::" por zeros separados por dois pontos. Se não houver zeros a serem adicionados, ele ainda será adicionado, para que o endereço não seja válido no finalreplace(/^:0|0:$/g, zeros ? '0:0' : '0')
- trata do caso especial quando o endereço começa ou termina com "::", pois asplit
função adiciona 1 ao número de valores hexadecimais (:: 1 -> ["", "1"])É isso aí! Agora vamos calcular o formato abreviado:
replace(/(\b0(:0)*)(?!.*\1:0)/,':')
- substitua a linha mais longa de zeros por dois pontos (não importa quantos).replace(/::+/,'::')
- remova os dois pontos extras, se houverreturn /^(:[\da-f]{1,4}){8}$/i.test(':'+longIP) && [longIP, shortIP];
- teste se a versão longa é IPv6 válida e retorne ambas as versões oufalse
se o teste falhar.Testes no Firefox:
fonte
1:2:3:4::a:b:c:d
Javascript (E6)
246305284292319Revisado com muita atenção Caso especial para :: fase de compressão especificamente manipulada evita o loop for (mas não muito mais curto)
. Tenho certeza de que a fase final de compressão pode ser reduzida. Agora não de qualquer maneiraGraças a nderscore
Como um programa
Entrada e saída usando js pop-up, basicamente:
p=prompt,p(F(p()))
Reescrevendo com pop-up e sem a definição da função, a contagem de caracteres deve estar abaixo de 260Ungolfed e comentou um pouco
Console de teste
Saída de teste
fonte
prompt()
. Aqui estão algumas otimizações que o reduzem a 290: pastie.org/private/3ccpinzqrvvliu9nkccygPerl - 204
176 190 191 197(202 caracteres + 2 para
-p
sinalizador)Exemplo:
Explicação:
fonte
die
para uma saída silenciosa.1:2:3:4::a:b:c:d
. Este é um caso especial irritante, porque a maioria dos endereços de dois pontos é inválida, mas::2:3:4:a:b:c:d
e1:2:3:4:a:b:c::
são ambos válidos.sed, 276
Eu tenho 275 bytes em ipshorten.sed, mais 1 byte para o
-r
switchsed -rf
usar expressões regulares estendidas. Eu usei o OpenBSD sed (1) .Uso:
echo ::2:3:4:a:b:c:d | sed -rf ipshorten.sed
Eu uso 22 expressões regulares, pois o sed não pode comparar números ou criar matrizes. Para cada linha de entrada, sed executa os comandos e imprime a linha. Durante o teste, coloquei várias linhas de supostos endereços IP em um arquivo e alimentei esse arquivo para sed. Uma referência a expressões regulares estendidas está em re_format (7) .
s/^/:/
adiciona dois pontos extras ao início da linha. Eu uso esse cólon extra para jogar golfe nos próximos dois comandos./^(:[0-9A-Fa-f]{0,4})*$/!d
verifica se a linha inteira corresponde a zero ou mais grupos de dois pontos seguidos por zero a quatro dígitos hexadecimais.!
nega a verificação ed
exclui linhas com números hexadecimais muito grandes ou com caracteres inválidos. Quandod
exclui uma linha, sed não executa mais comandos nessa linha.s/:0*([^:])/:\1/g
exclui 0s iniciais de cada número. Mudaria:0000:0000:
para:0:0:
. Eu devo fazer isso porque meu loop de contração funciona apenas com 0s de um dígito.s/://
exclui os dois pontos extras. Exclui apenas o primeiro dois pontos.s/::/:=/
muda o primeiro::
para:=
. Isso ocorre para que os comandos posteriores possam corresponder=
e não::
e, portanto=
, não contam como dois pontos. Se não houver::
, essa substituição com segurança não fará nada.::
deve fazer pelo menos um 0, mas há três casos diferentes para colocar esse 0.s/(.:=)(.)/\10:\2/
é o primeiro caso. Se::
estava entre dois outros caracteres,:=
torna - se:=0:
. Este é o único caso que adiciona dois pontos.s/^:=/0&/
é o segundo caso. Se::
estava no início da linha, coloque 0 lá.s/=$/&0/
é o terceiro caso, para::
no final da linha.:E
é o rótulo para o loop de expansão./(.*:){7}/!{/=/!d
inicia um bloco condicional se a linha tiver menos de 7 pontos./=/!d
exclui linhas que não tinham::
e não eram dois pontos suficientes.s//=0:/
adiciona um cólon. Vazio//
repete a última expressão regular, então é isso mesmos/=/=0:/
.bE
ramifica para:E
continuar o loop.}
fecha o bloco. Agora a linha tem pelo menos sete dois pontos.s/=//
exclui=
./^:|::|:$|(.*:){8}/d
é uma verificação final após a expansão. Exclui linhas com dois pontos principais, um extra::
que não foi expandido, dois pontos à direita ou oito ou mais dois pontos.p
imprime a linha, que é um endereço IP em formato longo.s/.*/:&:/
quebra o endereço em dois pontos extras.:0:0:0:
, e contratá-lo::
.s/:((0:)+)/:<\1>/g
come cada grupo de 0s, assim:0:0:0:
se tornaria:<0:0:0:>
.:C
é o rótulo do loop de contração.s/0:>/>0:/g
move um 0 de cada boca, assim:<0:0:0:>
se tornaria:<0:0:>0:
./<0/{s/<>//g
abre um bloqueio condicional se alguma boca não estiver vazia.s/<>//g
exclui todas as bocas vazias, porque esses grupos são muito curtos.bC
continua o ciclo de contração.}
fecha o bloco. Agora qualquer boca está vazia e marca o grupo mais longo de 0s.s/<>(0:)+/:/
contrai o grupo mais longo, por isso:<>0:0:0:
se tornaria::
. Em um empate, ele pega a boca vazia à esquerda.s/<>//g
exclui outras bocas vazias./^::/!s/://
exclui o primeiro dois pontos extras, a menos que faça parte::
./::$/!s/:$//
faz isso pelo último cólon extra. Então sed imprime o endereço IP em formato abreviado.fonte
Python 3: 387 caracteres
Funciona até com entradas encurtadas incorretamente.
A substituição dupla de
':::'
com'::'
parece muito ruim, mas não tenho certeza de como lidar corretamente com a seqüência mais longa de 0s quando ela se limita a uma ou ambas as extremidades.Substitua a final
pass
porraise
para ver como ela estátravando,protegendo contra entradas malformadas.fonte
1:2:3:4::a:b:c:d
mas rejeitou ambos::2:3:4:a:b:c:d
e1:2:3:4:a:b:c::
. Eu acredito que estava errado nas três vezes.