Belirli bir aralıkta kaç IP adresi var?


31

Esinlenerek ...

Ağ Oluşturma - Belirli bir aralıkta kaç IP adresi olduğunu nasıl bulabilirim?

Her biri standart noktalı gösterimde ifade edilen bir IPv4 adresi olan ve iki IP adresi girişi de dahil olmak üzere bu aralığın kapsadığı IP adreslerinin sayısını veren veya veren iki dizgiyi giriş olarak alan bir program veya işlev yazın.

  • Bir IP adresini ayrıştırmak için tasarlanmış herhangi bir harici kod, kitaplık veya hizmet kullanmamalısınız. (Diğer dize işleme standart kütüphane işlevleri kabul edilebilir.)
  • Tüm 2 ^ 32 IP adresleri eşittir. Yayın, sınıf E, vb. Arasında hiçbir ayrım yapılmamıştır.
  • Normal kod-golf kuralları geçerlidir.

Örneğin:

"0.0.0.0","255.255.255.255" returns 4294967296.
"255.255.255.255","0.0.0.0" also returns 4294967296.
"1.2.3.4","1.2.3.4" returns 1.
"56.57.58.59","60.61.62.63" returns 67372037.
"1","2" is invalid input. Your code may do anything you like.

Bu soruyu programcılar üzerinde gördüm ve kod golf lol hakkında soru sormayı düşünüyordum.
Cruncher

3
Bunun standartlara göre hangi IP adreslerinin imkansız olduğuna dair bir StackOverflow sorusu olduğunu düşündüm.
Ming-Tang

8
IPv4 biraz geçmez mi?
ugoren

Yanıtlar:


20

GolfScript, 20 bayt

~]7/${2%256base}/)\-

Çevrimiçi deneyin.

Test durumları

$ echo 0.0.0.0 255.255.255.255 | golfscript range.gs
4294967296
$ echo 255.255.255.255 0.0.0.0 | golfscript test.gs
4294967296
$ echo 1.2.3.4 1.2.3.4 | golfscript test.gs
1
$ echo 56.57.58.59 60.61.62.63 | golfscript test.gs
67372037

Nasıl çalışır

~]        # Evaluate and collect into an array.
          #
          # “.” duplicates, so for "5.6.7.8 1.2.3.4", this leaves
          # [ 5 5 6 6 7 7 8 1 1 2 2 3 3 4 ] on the stack.
          #
7/        # Split into chunks of length 7: [ [ 5 5 6 6 7 7 8 ] [ 1 1 2 2 3 3 4 ] ]
$         # Sort the array of arrays: [ [ 1 1 2 2 3 3 4 ] [ 5 5 6 6 7 7 8 ] ]
{         # For each array:
  2%      # Extract every second element. Example: [ 1 2 3 4 ]
  256base # Convert the IP into an integer by considering it a base 256 number.
}/        #
)         # Add 1 to the second integer.
\-        # Swap and subtract. Since the integers were sorted, the result is positive.

Çok güzel ve hoş kullanımdan $kaçının abs.
Chris Jester-Young,

4
~]Ayrıca gerçekten zeki.
primo

10

Python 2 - 106

Burada görün .

def a():x=map(int,raw_input().split("."));return x[0]*2**24+x[1]*2**16+x[2]*2**8+x[3]
print abs(a()-a())+1

Örnek Giriş

0.0.0.0
0.0.0.255

Örnek çıktı

256


1
def a():return reduce(lambda c,d:c*256+d,map(int,raw_input().split(".")))çok daha kısa
Michael M.

5
@Michael Öneri için teşekkürler. Birkaç dakika kullandım, sonra baktım ve "Bunun% 90'ını yazmadım" demiştim. bu yüzden geri aldım.
Rainbolt

@Michael a=lambda:yerine def a():return 6 karakter kaydeder
avall

@Rusher 107 değil, 106
avall

1
@avall: Son LF'yi saydığınızı varsayıyorum.
Dennis,

8

CJam - 15

{r'./256b}2*-z)

Http://cjam.aditsu.net/ adresinde deneyin

Teşekkürler Dennis, vay, kendi dilimden en iyi şekilde nasıl yararlanabileceğimi bilmiyorum: p


Sen ortadan kaldırarak iki bayt kaydedebilirsiniz :i( bkullanarak ve bir tam sayıya döküm görünüyor) {r...}2*yerineqS/{...}/
Dennis

6

Saf bash, 66 bayt

p()(printf %02x ${1//./ })
r=$[0x`p $1`-0x`p $2`]
echo $[1+${r/-}]

Notlar:

  • Bir fonksiyon tanımlar pNoktalı bir ondalık IP adresi geçiren ve bu adresin onaltılık gösterimini veren :
    • ${1//./ }yerini alan bir parametre genişlemesi .ile IP adresini geçirilenp()
    • printfÇoğunlukla kendi kendini açıklayıcı. Sadece bir format belirteci %02xve kalan dört argüman olduğu için, format belirteci kalan her bir argüman için tekrar kullanılır ve 4 oktetin her birinin 2 onaltılık basamağını etkin bir şekilde birleştirir.
  • $[]aritmetik genişlemeye neden olur. Temel bir çıkarma yaparız ve değişkene atarız.r
  • ${r/-}olası bir -karakteri kaldırmak için bir parametre genişletme
  • Menzili vermek için 1 + mutlak farkı gösterin.

Çıktı:

$ ./iprangesize.sh 0.0.0.0 255.255.255.255
4294967296
$ ./iprangesize.sh 255.255.255.255 0.0.0.0
4294967296
$ ./iprangesize.sh 1.2.3.4 1.2.3.4
1
$ ./iprangesize.sh 56.57.58.59 60.61.62.63
67372037
$ ./iprangesize.sh 1 2
2
$ 

Ben algılamak printfve echo. Bunlar parçası bashmı?
Hesap MakinesiFeline

1
@CatsAreFluffy Onlar yerleşiktir.
faz

6

Python 2.7 - 96 91 90 87

Bir işlev yaptı.

f=lambda a:reduce(lambda x,y:x*256+int(y),a.split("."),0)
p=lambda a,b:abs(f(a)-f(b))+1

Kullanımı:

>>> p("1.2.3.4","1.2.3.5")
2

Düzenleme: Gereksiz kaldırıldı int()gelen fişlevi. İsaacg için teşekkürler

Düzen2:LF Dosyanın sonunda kaldırıldı (@Rusher sayesinde) ve başlatıcı map()pahasına kaldırıldı reduce()(@ njzk2 sayesinde)


1
f işlevi neden dışardan int () işlevine ihtiyaç duyuyor?
isaacg

1
İyi. Hiçbir fikrim yoktu: D
avall

haritayı kullanmak yerine int değerini azaltarak 2 karakter kazanabilir ( ,0azaltma işlevine parametre eklemeniz gerektiğinden yalnızca 2 )
njzk2

Neredeyse tam olarak sizin kodunuz olan bir şey yazdım, bu yüzden şimdi göndermekte zorlanmayacağım. Aslında, benimki üç karakter daha uzun!
danmcardle

5

GolfScript, 27 bayt

' '/{'.'/{~}%256base}/-abs)

Örnekler:

$ echo 0.0.0.0 255.255.255.255 | ruby golfscript.rb iprange.gs
4294967296
$ echo 255.255.255.255 0.0.0.0 | ruby golfscript.rb iprange.gs
4294967296
$ echo 1.2.3.4 1.2.3.4 | ruby golfscript.rb iprange.gs
1
$ echo 56.57.58.59 60.61.62.63 | ruby golfscript.rb iprange.gs
67372037

2
Bunun /yerine bir karakter kaydedebilirsiniz %~.
Dennis,

4

CoffeeScript - 94, 92, 79, 72

I=(a)->a.split(".").reduce((x,y)->+y+x*256)
R=(a,b)->1+Math.abs I(b)-I a

Golfsüz :

I = ( a ) ->
    return a.split( "." ).reduce( ( x, y ) -> +y + x * 256 )

R = ( a, b ) ->
    return 1 + Math.abs I( b ) - I( a )

Eşdeğer JavaScript :

function ip2long( ip_str )
{
    var parts = ip_str.split( "." );    
    return parts.reduce( function( x, y ) {
        return ( +y ) + x * 256; //Note: the unary '+' prefix operator casts the variable to an int without the need for parseInt()
    } );
}

function ip_range( ip1, ip2 )
{
    var ip1 = ip2long( ip1 );
    var ip2 = ip2long( ip2 );

    return 1 + Math.abs( ip2 - ip1 );
}

Çevrimiçi deneyin .


1
Bazı parantezleri boşluklarla değiştirerek bazı karakterleri kaydedebilirsiniz:I=(a)->n=0;a.split(".").forEach((x)->n<<=8;n+=parseInt x);n>>>0 R=(a,b)->1+Math.abs I(b)-I a
Rob W

Çok fazla alan kaybediyorsunuz gibi hissediyor Math.abs, ancak daha kısa bir şey bulamıyorum. (z>0)*z||-zElimden gelenin en iyisi (aynı uzunluk ve tek bir karakter girişi gerekiyor). Bundan daha akıllı bir şeyin var mı?
Aaron Dufour

Bu javascript sürümü gerçekten bana yardım ediyor, ive bir saattir bunun için arıyorum. Teşekkürler!
nodeffect,

4

dc, 61 karakter

?[dXIr^*rdXIr^*256*+r1~dXIr^*r256*+65536*+]dspxsalpxla-d*v1+p

Dizeleri ayrıştırma yeteneğine sahip olmadığından, bunun dc ile çözülebileceğinin şaşırtıcı olduğunu düşünüyorum. İşin püf noktası, 192.168.123.185’in yığın halinde

.185
.123
192.168

ve dXIr^*ondalık basamağı olduğu kadar kesir basamağı kadar kaydırır ve hatta .100 için çalışır.

$ echo 56.57.58.59 60.61.62.63 | dc -e '?[dXIr^*rdXIr^*256*+r1~dXIr^*r256*+65536*+]dspxsalpxla-d*v1+p'
67372037.00

Girişin zaten yığında olmasına izin verirseniz bir karakter çıkarın.


4

Powershell - 112 108 92 78 bayt

Bu benim ilk golf oynamam. İşte hiçbir şey gitmiyor:

Golf (Eski):

$a,$b=$args|%{$t='0x';$_-split'\.'|%{$t+="{0:X2}"-f[int]$_};[uint32]$t};1+[math]::abs($a-$b)

Golf (yeni)

$a,$b=$args|%{$t='0x';$_-split'\.'|%{$t+="{0:X2}"-f+$_};[long]$t}|sort;1+$b-$a

Ungolfed:

$a, $b = $args | % {           #powershell's way of popping an array. In a larger array
                               #$a would equal the first member and $b would be the rest.
    $t = '0x';                 #string prefix of 0x for hex notation
    $_ -split '\.' | % {       #split by escaped period (unary split uses regex)
        $t += "{0:X2}" -f +$_  #convert a dirty casted int into a hex value (1 octet)
    };
    [long]$t                   #and then cast to long
} | sort;                      #sort to avoid needing absolute value
1 + $b - $a                    #perform the calculation

kullanım

Dosya olarak kaydet (bu durumda getipamount.ps1) ve ardından konsoldan çağrı yapın

getipamount.ps1 255.255.255.255 0.0.0.0

4

LINQ ile C # - 139 bayt

(Bob'un önerisini uyguladıktan sonra 140'tan.)

long f(params string[] a){return Math.Abs(a.Select(b=>b.Split('.').Select(long.Parse).Aggregate((c,d)=>c*256+d)).Aggregate((e,f)=>e-f))+1;}

Ungolfed ....

    long f(params string[] a)                           // params is shorter than two parameters.
    {
        return Math.Abs(                                // At the end, make all values +ve.
             a.Select(                                  // Go through both items in the array...
                b =>                                    // Calling each one 'b'. 
                    b.Split('.')                        // Separating out each "." separated byte...
                    .Select(long.Parse)                 // Converting them to a long.
                    .Aggregate((c, d) => c*256 + d)     // Shift each byte along and add the next one.
             )
             .Aggregate((e,f) => e-f)                   // Find the difference between the two remaining values.
         )+1;                                           // Add one to the result of Math.Abs.
    }

https://dotnetfiddle.net/XPTDlt


Birisi bana, bu bütün baytların bir şey boyunca nasıl değiştiğini açıklayabilir mi?
Obversity

@Obversity a.b.c.deşdeğerdir (a << 24) | (b << 16) | (c << 8) | (d << 0)eşdeğerdir (((a << 8) << 8) << 8) + ((b << 8) << 8) + (c << 8) + d). Temel olarak, toplamanın her yinelemesi mevcut toplamı alır ve bir oktet tarafından sola kaydırır, ardından bir sonraki oktet ekler.
Bob,

Bunun c*256yerine karakter kullanarak kaydedebilirsiniz (c<<8).
Bob

@Bob Peki benekli.
billpg

Sen değiştirerek iki daha fazla karakter kaydedebilirsiniz e-file e<f?f-e:e-fbırakarakMath.Abs()
Patrick Huizinga

4

Perl, 43 bayt

#!perl -pa
$_=1+abs${\map{$_=vec eval,0,32}@F}-$F[0]

Shebang'ı iki bayt olarak saymak.

Örnek Kullanım:

$ echo 0.0.0.0 255.255.255.255 | perl count-ips.pl
4294967296

$ echo 255.255.255.255 0.0.0.0 | perl count-ips.pl
4294967296

$ echo 56.57.58.59 60.61.62.63 | perl count-ips.pl
67372037

notlar

  • vec eval,0,32için bir bırakma ip2long. Perl, karakter değişmezlerinin, bir ön eki olarak sıralı olarak ifade edilmesini sağlar v, örneğin v0boş karakter için kullanılabilir. Bunlar da birlikte zincirlenebilir, örneğin v65.66.67.68ABCD. Üç veya daha fazla değer bulunduğunda, başlangıç vgerekli değildir. vecFonksiyon yorumlayan bir tamsayı dizisi olarak bir dize, bit belirtilen sayıda (burada, 32) sahip olan, her bir hücre. unpack N,evalaynı zamanda eşit işe yarayacaktı.

3

JavaScript ES6 - 68 bayt

f=x=>prompt().split('.').reduce((a,b)=>+b+a*256);1+Math.abs(f()-f())

Firefox’un konsolu ile (F12 tuşuna basın) deneyin.


Sen kullanarak olmalıdır alertya console.log. Konsol çıkışı ucuz.
nderscore,

4
@nderscore, console.logdoğrudan çıktı arasında kesinlikle fark yoktur . Bu kod golf, temiz kod değil.
Michael M.

Bu meta gönderiye en çok cevap verilen cevap aynı fikirde değil: IO için JavaScript Standartları . Bu temiz bir kod meselesi değil. Bu aslında hiçbir şey çıkarılamaması meselesi.
nderscore

@ DigitalTrauma, operatör önceliği nedeniyle çalışmaz . (ekleme, bit yönünde kaydırma)
Michael M.

2

Python 2.7, 104 bayt

y=lambda:map(int,input().split("."));a,b=y(),y();print sum(256**(3-i)*abs(a[i]-b[i])for i in range(4))+1

1
Çözüm için teşekkürler. Yapabileceğinizi düşünüyor musunuz: 1. Uzunluktan ödün vermeden okunabilirlik için noktalı virgülden yeni satırlara geçin. 2. Kodun nasıl çalıştığını açıklayın?
isaacg,

2

Perl, 72 bayt

#!perl -ap
@a=map{unpack N,pack C4,split/\./,$_}@F;$_=abs($a[1]-$a[0])+1

Kullanımı:

$ echo 10.0.2.0 10.0.3.255 | perl ip-range.pl
512$ 

Bu zaten Primo'nun Perl programından daha uzun , bu yüzden çok ilginç değil.

Eski IP adres formatı için 119 bayt, Perl

#!perl -ap
sub v(){/^0/?oct:$_}@a=map{$m=3;@p=split/\./,$_;$_=pop@p;$s=v;$s+=v<<8*$m--for@p;$s}@F;$_=abs($a[1]-$a[0])+1

Kullanımı:

$ echo 10.0.2.0 10.0.3.255 | perl ip-obsolete.pl
512$ 
$ echo 10.512 10.1023 | perl ip-obsolete.pl
512$ 
$ echo 0xa.0x200 012.01777 | perl ip-obsolete.pl 
512$ 

Bu program IP adresleri için eski formatı kabul eder! Bu, 1, 2 veya 3 parçalı veya onaltılık veya sekizli parçalı adresleri içerir. Alıntıİnet_addr (3) kılavuz sayfasından ,

Nokta notasyonu kullanılarak belirtilen değerler aşağıdaki formlardan birini alır:

a.b.c.d
a.b.c
a.b
a

... Üç bölümlü bir adres belirtildiğinde, son bölüm 16 bitlik bir miktar olarak yorumlanır ve ağ adresinin en sağdaki iki baytına yerleştirilir. ... İki bölümlü bir adres verildiğinde, son bölüm 24 bitlik bir miktar olarak yorumlanır ve ağ adresinin en sağdaki üç baytına yerleştirilir. ... Sadece bir kısım verildiğinde, değer herhangi bir byte düzenlemesi olmadan doğrudan ağ adresinde saklanır.

Nokta notasyonunda "parça" olarak verilen tüm sayılar, C dilinde belirtildiği gibi ondalık, sekizli veya onaltılık olabilir (yani, bir satır 0x veya 0X onaltılık anlamına gelir; satır 0, sekizlik anlamına gelir; ondalık olarak yorumlandı).

Çoğu program artık bu eskimiş formatı kabul etmiyor, ancak ping 0177.1hala OpenBSD 5.5'te çalışıyordu.


BSD kullandığınız gerçeği IP olayından daha şaşırtıcı.
faz

2

PHP, 138 110 bayt

<?php

function d($a,$b){foreach(explode('.',"$a.$b")as$i=>$v){$r+=$v*(1<<24-$i%4*8)*($i<4?1:-1);}return 1+abs($r);}

// use it as
d('0.0.0.0','255.255.255.255');

'Hayır kullanımdan kaldırma uyarıları' hiç söz yok gibi, değiştirerek bir char kaydedebilirsiniz explode('.',"$a.$b")ile split('\.',"$a.$b").
MrLore

Ben 110, 110 değil sayıyorum. Bir fonksiyon yerine bir program ile 9 bayt ve bu golf adımlarla 8 daha kaydedin
Titus

1

Mathematica 9, 108 bayt

c[f_,s_]:=1+First@Total@MapIndexed[#1*256^(4-#2)&,First@Abs@Differences@ToExpression@StringSplit[{f,s},"."]]

Ungolfed:

countIpAddresses[first_, second_] := Module[{digitArrays, differences},

  (* Split the strings and parse them into numbers. 
  Mathematica automatically maps many/most of its functions across/
  through lists *)

  digitArrays = ToExpression[StringSplit[{first, second}, "."]];

  (* Find the absolute value of the differences of the two lists, 
  element-wise *)
  differences = Abs[Differences[digitArrays]];

  (* differences looks like {{4, 4, 4, 4}} right now, 
  so take the first element *)
  differences = First[differences];

  (* now map a function across the differences, 
  taking the nth element (in code, '#2') which we will call x (in 
  code, '#1') and setting it to be equal to (x * 256^(4-n)). 
  To do this we need to track the index, so we use MapIndexed. 
  Which is a shame, 
  because Map can be written '/@' and is generally a huge character-
  saver. *)
  powersOf256 = MapIndexed[#1*256^(4 - #2) &, differences];

  (* now we essentially have a list (of singleton lists, 
  due to MapIndexed quirk) which represents the digits of a base-256, 
  converted to decimal form. 
  Example: {{67108864},{262144},{1024},{4}}

  We add them all up using Total, 
  which will give us a nested list as such: {67372036}

  We need to add 1 to this result no matter what. But also, 
  to be fair to the challenge, we want to return a number - 
  not a list containing one number. 
  So we take the First element of our result. If we did not do this, 
  we could chop off 6 characters from our code. *)

  1 + First[Total[powersOf256]]
]


0

C # - 135

long f(string x,string y){Func<string,long>b=s=>s.Split('.').Select((c,i)=>long.Parse(c)<<(3-i)*8).Sum();return Math.Abs(b(x)-b(y))+1;}

Doğru biçimlendirilmiş

long g(string x, string y) { 
    Func<string, long> b = s => s.Split('.').Select((c, i) => long.Parse(c) << (3 - i) * 8).Sum(); 
    return Math.Abs(b(x) - b(y)) + 1; 
}

https://dotnetfiddle.net/Q0jkdA


0

Ruby, 93 bayt

a=->(x){s=i=0;x.split('.').map{|p|s+=256**(3-i)*p.to_i;i+=1};s}
s=->(x,y){1+(a[x]-a[y]).abs}

Çıktı

irb(main):003:0> s['1.1.1.1', '1.1.1.2']
=> 2
irb(main):006:0> s['0.0.0.0', '255.255.255.255']
=> 4294967296

0

J, 25 bayt

Noktalı dörtlü IP dizelerini sol ve sağ argüman olarak alır.

>:@|@-&(256#.".;.2@,&'.')

Açıklaması:

>:@|@-&(256#.".;.2@,&'.')  NB. ip range
      &(                )  NB. on both args, do:
                   ,&'.'   NB.   append a .
               ;.2@        NB.   split by last character:
             ".            NB.     convert each split to number
        256#.              NB. convert from base 256
   |@-                     NB. absolute difference
>:@                        NB. add 1 to make range inclusive

Örnekler:

   '0.0.0.0' >:@|@-&(256#.".;.2@,&'.') '255.255.255.255'
4294967296
   iprange =: >:@|@-&(256#.".;.2@,&'.')
   '255.255.255.255' iprange '0.0.0.0'
4294967296
   '1.2.3.4' iprange '1.2.3.4'
1
   '56.57.58.59' iprange '60.61.62.63'
67372037

0

Faktör, 73 bayt

CoffeeScript cevabının çevirisi.

[ "." split [ 10 base> ] [ [ 256 * ] dip + ] map-reduce ] bi@ - abs 1 + ]

0

Javascript ES6, 81 karakter

(a,b)=>Math.abs(eval(`(((((${a})>>>0)-(((((${b})>>>0)`.replace(/\./g,")<<8|")))+1

Ölçek:

f=(a,b)=>Math.abs(eval(`(((((${a})>>>0)-(((((${b})>>>0)`.replace(/\./g,")<<8|")))+1
;`0.0.0.0,255.255.255.255,4294967296
255.255.255.255,0.0.0.0,4294967296
1.2.3.4,1.2.3.4,1
56.57.58.59,60.61.62.63,67372037`.split`
`.map(x=>x.split`,`).every(x=>f(x[0],x[1])==x[2])

Not: Biraz sonra optimize etmeye çalışacağım.


0

Lua, 153 Bayt

Lua'nın bölünmüş bir işleve sahip olmaması çok yazık, benimkini tanımlamak zorunda kaldım!

a,b=...r=0y=8^8x={}t={}function f(t,s)s:gsub("%d+",function(d)t[#t+1]=d end)end
f(x,a)f(t,b)for i=1,4 do r=r+y*math.abs(t[i]-x[i])y=y/256 end print(r+1)

Ungolfed

a,b=...                    -- unpack the arguments into two variables
r=0                        -- initialise the sume of ip adress
y=8^8                      -- weight for the rightmost value
x={}t={}                   -- two empty arrays -> will contains the splittedip adresses
function f(t,s)            -- define a split function that takes:
                           --   a pointer to an array
                           --   a string
  s:gsub("%d+",function(d) -- iterate over the group of digits in the string
    t[#t+1]=d              -- and insert them into the array
  end)
end
f(x,a)                     -- fill the array x with the first address
f(t,b)                     -- fill the array t with the second address
for i=1,4                  -- iterate over t and x
do
  r=r+y*math.abs(t[i]-x[i])-- incr r by weight*abs(range a- range b)
  y=y/256                  -- reduce the weight
end
print(r+1)                 -- output the result

0

Jöle , 12 bayt, dil sonlandırma tarihi mücadelesi

ṣ”.V€ḅ⁹µ€ạ/‘

Çevrimiçi deneyin!

açıklama

ṣ”.V€ḅ⁹µ€ạ/‘
       µ€     On each element of input:
ṣ”.             Split on periods
   V€           Convert string to number in each section
     ḅ⁹         Convert base 256 to integer
         ạ/   Take absolute difference of the resulting integers
           ‘  Increment

Kapsayıcı bir aralıktaki elementlerin sayısı, bitiş noktalarının mutlak farkı, artı 1'dir.


0

Axiom, 385 bytes

c(a:String):INT==(d:=digit();s:NNI:=#a;t:INT:=0;for i in 1..s repeat(~member?(a.i,d)=>return-1;t:=t+(ord(a.i)-48)*10^(s-i)::NNI);t)
g(x:String):List NNI==(a:=split(x,char".");s:NNI:=#a;r:=[];for i in s..1 by -1 repeat(y:=c(a.i);y=-1=>return [];r:=concat(y,r));r)
m(x:NNI,y:NNI):NNI==x*256+y
f(a:String,b:String):INT==(x:=g(a);y:=g(b);#x~=4 or #y~=4=>-1;1+abs(reduce(m,x)-reduce(m,y)))

ungolf it and test

-- convert the string only digit a in one not negative number
-- return -1 in case of error
cc(a:String):INT==
     d:=digit();s:NNI:=#a;t:INT:=0
     for i in 1..s repeat
               ~member?(a.i,d)=>return -1
               t:=t+(ord(a.i)-48)*10^(s-i)::NNI
     t

-- Split the string x using '.' as divisor in a list of NNI
-- if error return []
gg(x:String):List NNI==
    a:=split(x,char".");s:NNI:=#a;r:=[]
    for i in s..1 by -1 repeat
          y:=cc(a.i)
          y=-1=>return []
          r:=concat(y,r)
    r


mm(x:NNI,y:NNI):NNI==x*256+y

-- Return absolute value of difference of address for IP strings in a and in b 
-- Retrun -1 for error
-- [Convert the IP strings in a and in b in numbers ad subtract and return the difference]
ff(a:String,b:String):INT==(x:=gg(a);y:=gg(b);#x~=4 or #y~=4=>-1;1+abs(reduce(mm,x)-reduce(mm,y)))


(14) -> f("0.0.0.0", "255.255.255.255")
   (14)  4294967296
                                                    Type: PositiveInteger
(15) -> f("255.255.255.255", "0.0.0.0")
   (15)  4294967296
                                                    Type: PositiveInteger
(16) -> f("1.2.3.4", "1.2.3.4")
   (16)  1
                                                    Type: PositiveInteger
(17) -> f("56.57.58.59", "60.61.62.63")
   (17)  67372037
                                                    Type: PositiveInteger
(18) -> f("1", "2")
   (18)  - 1
                                                            Type: Integer
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.