세계 IPv6의 날 2014


22

세계 IPv6 의 기념일을 기념하기 위해 인터넷 협회는 2014 년 6 월 6 일에 하루 동안 IPv4를 끄는 캠페인을 발표했습니다 .


IPv6 주소는 8 개의 콜론으로 구분 된 16 비트 16 진수 값으로 긴 형식으로 표시 될 수 있습니다. 주소에 따라 2.2 RFC 3513 주소텍스트 표현 섹션의 항목 2에 설명 된대로 단축 될 수도 있습니다 .

0 비트를 포함하는 주소를보다 쉽게 ​​작성하기 위해 0을 압축하는 특수 구문을 사용할 수 있습니다. "::"의 사용은 16 비트의 0으로 구성된 하나 이상의 그룹을 나타냅니다. "::"는 주소에 한 번만 나타날 수 있습니다. "::"을 사용하여 주소에서 선행 또는 후행 0을 압축 할 수도 있습니다.

  • 이 문제에 대한 항목 중 하나 긴 또는 단축 형식으로 포맷 정확히 하나의 IPv6 주소를 받아 프로그램이 될 것이며, 동일한 주소가 표시됩니다 모두 순서대로, 길고 짧은 형식을.

  • 입력은 명령 행 인수, STDIN 또는 선택한 언어에 적합한 기타 입력 소스에서 올 수 있습니다.

  • IPv6 주소를 구문 분석하기위한 라이브러리 또는 유틸리티는 금지되어 있습니다 (예 : inet_ {ntop, pton} () ).

  • 입력 주소가 유효하지 않은 경우 출력이 비어 있습니다 (또는 주소가 유효하지 않음을 나타내는 적절한 오류 메시지 가 표시됨)

  • 경우 ::단축이 발생, 하나의 단축는 지정된 주소를 발생할 수 있습니다. 주어진 주소에 대해 둘 이상의 잠재적 단축 작업이있는 경우 전체 가장 짧은 주소를 제공하는 작업을 사용해야합니다. 이와 관련하여 동점이 있으면 첫 번째 작업이 사용됩니다. 아래 예에 설명되어 있습니다.

  • 피해야 할 표준 허점

예 :

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>

이것은 이므로 2014 년 6 월 6 일에 가장 짧은 바이트 단위의 답변이 승자로 승인됩니다.


입력이라고 가정하십시오 1:0:0:2:2::3. 단축 된 출력이 그것과 같 1::2:2:0:0:3습니까? 최적화되지 않은 입력의 경우와 동일합니다.
마틴 엔더

@ m.buettner이 경우에는 어느 쪽이든 고를 수 있습니다.
Digital Trauma

1::2:0:0:0:3가능한 입력은?
user12205


2
나는 이것이 누군가가 ipv6을 배우게 할 유일한 방법이라고 생각합니다. +1
Obversity

답변:


4

자바 스크립트 (ES6) -198 , 183 , 180 , 188 , 187 바이트

f=s=>/^(:[\da-f]{1,4}){8}$/i.test(':'+(s=s[r='replace'](d='::',':0'.repeat((n=8-s.split(/:+/).length%9)||1)+':')[r](/^:0|0:$/g,n?'0:0':0)))&&[s,s[r](/(\b0(:0)*)(?!.*\1:0)/,d)[r](/::+/,d)]

그리고 일부 팝업 (203 바이트)이있는 조금 더 긴 대화 형 버전입니다.

/^(:[\da-f]{1,4}){8}$/i.test(':'+(s=(s=prompt())[r='replace'](d='::',':0'.repeat((n=8-s.split(/:+/).length%9)||1)+':')[r](/^:0|0:$/g,n?'0:0':0)))&&alert(s+'\n'+s[r](/(\b0(:0)*)(?!.*\1:0)/,d)[r](/::+/,d))

언 골프 드 :

function ipv6(str) {
    "use strict";
    var zeros = 8 - str.split(/:+/).length % 9

        ,longIP = str
            .replace('::', ':0'.repeat(zeros || 1) + ':')
            .replace(/^:0|0:$/g, zeros ? '0:0' : '0')

        ,shortIP = longIP
            .replace(/(\b0(:0)*)(?!.*\1:0)/,':')
            .replace(/::+/,'::');

    return /^(:[\da-f]{1,4}){8}$/i.test(':'+longIP) && [longIP, shortIP];
}

설명:

IPv6 주소의 긴 버전을 계산하려면 다음을 수행하십시오.

8 - str.split(/:+/).length % 9-삽입해야 할 제로 수를 계산하십시오. 그것들은 8-16 진수 값의 수입니다. 여기 % 9는 가드이므로 절대 음수가 아닙니다.

replace('::', ':0'.repeat(zeros || 1) + ':')- "::"을 콜론으로 구분 된 0으로 바꾸십시오. 추가 할 0이 없으면 여전히 1을 추가하여 주소가 결국 유효하지 않습니다.

replace(/^:0|0:$/g, zeros ? '0:0' : '0')- split함수가 16 진 값의 수에 1을 더할 때 주소가 "::"로 시작하거나 끝나는 특수한 경우를 다룹니다 (:: 1-> [ "", "1"]).

그게 다야! 이제 짧은 형식을 계산해 봅시다 :

replace(/(\b0(:0)*)(?!.*\1:0)/,':') -가장 긴 0의 행을 콜론으로 바꿉니다 (얼마나 많은지는 중요하지 않습니다).

replace(/::+/,'::') -여분의 콜론을 제거하십시오

return /^(:[\da-f]{1,4}){8}$/i.test(':'+longIP) && [longIP, shortIP];-긴 버전이 유효한 IPv6 false인지 테스트하고 두 버전을 모두 반환하거나 테스트에 실패한 경우

Firefox에서 테스트 :

>>> f('1080:0:0:0:8:800:200C:417A')
["1080:0:0:0:8:800:200C:417A", "1080::8:800:200C:417A"]
>>> f('FF01::101')
["FF01:0:0:0:0:0:0:101", "FF01::101"]
>>> f('0:0:0:0:0:0:0:1')
["0:0:0:0:0:0:0:1", "::1"]
>>> f('::')
["0:0:0:0:0:0:0:0", "::"]
>>> f('1:0:0:2:0:0:0:3')
["1:0:0:2:0:0:0:3", "1:0:0:2::3"]
>>> f('1:0:0:8:8:0:0:3')
["1:0:0:8:8:0:0:3", "1::8:8:0:0:3"]
>>> f('1:2:3:4:5:6:7:8')
["1:2:3:4:5:6:7:8", "1:2:3:4:5:6:7:8"]
>>> f('ABCD:1234')
false
>>> f('ABCDE::1234')
false
>>> f('1:2:3:4:5:6:7:8:9')
false
>>> f(':::1')
false
>>> f('1:2:3:4::a:b:c:d')
false
>>> f('codegolf puzzle')
false

내 것보다 훨씬 낫다! 그냥 :,이 :: 1과 같은 손잡이 입력에 약간의 수정이 필요합니다 : 1 ::
edc65

이것은 유효하지 않습니다1:2:3:4::a:b:c:d
kernigh

6

자바 스크립트 (E6) 246305288492319

크게 수정 : :: 특별히 처리 된 압축 단계는 for 루프를 피합니다 (그러나 실제로는 짧지는 않습니다) 최종 압축 단계를 짧게 할 수 있다고 확신합니다. 어쨌든 지금은 아닙니다

F=i=>(c=':',d=c+c,z=':0'.repeat(9-i.split(c,9).length)+c,i=i==d?0+z+0:i[R='replace'](/^::/,0+z)[R](/::$/,z+0)[R](d,z>c?z:d),/^(:[\da-f]{1,4}){8}:$/i.test(k=c+i+c)&&[i,k[R]((k.match(/:(0:)+/g)||[]).sort().pop(),d)[R](/^:([^:])|([^:]):$/g,'$1$2')])

nderscore 덕분에

프로그램으로

기본적으로 js 팝업을 사용하여 입력 및 출력 : p=prompt,p(F(p())) 작성 및 함수 정의없이 문자 수는 260 미만이어야합니다.

언 골프 하고 약간의 코멘트

F = i => (
  c = ':',
  d = c+c,
  z = ':0'.repeat(9-i.split(c,9).length) + c, 
  i = i == d ? 0+z+0 /* special case '::' */
    : i.replace(/^::/,0+z) /* special case '::...' */
       .replace(/::$/,z+0) /* special case '...::' */
       .replace(d, z > c ? z : d), /* here, if z==c, not valid: too much colons */
  /^(:[\da-f]{1,4}){8}:$/i.test(k = c+i+c) /* Check if valid */
  && [
   i, 
   k.replace((k.match(/:(0:)+/g)||[]).sort().pop(),d) /* find longest 0: sequence and replace it */
    .replace(/^:([^:])|([^:]):$/g,'$1$2') /* cut leading and trailing colons */
  ]
)

콘솔에서 테스트

i=['1080:0:0:0:8:800:200C:417A'
, '::1:2:3:4:5:6:7', '1:2:3:4:5:6:7::'
, '1:2:3:4::5:6:7:8'
, ':1:2:3:4:5:6:7', '1:2:3:4:5:6:7:'
, 'FF01::101', '0:0:0:0:0:0:0:1'
, '::', '1::', '::1', ':::1', '1:::'
, '1:0:0:2:0:0:0:3', '1:0:0:0:2:0:0:3', '1::8:0:0:0:3'
, '1:2:3:4:5:6:7:8'
, 'ABCD:1234', 'ABCDE::1234', ':::', '::::::::::'
, '1:2:3:4:5:6:7:8:9', '::::1', 'codegolf puzzle'];
i.map(x=>x+' => '+F(x)).join('\n')

테스트 출력

"1080:0:0:0:8:800:200C:417A => 1080:0:0:0:8:800:200C:417A,1080::8:800:200C:417A
::1:2:3:4:5:6:7 => 0:1:2:3:4:5:6:7,::1:2:3:4:5:6:7
1:2:3:4:5:6:7:: => 1:2:3:4:5:6:7:0,1:2:3:4:5:6:7::
1:2:3:4::5:6:7:8 => false
:1:2:3:4:5:6:7 => false
1:2:3:4:5:6:7: => false
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:: => 1:0:0:0:0:0:0:0,1::
::1 => 0:0:0:0:0:0:0:1,::1
:::1 => false
1::: => false
1:0:0:2:0:0:0:3 => 1:0:0:2:0:0:0:3,1:0:0:2::3
1:0:0:0:2:0:0:3 => 1:0:0:0:2:0:0:3,1::2:0:0:3
1::8:0:0:0:3 => 1:0:0:8:0:0:0:3,1:0:0:8::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 => false
ABCDE::1234 => false
::: => false
:::::::::: => false
1:2:3:4:5:6:7:8:9 => false
::::1 => false
codegolf puzzle => false"   

오히려 함수보다는 프로그램입니다. 이것이 가능한지 알 수있을만큼 자바 스크립트를 잘 모릅니다.
Digital Trauma

@nderscore 죄송합니다-오타. 새로운 의견 수정.
Digital Trauma

에서 입력을 받아 프로그램으로 만들 수 있습니다 prompt(). 다음은 290으로 낮추는 최적화입니다. pastie.org/private/3ccpinzqrvvliu9nkccyg
nderscore

@nderscore : thx, 첫 번째 교체는 input = '::'에 대해 작동하지 않습니다.
edc65

@ edc65 나는 그 대체에 대한 해결책을 찾았습니다 :) pastie.org/private/kee0sdvjez0vfcmlvaxu8q
nderscore

4

펄-204 -20417619019197

(202 자 + -p플래그는 2 )

$_=uc;(9-split/:/)||/^:|:$/||last;s/^::/0::/;s/::$/::0/;s|::|':0'x(9-split/:/).':'|e;/::|^:|:$|\w{5}|[^A-F0-:].*\n/||(8-split/:/)and last;s/\b0*(?!\b)//g;print;s/\b((0:)*0)\b(?!.*\1:0\b)/::/;s/::::?/::/

예:

$ perl -p ipv6.pl <<< 1:0:2:0::3
1:0:2:0:0:0:0:3
1:0:2::3
$ perl -p ipv6.pl <<< somethinginvalid
$ perl -p ipv6.pl <<< 1:2:0:4:0:6::8
1:2:0:4:0:6:0:8
1:2::4:0:6:0:8

설명:

# -p reads a line from stdin and stores in $_
#
# Convert to uppercase
$_ = uc;

# Detect the annoying case @kernigh pointed out
(9 - split /:/) || /^:|:$/ || last;

# Fix :: hanging on the beginning or the end of the string
s/^::/0::/;
s/::$/::0/;

# Replace :: with the appropriate number of 0 groups
s|::|':0' x (9 - split /:/) . ':'|e;

# Silently exit if found an extra ::, a hanging :, a 5-char group, an invalid
# character, or there's not 8 groups
/::|^:|:$|\w{5}|[^A-F0-:].*\n/ || (8 - split /:/) and last;

# Remove leading zeros from groups
s/\b0*(?!\b)//g;

# Output the ungolfed form
print;

# Find the longest sequence of 0 groups (a sequence not followed by something
# and a longer sequence) and replace with ::
# This doesn't replace the colons around the sequence because those are optional
# thus we are left with 4 or 3 colons in a row
s/\b((0:)*0)\b(?!.*\1:0\b)/::/;

# Fix the colons after previous transformation
s/::::?/::/

# -p then prints the golfed form of the address

1
"ipv6.pl line 1, <> line 1에서 사망했습니다 . " 이것은 질문 의견에서 질문되었습니다. 메시지가있는 경우 메시지가 유효하지 않기 때문에 명확해야합니다. 나는 질문에서 그것을 명확히하려고 노력했다. 그렇지 않으면 좋아 보인다!
Digital Trauma

1
@DigitalTrauma die자동 종료로 변경 되었습니다.
mniip

1
버그? 이 프로그램은 잘못된 주소를 허용합니다 1:2:3:4::a:b:c:d. 대부분의 여덟 대장 주소가 유효하지만, 때문에, 성가신 특별한 경우 ::2:3:4:a:b:c:d1:2:3:4:a:b:c::모두 유효합니다.
kernigh 2016 년

3

sed, 276

ipshorten.sed에 275 바이트가 있고 확장 정규식을 사용 하기 위해 -r스위치에 1 바이트 sed -rf가 있습니다. OpenBSD sed (1) 사용했습니다 .

용법: echo ::2:3:4:a:b:c:d | sed -rf ipshorten.sed

s/^/:/
/^(:[0-9A-Fa-f]{0,4})*$/!d
s/:0*([^:])/:\1/g
s/://
s/::/:=/
s/(.:=)(.)/\10:\2/
s/^:=/0&/
s/=$/&0/
:E
/(.*:){7}/!{/=/!d
s//=0:/
bE
}
s/=//
/^:|::|:$|(.*:){8}/d
p
s/.*/:&:/
s/:((0:)+)/:<\1>/g
:C
s/0:>/>0:/g
/<0/{s/<>//g
bC
}
s/<>(0:)+/:/
s/<>//g
/^::/!s/://
/::$/!s/:$//

sed는 숫자를 비교하거나 배열을 만들 수 없으므로 22 개의 정규 표현식을 사용합니다. 각 입력 행에 대해 sed는 명령을 실행하고 행을 인쇄합니다. 테스트하는 동안 여러 줄의 IP 주소를 파일에 넣고이 파일을 sed에 공급했습니다. 확장 정규 표현식에 대한 참조는 re_format (7)에 있습니다.

  1. s/^/:/줄의 시작 부분에 콜론을 추가합니다. 이 추가 콜론을 사용하여 다음 두 명령을 골라냅니다.
  2. /^(:[0-9A-Fa-f]{0,4})*$/!d전체 행이 0 개 이상의 콜론 그룹과 일치하고 0에서 4 개의 16 진 숫자와 일치하는지 확인합니다. !검사를 무효화하므로 d너무 큰 16 진수 또는 유효하지 않은 문자가있는 행을 삭제합니다. 때 d라인을 삭제, 실행이 라인에 더 이상 명령을 나오지.
  3. s/:0*([^:])/:\1/g각 숫자에서 선행 0을 삭제합니다. 로 변경 :0000:0000:됩니다 :0:0:. 수축 루프는 한 자리 0으로 만 작동하기 때문에이 작업을 수행해야합니다.
  4. s/://여분의 콜론을 삭제합니다. 첫 번째 콜론 만 삭제합니다.
  5. s/::/:=/첫 번째 ::를로 변경합니다 :=. 이것은 나중에 명령이 =아닌 일치 할 수 ::있으므로 =콜론으로 계산되지 않습니다. 이 없으면 ::이 대체는 안전하게 수행되지 않습니다.
    • 이제 ::적어도 하나의 0을 만들어야하지만이 0을 배치하는 세 가지 경우가 있습니다.
  6. s/(.:=)(.)/\10:\2/첫 번째 경우입니다. ::다른 두 문자 사이에 있으면 이 :=됩니다 :=0:. 콜론을 추가하는 유일한 경우입니다.
  7. s/^:=/0&/두 번째 경우입니다. ::줄의 시작 부분에 있었다면 0을 입력하십시오.
  8. s/=$/&0/::줄 끝의 세 번째 경우 입니다.
  9. :E 확장 루프의 레이블입니다.
  10. /(.*:){7}/!{/=/!d라인에 콜론이 7 개 미만인 경우 조건부 블록을 시작합니다. 콜론이없고 충분하지 않은 /=/!d행을 삭제합니다 ::.
  11. s//=0:/하나의 콜론을 추가합니다. Empty //는 마지막 정규 표현식을 반복하므로 실제로는 s/=/=0:/입니다.
  12. bE:E루프를 계속 하기 위해 분기합니다 .
  13. }블록을 닫습니다. 이제 줄에 7 개 이상의 콜론이 있습니다.
  14. s/=//삭제 =합니다.
  15. /^:|::|:$|(.*:){8}/d확장 후 최종 점검입니다. 선행 콜론, ::확장되지 않은 추가 콜론, 후행 콜론 또는 8 개 이상의 콜론 이있는 행을 삭제합니다 .
  16. p 긴 형식의 IP 주소 인 행을 인쇄합니다.
  17. s/.*/:&:/ 추가 콜론으로 주소를 줄 바꿈합니다.
    • 다음 작업은와 같이 가장 긴 0 그룹을 찾아서 :0:0:0:계약하는 것 ::입니다.
  18. s/:((0:)+)/:<\1>/g먹는다 0의 각 그룹은, 그렇게 :0:0:0:될 것입니다 :<0:0:0:>.
  19. :C 수축 루프의 레이블입니다.
  20. s/0:>/>0:/g각각의 입에서 하나의 공을 이동, 그렇게 :<0:0:0:>될 것입니다 :<0:0:>0:.
  21. /<0/{s/<>//g입이 비어 있지 않으면 조건부 블록을 엽니 다. s/<>//g그룹이 너무 짧기 때문에 모든 빈 입을 삭제합니다.
  22. bC 수축 루프를 계속합니다.
  23. }블록을 닫습니다. 이제 모든 입이 비어 있으며 가장 긴 그룹 인 0입니다.
  24. s/<>(0:)+/:/가장 긴 그룹이 계약, 그렇게 :<>0:0:0:될 것입니다 ::. 넥타이로 왼쪽의 빈 입을 선택합니다.
  25. s/<>//g 다른 빈 입을 삭제합니다.
  26. /^::/!s/://의 일부가 아닌 경우 첫 번째 추가 콜론을 삭제합니다 ::.
  27. /::$/!s/:$//마지막 추가 콜론에 대해서도 마찬가지입니다. 그런 다음 sed는 IP 주소를 짧은 형식으로 인쇄합니다.

1

파이썬 3 : 387 자

입력이 잘못 단축 된 경우에도 작동합니다.

$ echo '1::2:0:0:0:3' | python3 ipv6.py 
1:0:0:2:0:0:0:3
1:0:0:2::3

':::'with 의 double replace '::'는 실제로 나쁜 느낌이 들지만 한쪽 또는 양쪽 끝에 접할 때 가장 긴 0의 문자열을 깨끗하게 처리하는 방법을 잘 모릅니다.

c=':'
p=print
try:
 B=[int(x,16)if x else''for x in input().split(c)];L=len(B)
 if any(B)-1:B=[''];L=1
 if L!=8:s=B.index('');B[s:s+1]=[0]*(9-L)
 for b in B:assert-1<b<2**16
 H=[format(x,'X')for x in B];o=c.join(H);p(o);n=''.join(str(h=='0')[0]for h in H)
 for i in range(8,0,-1):
  s=n.find('T'*i)
  if s>=0:H[s:s+i]=[c*2];p(c.join(H).replace(c*3,c*2).replace(c*3,c*2));q
 p(o)
except:0

마지막 교체 passraise는 어떻게 볼 수 있도록 충돌 잘못된 입력에 대한 보호를.

$ cat ipv6-test.sh 
echo '1080:0:0:0:8:800:200C:417A' | python3 ipv6.py
echo '1:2:3:4:5:6:7:8' | python3 ipv6.py
echo 'FF01::101' | python3 ipv6.py
echo '0:0:0:0:0:0:0:1' | python3 ipv6.py
echo '0:0:0:0:1:0:0:0' | python3 ipv6.py
echo '1:0:0:0:0:0:0:0' | python3 ipv6.py
echo '::' | python3 ipv6.py
echo '1:0:0:2:0:0:0:3' | python3 ipv6.py
echo '1::2:0:0:0:3' | python3 ipv6.py
echo '1:0:0:8:8:0:0:3' | python3 ipv6.py
echo 'ABCD:1234' | python3 ipv6.py
echo 'ABCDE::1234' | python3 ipv6.py
echo '1:2:3:4:5:6:7:8:9' | python3 ipv6.py
echo ':::1' | python3 ipv6.py
echo 'codegolf puzzle' | python3 ipv6.py
$ ./ipv6-test.sh 
1080:0:0:0:8:800:200C:417A
1080::8:800:200C:417A

1:2:3:4:5:6:7:8
1:2:3:4:5:6:7:8

FF01:0:0:0:0:0:0:101
FF01::101

0:0:0:0:0:0:0:1
::1

0:0:0:0:1:0:0:0
::1:0:0:0

1:0:0:0:0:0:0:0
1::


0:0:0:0:0:0:0:0
::

1:0:0:2:0:0:0:3
1:0:0:2::3

1:0:0:2:0:0:0:3
1:0:0:2::3

1:0:0:8:8:0:0:3
1::8:8:0:0:3

@DigitalTrauma가 수정되었습니다. "0 : 0 : 0 ..."을 (를) 검색하고 후행 0을 캡처하고있었습니다.
Nick T

당신은 요즘 "충분한"단어를 듣지 못합니다
Claudiu

버그? 이 프로그램 1:2:3:4::a:b:c:d::2:3:4:a:b:c:d및을 (를) 수락 했지만 거부했습니다 1:2:3:4:a:b:c::. 나는 그것이 세 번 모두 잘못되었다고 생각합니다.
kernigh 2016 년
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.