โลก IPv6 วัน 2014


22

เพื่อทำเครื่องหมายครบรอบของวัน IPv6 โลกสังคมอินเทอร์เน็ตมีการเผยแพร่แคมเปญไปปิด IPv4 วันที่ 6 มิถุนายน 2014 วันหนึ่ง


ที่อยู่ IPv6 อาจแสดงในรูปแบบที่ยาวของพวกเขาเป็นค่าเลขฐานสิบหก 16 บิตที่คั่นด้วยโคลอน ขึ้นอยู่กับที่อยู่พวกเขาอาจย่อให้สั้นตามที่อธิบายไว้ในรายการที่ 2 ของส่วนที่ 2.2 การแสดงข้อความของที่อยู่ RFC 3513 :

เพื่อให้การเขียนที่อยู่ที่มีศูนย์บิตง่ายขึ้นจะมีไวยากรณ์พิเศษให้บีบอัดศูนย์ การใช้ "::" บ่งชี้หนึ่งหรือมากกว่าหนึ่งกลุ่มของศูนย์ 16 บิต "::" สามารถปรากฏได้เพียงครั้งเดียวเท่านั้นในที่อยู่ "::" ยังสามารถใช้ในการบีบอัดนำหน้าหรือต่อท้ายศูนย์ในที่อยู่

  • รายการที่ท้าทายนี้จะเป็นโปรแกรมที่ยอมรับที่อยู่ IPv6 หนึ่งที่จัดรูปแบบทั้งในรูปแบบยาวหรือสั้นและจะแสดงที่อยู่เดียวกันทั้งในรูปแบบยาวและสั้นตามลำดับนั้น

  • อินพุตอาจมาจากอาร์กิวเมนต์บรรทัดคำสั่ง STDIN หรือแหล่งอินพุตอื่น ๆ ที่เหมาะสมกับภาษาที่คุณเลือก

  • ไลบรารี่หรือยูทิลิตี้เฉพาะสำหรับการแยกที่อยู่ IPv6 ถูกแบน (เช่นinet_ {ntop, pton} () )

  • หากที่อยู่อินพุตไม่ถูกต้องผลลัพธ์จะว่างเปล่า (หรือข้อความแสดงข้อผิดพลาดที่เหมาะสมที่ระบุว่าที่อยู่ไม่ถูกต้อง )

  • ในกรณีที่::เกิดการตัดทอนการตัดทอนอาจเกิดขึ้นเพียงครั้งเดียวสำหรับที่อยู่ที่ระบุ หากมีการดำเนินการ shortening ที่เป็นไปได้มากกว่าหนึ่งรายการสำหรับที่อยู่ที่ระบุจะต้องใช้การดำเนินการที่ให้ที่อยู่ที่สั้นที่สุดโดยรวม หากมีการเสมอกันในเรื่องนี้การดำเนินการครั้งแรกจะถูกใช้ นี่คือตัวอย่างในตัวอย่างด้านล่าง

  • ช่องโหว่มาตรฐานที่ควรหลีกเลี่ยง

ตัวอย่าง:

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>

นี่คือดังนั้นคำตอบที่สั้นที่สุดเป็นไบต์ในวันที่ 6 มิถุนายน 2014 จะได้รับการยอมรับในฐานะผู้ชนะ


1:0:0:2:2::3บอกว่าใส่เป็น ผลลัพธ์ที่สั้นลงจะเหมือนกันหรือ1::2:2:0:0:3ไม่? เหมือนกันกับอินพุตที่สั้นลงที่ไม่เหมาะสม
Martin Ender

@ m.buettner ในกรณีนี้ฉันจะให้คุณเลือกอย่างใดอย่างหนึ่ง
Digital Trauma

คือ1::2:0:0:0:3การป้อนข้อมูลไปได้หรือไม่
user12205

@ace สอดคล้องกับหลักการความแข็งแกร่งที่แข็งแกร่งของJon Postelใช่
Digital Trauma

2
ฉันคิดว่านี่เป็นวิธีเดียวที่ทุกคนจะได้รับให้ฉันเรียนรู้ ipv6 +1
Obversity

คำตอบ:


4

JavaScript (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))

Ungolfed:

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 - จำนวนของค่าฐานสิบหก ที่นี่% 9 เป็นยามดังนั้นมันจะไม่เป็นจำนวนลบ

replace('::', ':0'.repeat(zeros || 1) + ':')- แทนที่ "::" ด้วยค่าศูนย์คั่นด้วยโคลอน หากไม่มีศูนย์ที่จะเพิ่มมันยังคงเพิ่มอีกหนึ่งศูนย์เพื่อที่อยู่จะไม่ถูกต้องในท้ายที่สุด

replace(/^:0|0:$/g, zeros ? '0:0' : '0')- ข้อตกลงนี้มีตัวพิมพ์พิเศษเมื่อที่อยู่เริ่มต้นหรือลงท้ายด้วย "::" เนื่องจากsplitฟังก์ชันจะเพิ่ม 1 เป็นจำนวนค่าเลขฐานสิบหก (:: 1 -> ["", "1"])

แค่นั้นแหละ! ทีนี้ลองคำนวณรูปแบบย่อ:

replace(/(\b0(:0)*)(?!.*\1: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

Javascript (E6) 246 305 284 292 319

กรณีพิเศษที่ได้รับการแก้ไขอย่างหนักสำหรับ :: จัดการโดยเฉพาะขั้นตอนการบีบอัดหลีกเลี่ยงการวนรอบ (แต่ไม่สั้นมากจริง ๆ ) ฉันแน่ใจว่าขั้นตอนการบีบอัดขั้นสุดท้ายสามารถทำให้สั้นลงได้ ไม่ใช่ตอนนี้

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')])

ขอบคุณที่ขีดล่าง

เป็นโปรแกรม

อินพุตและเอาต์พุตโดยใช้ js ป๊อปอัพโดยทั่วไป: p=prompt,p(F(p())) การเขียนใหม่ด้วยป๊อปอัพและไม่มีคำจำกัดความของฟังก์ชันจำนวนถ่านควรต่ำกว่า 260

Ungolfed และแสดงความคิดเห็นเล็กน้อย

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: ขอบคุณการแทนที่ครั้งที่ 1 ไม่สามารถใช้งานได้กับอินพุต = '::' แต่ก็เยี่ยมมาก!
edc65

@ edc65 ฉันพบการแก้ไขสำหรับแทนที่ :) pastie.org/private/kee0sdvjez0vfcmlvaxu8q
nderscore

4

Perl - 204 176 190 191 197

(202 ตัวอักษร + 2 สำหรับ-pธง)

$_=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 1 <> บรรทัดที่ 1" สิ่งนี้ถูกถามเกี่ยวกับในความคิดเห็นของคำถาม หากมีข้อความจะต้องชัดเจนว่าเป็นเพราะข้อความที่ไม่ถูกต้อง ฉันพยายามชี้แจงว่าในคำถาม มิฉะนั้นดูดี!
Digital Trauma

1
@DigitalTrauma เปลี่ยนdieเป็นทางออกเงียบ
mniip

1
แมลง? 1:2:3:4::a:b:c:dโปรแกรมนี้ยอมรับอยู่ไม่ถูกต้อง นี่เป็นกรณีพิเศษที่น่ารำคาญเพราะที่อยู่แปดโคลอนส่วนใหญ่ไม่ถูกต้อง แต่::2:3:4:a:b:c:dและ1:2:3:4:a:b:c::ทั้งคู่นั้นใช้ได้
kernigh

3

sed, 276

ฉันมี 275 ไบต์ใน ipshorten.sed บวก 1 ไบต์สำหรับ-rสวิตช์ใน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/:$//

ฉันใช้นิพจน์ทั่วไป 22 นิพจน์เนื่องจากไม่สามารถเปรียบเทียบตัวเลขหรือสร้างอาร์เรย์ได้ สำหรับแต่ละบรรทัดอินพุต sed เรียกใช้คำสั่งและพิมพ์บรรทัด ในระหว่างการทดสอบฉันใส่ที่อยู่ IP ที่ถูกกล่าวหาหลายบรรทัดไว้ในไฟล์และป้อนไฟล์นี้ให้เรียบร้อย อ้างอิงถึงการแสดงออกปกติขยายอยู่ในre_format (7)

  1. s/^/:/เพิ่มเครื่องหมายโคลอนพิเศษให้กับจุดเริ่มต้นของบรรทัด ฉันใช้ลำไส้ใหญ่พิเศษนี้เพื่อเล่นกอล์ฟสองคำสั่งถัดไป
  2. /^(:[0-9A-Fa-f]{0,4})*$/!dตรวจสอบว่าทั้งบรรทัดตรงกับศูนย์ของกลุ่มโคลอนหรือมากกว่าตามด้วยศูนย์เลขฐานสิบหกถึงสี่หลัก !ปฏิเสธการตรวจสอบดังนั้นdลบบรรทัดที่มีเลขฐานสิบหกที่ใหญ่เกินไปหรืออักขระที่ไม่ถูกต้อง เมื่อdลบบรรทัด sed จะไม่เรียกใช้คำสั่งเพิ่มเติมในบรรทัดนี้
  3. s/:0*([^:])/:\1/gลบ 0s นำหน้าจากแต่ละหมายเลข มันจะเปลี่ยนไป: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:/เพิ่มหนึ่งโคลอน ที่ว่างเปล่า//จะทำซ้ำการแสดงออกปกติล่าสุดดังนั้นนี่คือจริงs/=/=0:/
  12. bEสาขาเพื่อ:Eดำเนินการต่อห่วง
  13. }ปิดบล็อก ตอนนี้สายมีโคลอนอย่างน้อยเจ็ด
  14. s/=//=ลบ
  15. /^:|::|:$|(.*:){8}/dเป็นการตรวจสอบครั้งสุดท้ายหลังจากการขยาย มันจะลบเส้นที่มีโคลอนนำหน้าซึ่งเป็นส่วนเสริม::ที่ไม่ได้ขยายโคลอนต่อท้ายหรือโคลอนแปดตัวขึ้นไป
  16. p พิมพ์บรรทัดซึ่งเป็นที่อยู่ IP ในรูปแบบยาว
  17. s/.*/:&:/ ล้อมที่อยู่ในเครื่องหมายโคลอนพิเศษ
    • งานต่อไปคือการหากลุ่มที่ยาวที่สุดของ 0s เช่นและหดตัวลงใน:0:0:0:::
  18. s/:((0:)+)/:<\1>/gกินแต่ละกลุ่ม 0s ดังนั้นก็จะกลายเป็น:0:0:0::<0:0:0:>
  19. :C เป็นฉลากสำหรับห่วงการหดตัว
  20. s/0:>/>0:/gย้ายหนึ่ง 0 จากแต่ละปากจึงจะกลายเป็น:<0:0:0:>:<0:0:>0:
  21. /<0/{s/<>//gเปิดบล็อกที่มีเงื่อนไขหากปากไม่ว่างเปล่า s/<>//gลบปากที่ว่างเปล่าทั้งหมดเนื่องจากกลุ่มเหล่านั้นสั้นเกินไป
  22. bC ยังคงหดวง
  23. }ปิดบล็อก ตอนนี้ปากใดว่างเปล่าและทำเครื่องหมายกลุ่มที่ยาวที่สุดของ 0s
  24. s/<>(0:)+/:/สัญญากลุ่มที่ยาวที่สุดเพื่อที่จะกลายเป็น:<>0:0:0: ::ในเน็คไทมันจะเลือกปากที่ว่างเปล่าทางด้านซ้าย
  25. s/<>//g ลบปากที่ว่างเปล่าอื่น ๆ
  26. /^::/!s/://::ลบลำไส้ใหญ่พิเศษครั้งแรกเว้นแต่จะเป็นส่วนหนึ่งของ
  27. /::$/!s/:$//ทำเช่นนั้นสำหรับลำไส้ใหญ่ส่วนสุดท้ายพิเศษ จากนั้นพิมพ์ที่อยู่ IP ในรูปแบบย่อ

1

Python 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

การแทนที่แบบสองครั้ง':::'ด้วย'::'ความรู้สึกไม่ดีจริง ๆ แต่ไม่แน่ใจว่าจะจัดการกับสายอักขระที่ยาวที่สุดของ 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

แทนที่ขั้นสุดท้ายpassด้วยraiseเพื่อดูว่าการทำงานล้มเหลวป้องกันการป้อนข้อมูลที่ผิดรูปแบบอย่างไร

$ 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

คุณไม่ได้ยินคำว่า "abuts" เพียงพอทุกวันนี้
Claudiu

แมลง? โปรแกรมนี้ได้รับการยอมรับ1:2:3:4::a:b:c:dแต่ถูกปฏิเสธทั้งสองและ::2:3:4:a:b:c:d 1:2:3:4:a:b:c::ฉันเชื่อว่ามันผิดทั้งสามครั้ง
kernigh
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.