Dünya IPv6 günü 2014


22

Dünya IPv6 gününün yıldönümünü kutlamak için İnternet Derneği, 6 Haziran 2014'te Bir Gün için IPv4'ü Kapatmak için bir kampanya yayınladı .


IPv6 adresleri, uzun formlarında, sekiz adet kolon ile ayrılmış 16 bit hex değeri olarak gösterilebilir. Adrese bağlı olarak, 2.2 . RFC 3513 Adreslerinin Metin Temsili bölümündeki 2. maddede de açıklandığı gibi kısaltılabilirler :

Sıfır bit içeren adresleri yazmak kolaylaştırmak için sıfırları sıkıştırmak için özel bir sözdizimi mevcuttur. "::" kullanımı, 16 bit sıfırlık bir veya daha fazla grubu belirtir. "::" bir adreste yalnızca bir kez görünebilir. "::", bir adresteki baştaki veya sondaki sıfırları sıkıştırmak için de kullanılabilir.

  • Bu zorluğa girilen girişler, uzun veya kısaltılmış formatta formatlanmış bir IPv6 adresini tam olarak kabul eden ve aynı adresi hem uzun hem de kısa formatlarda bu sırayla gösterecek olan programlar olacaktır .

  • Giriş, komut satırı argümanlarından, STDIN'den veya dil seçiminize uyan başka bir giriş kaynağından gelebilir.

  • Özellikle IPv6 adreslerini ayrıştırmak için kullanılan kitaplıklar veya yardımcı programlar yasaklanmıştır (örneğin, inet_ {ntop, pton} () ).

  • Giriş adresi geçersizse, çıkış boş olacaktır (veya adresin geçersiz olduğunu belirten bazı uygun hata mesajları verilmiştir)

  • ::Kısaltmanın olduğu durumlarda , belirli bir adres için yalnızca bir kısaltma işlemi olabilir. Belirli bir adres için birden fazla potansiyel kısaltma işlemi varsa, en kısa adresi veren işlem kullanılmalıdır. Bu konuda bir bağ varsa, ilk işlem kullanılacaktır. Bu, aşağıdaki örneklerde gösterilmektedir.

  • Kaçınılması gereken standart boşluklar

Örnekler:

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>

Bu , bu nedenle 6 Haziran 2014'te byte olarak verilen en kısa cevap kazanan olarak kabul edilecektir.


Girişin dediğini söyle 1:0:0:2:2::3. Kısaltılmış çıktı bununla aynı 1::2:2:0:0:3mıdır yoksa ? Optimal olmayan kısaltılmış giriş için aynı.
Martin Ender

@ m.buettner Bu durumda, ikisini de seçmenize izin vereceğim.
Dijital Travma

1::2:0:0:0:3 olası girdi?
user12205


2
Sanırım bu, birinin bana ipv6'yı öğrenmemi sağlayacak tek yolu. +1
Sıkıntı

Yanıtlar:


4

JavaScript (ES6) - 198 , 183 , 180 , 188 , 187 bayt

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

Ve biraz daha uzun, bazı açılır pencerelerle etkileşimli sürüm (203 bayt):

/^(:[\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];
}

Açıklama:

IPv6 adresinin uzun versiyonunu hesaplamak için:

8 - str.split(/:+/).length % 9- kaç tane sıfır girmemiz gerektiğini hesapla. Bunlar 8 - onaltılık değerlerin sayısıdır. Burada% 9 bir bekçidir, dolayısıyla hiçbir zaman negatif bir sayı olmaz.

replace('::', ':0'.repeat(zeros || 1) + ':')- "::" 'yi iki nokta üst üste sıfırlarla değiştirin. Eklemek için hiç sıfır yoksa, yine de bir tane ekler, böylece adres sonunda geçerli olmaz

replace(/^:0|0:$/g, zeros ? '0:0' : '0') - adres, adres olarak "::" ile başladığında veya bittiğinde bu özel durumla ilgilidir. split fonksiyon, hex değerlerinin sayısına 1 eklerken (:: 1 -> ["", "1"])

Bu kadar! Şimdi kısa formu hesaplayalım:

replace(/(\b0(:0)*)(?!.*\1:0)/,':') - En uzun sıfır sırasını sütun (lar) ile değiştirin (Kaç tane olduğu önemli değil).

replace(/::+/,'::') - eğer varsa ekstra kolonları çıkarın

return /^(:[\da-f]{1,4}){8}$/i.test(':'+longIP) && [longIP, shortIP]; - Uzun versiyonun IPv6 geçerli olup olmadığını test edin ve her iki versiyonu da döndürün ya da false test başarısız olursa.

Firefox'taki Testler:

>>> 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

Benimkinden çok daha iyi! Sadece böyle girişi yapmak için bazı düzeltmelere ihtiyacımız var :: 1 :,: 1 ::
edc65

Bu geçersiz kabul etti1:2:3:4::a:b:c:d
kernigh

6

Javascript (E6) 246 305 284 292 319

Yoğun şekilde revize edildi Özel olarak işlenmiş :: için özel durum, sıkıştırma aşaması for döngüsünü önler (ancak çok kısa değil) Son sıkıştırma aşamasının daha kısa yapılabileceğinden eminim. Şimdi olmaz

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 için teşekkürler

Bir program olarak

Temelde js popup kullanarak giriş ve çıkış: p=prompt,p(F(p())) popup ve fonksiyon tanımlaması olmadan yeniden yazma, karakter sayımı 260 altında olmalıdır

Ungolfed ve biraz yorum yaptı

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 */
  ]
)

Konsolda test et

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

Test çıkışı

"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"   

Bir işlevden çok bir programı tercih ederim. Bu mümkün olup olmadığını bilmek yeterince javascript bilmiyorum.
Dijital Travma

@nderscore Hata, yazım hatası. Yeni bir yorumda düzeltildi.
Dijital Travma

Girdi alarak bir program haline getirilebilir prompt(). 290'a indirgeyen
nderscore

@nderscore: thx, 1. değiştirme input = '::' için çalışmıyor, yine de harika iş!
edc65

@ edc65 Bunun için bir düzeltme buldum :) pastie.org/private/kee0sdvjez0vfcmlvaxu8q
nderscore

4

Perl - 204 176 190 191 197

( -pBayrak için 202 karakter + 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/::::?/::/

Örnek:

$ 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

Açıklama:

# -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
"İpv6.pl 1. satırda öldü, <> 1. satırda" . Bu soru yorumlarında sorulmuştur. Bir mesaj varsa, bunun geçersiz bir mesaj olduğu anlaşılmalıdır. Bu soruyu açıklığa kavuşturmaya çalıştım. Aksi takdirde iyi görünüyor!
Dijital Travma

1
@DigitalTrauma dieSessiz bir çıkışa değiştirildi.
mniip

1
Bir böcek? Bu program geçersiz adresi kabul ediyor 1:2:3:4::a:b:c:d. En sekiz kolon adresleri geçersizdir, ancak, çünkü bu, sinir bozucu bir özel durumdur ::2:3:4:a:b:c:dve 1:2:3:4:a:b:c::hem geçerlidir.
kernigh

3

sed, 276

İpshorten.sed'de 275 baytım var, artı 1 bayt. -rsed -rfGenişletilmiş düzenli ifadeler kullanmak geçiş geçiş . OpenBSD sed (1) kullandım .

Kullanımı: 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 sayıları karşılaştıramaz veya dizileri yapamadığı için 22 normal ifade kullanıyorum. Her girdi satırı için sed komutları çalıştırır ve satırı yazdırır. Test sırasında, bir dosyaya birkaç satır IP adresi yazdım ve bu dosyayı baştan aşağı besledim. Genişletilmiş normal ifadelere bir referans re_format'tadır (7) .

  1. s/^/:/çizginin başına fazladan bir sütun ekler. Bu iki kolonu sonraki iki komutu atmak için kullanıyorum.
  2. /^(:[0-9A-Fa-f]{0,4})*$/!dTüm çizginin sıfır veya daha fazla kolon grubuyla eşleşip eşleşmediğini, ardından sıfır ila dört onaltılık basamak olup olmadığını kontrol eder. !çeki olumsuzlar, yanid geçersiz çok büyük onaltılık sayıları olan veya geçersiz karakterleri olan satırları siler. Bir dsatırı silerken, sed bu satırda daha fazla komut çalıştırmaz.
  3. s/:0*([^:])/:\1/gher numaradan baştaki 0'ları siler. Bu değiştirecek :0000:0000:kadar:0:0: . Bunu yapmalıyım çünkü büzülme döngüm sadece tek basamaklı 0'larla çalışıyor.
  4. s/://fazladan kolonu siler. Sadece ilk kolonu siler.
  5. s/::/:=/ilk ::olarak değişir :=. Bu çok daha sonra komutlar =yerine eşleşebilir ::ve= iki nokta olarak sayılmaz. Eğer yoksa:: , bu değişiklik güvenli bir şekilde hiçbir şey yapmaz.
    • Şimdi ::en az bir 0 yapmalı, ancak bu 0'ı yerleştirmek için üç farklı durum vardır.
  6. s/(.:=)(.)/\10:\2/ilk dava. ::Diğer iki karakter arasında olsaydı , o zaman :=olur:=0: . İki nokta üst üste ekleyen tek durum budur.
  7. s/^:=/0&/ikinci durum. Eğer:: hattın başlangıç oldu, sonra 0 oraya koydu.
  8. s/=$/&0/ üçüncü dava, çünkü :: satırın sonunda.
  9. :E genişleme döngüsünün etiketidir.
  10. /(.*:){7}/!{/=/!dSatırda 7 kolondan az varsa koşullu blok başlatılır. /=/!dolmayan satırları siler::yeterli olan ve yeterli .
  11. s//=0:/bir kolon ekler. Boş //, son normal ifadeyi tekrarlar, yani bu gerçektens/=/=0:/ .
  12. bE:Edöngü devam etmek için dallar .
  13. }bloğu kapatır. Şimdi çizginin en az yedi sütunu var.
  14. s/=//siler =.
  15. /^:|::|:$|(.*:){8}/dgenişlemeden sonra yapılan son kontroldür. Önde gelen bir kolon, ::genişlemeyen bir ekstra , izleyen bir kolon veya sekiz veya daha fazla sütun içeren satırları siler .
  16. p IP adresi olan satırı uzun biçimde yazdırır.
  17. s/.*/:&:/ adresi fazladan virgüllerle sarar.
    • Bir sonraki görev, en uzun 0 grubunu bulmak :0:0:0:ve onunla anlaşmak ::.
  18. s/:((0:)+)/:<\1>/g0'lı grupların her birini yer, böylece :0:0:0:olur :<0:0:0:>.
  19. :C büzülme döngüsünün etiketidir.
  20. s/0:>/>0:/gher ağzından bir 0 hareket eder, böylece :<0:0:0:>olur :<0:0:>0:.
  21. /<0/{s/<>//g Ağız boş değilse şartlı bir blok açar. s/<>//gtüm boş ağızları siler çünkü bu gruplar çok kısadır.
  22. bC büzülme döngüsüne devam eder.
  23. }bloğu kapatır. Artık herhangi bir ağız boş ve en uzun 0'lı gruplara işaret ediyor.
  24. s/<>(0:)+/:/En uzun gruba sözleşme yapar, böylece :<>0:0:0:olur ::. Bir bağda, boş ağzı soldan alır.
  25. s/<>//g diğer boş ağızları siler.
  26. /^::/!s/://parçası olmadıkça ilk fazla sütunu siler ::.
  27. /::$/!s/:$//Son ekstra kolon için öyle. Daha sonra sed, IP adresini kısa biçimde yazdırır.

1

Python 3: 387 karakter

Yanlış kısaltılmış girdiyle bile çalışır.

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

Double yerine ':::'birlikte '::'gerçekten kötü hissediyor ama emin 0 yılların en uzun dize ile temiz bir şekilde anlaşma bir veya iki ucunu bitiştiği nasıl zaman.

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

Finalini değiştirin passile raiseo nasıl görmek çökmesini hatalı biçimlendirilmiş girdi karşı koruma.

$ 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 düzeltildi. "0: 0: 0 ..." ı arıyordum ve 0'ı takip ediyordu
Nick T

Bugünlerde yeterince "abuts" kelimesini gerçekten duymuyorsunuz
Claudiu

Bir böcek? Bu program kabul 1:2:3:4::a:b:c:dama hem reddedilen ::2:3:4:a:b:c:dve 1:2:3:4:a:b:c::. Üç kere de yanlış olduğuna inanıyorum.
kernigh
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.