How many IP addresses are in a given range?

32

6

Inspired by...

Networking - How can I work out how many IP addresses there are in a given range?

Write a program or function that takes two strings as input, each being an IPv4 address expressed in standard dotted notation and outputs or returns the number of IP addresses covered by this range, including the two IP addresses input.

  • You must not use any external code, libraries or services designed to parse an IP address. (Other string processing standard library functions are acceptable.)
  • All 2^32 IP addresses are equal. No distinction is made to broadcast, class E, etc.
  • Normal code-golf rules apply.

For example:

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

billpg

Posted 2014-05-29T18:43:30.013

Reputation: 1 995

I saw this question on programmers, and was thinking about asking it on code golf lol. – Cruncher – 2014-05-30T14:59:10.490

3I thought this is a StackOverflow question about what IP addresses are impossible according to the standards. – Ming-Tang – 2014-05-30T18:30:07.100

8Isn't IPv4 a bit passe? – ugoren – 2014-05-31T08:37:40.770

Answers

20

GolfScript, 20 bytes

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

Try it online.

Test cases

$ 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

How it works

~]        # 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.

Dennis

Posted 2014-05-29T18:43:30.013

Reputation: 196 637

Very nice, and nice use of $ to avoid abs. – Chris Jester-Young – 2014-05-30T06:26:07.927

4~] is also really clever. – primo – 2014-05-30T07:23:16.880

10

Python 2 - 106

See it here.

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

Example Input

0.0.0.0
0.0.0.255

Example Output

256

Rainbolt

Posted 2014-05-29T18:43:30.013

Reputation: 6 176

1def a():return reduce(lambda c,d:c*256+d,map(int,raw_input().split("."))) is a lot shorter – Michael M. – 2014-05-29T20:37:57.140

5@Michael Thanks for the suggestion. I used it for a few minutes, then looked at it and thought, "I didn't write 90% of that." so I rolled it back. – Rainbolt – 2014-05-29T20:50:29.723

@Michael a=lambda: instead of def a():return saves 6 characters – avall – 2014-05-30T11:41:03.300

@Rusher It's 107 characters, not 106 – avall – 2014-05-30T11:44:07.367

1@avall: I assume you're counting the final LF. – Dennis – 2014-05-30T13:36:32.137

@Rusher No i don't. I double checked it. Maybe you don't count LF between both lines. – avall – 2014-05-30T13:37:41.477

@avall: I've copied, pasted and tested. It's 106 bytes. Any chance you have a CR before your LF? – Dennis – 2014-05-30T13:42:02.380

Yes, it was LF. Edited it in HEX Editor. I'm on linux. – avall – 2014-05-30T14:08:41.087

@Michael: if using reduce, you don't even need the map reduce(lambda c,d:c*256+int(d),raw_input().split("."),0), gains 2 more chars – njzk2 – 2014-05-30T14:24:42.320

8

CJam - 15

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

Try it at http://cjam.aditsu.net/

Thanks Dennis, wow, I don't know how to get the best out of my own language :p

aditsu quit because SE is EVIL

Posted 2014-05-29T18:43:30.013

Reputation: 22 326

You can save two bytes by eliminating :i (b seems to cast to integer) and one by using {r...}2* instead of qS/{...}/ – Dennis – 2014-06-02T22:12:18.783

6

Pure bash, 66 bytes

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

Notes:

  • Defines a function p that is passed a dotted decimal IP address, and outputs the hex representation of that address:
    • ${1//./ } is a parameter expansion that replaces . with in the IP address passed to p()
    • The printf is mostly self explanatory. Since there is only one format specifier %02x and four remaining args, the format specifier is reused for each remaining arg, effectively concatenating the 2 hex digits of each of the 4 octets together
  • $[] causes arithmetic expansion. We do a basic subtraction, and assign to the variable r
  • ${r/-} is a parameter expansion to remove a possible - character - effectively abs()
  • Display 1 + the absolute difference to give the range.

Output:

$ ./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
$ 

Digital Trauma

Posted 2014-05-29T18:43:30.013

Reputation: 64 644

I detect printf and echo. Are those part of bash? – CalculatorFeline – 2016-04-11T00:34:10.223

1@CatsAreFluffy They're builtins. – phase – 2016-04-11T03:21:00.883

6

Python 2.7 - 96 91 90 87

Made a function.

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

Usage:

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

Edit: Removed unnecessary int() from f function. Thanks to isaacg

Edit2: Removed LF at the end of file (thanks to @Rusher) and removed map() at cost of reduce() initializer (thanks to @njzk2)

avall

Posted 2014-05-29T18:43:30.013

Reputation: 1 547

I just wrote something that is almost exactly your code, so I won't bother submitting now. Actually, mine is three characters longer! – danmcardle – 2015-03-24T13:51:57.637

1why does the f function need int() on the outside? – isaacg – 2014-05-30T07:14:36.567

1Well. I had no idea :D – avall – 2014-05-30T07:23:11.567

can gain 2 chars by putting the int in the reduce instead of using the map (only 2 as you need to add ,0 parameter to your reduce function) – njzk2 – 2014-05-30T14:26:39.143

5

GolfScript, 27 bytes

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

Examples:

$ 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

Chris Jester-Young

Posted 2014-05-29T18:43:30.013

Reputation: 4 464

2You can save one char by using / instead of %~. – Dennis – 2014-05-30T05:21:34.497

5

Perl, 43 bytes

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

Counting the shebang as two bytes.

Sample Usage:

$ 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

Notes

  • vec eval,0,32 is a drop-in for ip2long. Perl allows character literals to be expressed as their ordinal prefixed with a v, for example v0 can be used for the null char. These can also be chained together, for example v65.66.67.68ABCD. When three or more values are present, the initial v is unnecessary. The vec function interprets a string as an integer array, each cell having the specified number of bits (here, 32). unpack N,eval would have worked equally as well.

primo

Posted 2014-05-29T18:43:30.013

Reputation: 30 891

4

C# with LINQ - 139 bytes

(From 140 after applying Bob's suggestion.)

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

billpg

Posted 2014-05-29T18:43:30.013

Reputation: 1 995

Could someone explain to me how this whole shifting bytes along thing works? – Obversity – 2014-05-30T00:31:06.130

@Obversity a.b.c.d is equivalent to (a << 24) | (b << 16) | (c << 8) | (d << 0) is equivalent to (((a << 8) << 8) << 8) + ((b << 8) << 8) + (c << 8) + d). Basically, each iteration of the aggregation takes the existing sum and shifts it left by one octet, then adds the next octet. – Bob – 2014-05-30T01:04:37.647

You can save a character by using c*256 instead of (c<<8). – Bob – 2014-05-30T01:13:42.933

@Bob Well spotted. – billpg – 2014-05-30T07:54:26.163

You can save two more characters by replacing e-f with e<f?f-e:e-f and dropping the Math.Abs() – Patrick Huizinga – 2014-05-30T10:06:20.377

Scrap my last comment, you can save 4 by using Math.Abs(a.Select((b,i)=>b.Split('.').Select(long.Parse).Aggregate((c,d)=>c*256+d)*(1-2*i)).Sum())+1. The (1-2*i) will result in 1 for the first item and -1 for the second, thus making the second item negative, which will then be 'summed' to the first item. – Patrick Huizinga – 2014-05-30T10:36:19.083

And another 5 by replacing .Select(long.Parse).Aggregate((c,d)=>c*256+d) with .Select((c,j)=>long.Parse(c)<<8*j).Sum(). – Patrick Huizinga – 2014-05-30T10:44:50.323

And 2 more by replacing a.Select((b,i)=>b.Split('.').Select((c,j)=>long.Parse(c)<<8*j).Sum()*(1-2*i)).Sum() with a.SelectMany((b,i)=>b.Split('.').Select((c,j)=>(1-2*i)*long.Parse(c)<<8*j)).Sum(). Assign the sign when parsing the part. Then use SelectMany, instead of Select with a Sum inside, to get 8 numbers (one for each part of each address), which already get Summed in the end anyway. – Patrick Huizinga – 2014-05-30T10:48:48.503

@PatrickHuizinga I think your combined suggestions are a significant enough departure from my original code that you should submit a separate answer. (Unless there are prizes. I want to keep the prizes.) – billpg – 2014-05-30T10:52:26.093

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

Un-golfed:

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

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

Equivalent 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 );
}

Try it online.

Tony Ellis

Posted 2014-05-29T18:43:30.013

Reputation: 1 706

this javascript version really helps me, ive been searching for this for like an hour. thanks! – nodeffect – 2019-05-13T07:27:14.923

1You can save some characters by replacing some parentheses with spaces: 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 – 2014-05-29T20:48:43.783

It feels like you're losing a lot of space to Math.abs, but I can't come up with anything shorter. (z>0)*z||-z is the best I've got (same length, and it needs a single-char input). Do you have anything cleverer than that? – Aaron Dufour – 2014-05-30T21:07:58.233

4

dc, 61 characters

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

I think it's pretty amazing that this can be solved with dc at all since it has no ability to parse strings. The trick is that 192.168.123.185 goes on the stack as

.185
.123
192.168

and dXIr^* shifts the decimal point right as many fraction digits as there are and it even works for .100.

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

Subtract a character if you let the input already be on the stack.

Geoff Reedy

Posted 2014-05-29T18:43:30.013

Reputation: 2 828

4

Powershell - 112 108 92 78 bytes

This is my first time golfing. Here goes nothing:

Golfed (Old):

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

Golfed (new)

$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

Usage

Save as file (in this case getipamount.ps1) and then call from the console

getipamount.ps1 255.255.255.255 0.0.0.0

SomeShinyObject

Posted 2014-05-29T18:43:30.013

Reputation: 953

3

JavaScript ES6 - 68 bytes

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

Try it with the console (press F12) of Firefox.

Michael M.

Posted 2014-05-29T18:43:30.013

Reputation: 12 173

You should be using alert or console.log. Console output is cheap. – nderscore – 2014-05-29T20:24:29.333

4@nderscore, absolutely no difference between console.log and direct output. This is code-golf, it's not about do clean code. – Michael M. – 2014-05-29T20:31:53.407

The most upvoted answer to this meta post disagrees: JavaScript Standards for IO. It's not a matter of clean code. It's a matter of not actually outputting anything.

– nderscore – 2014-05-29T20:57:39.757

@DigitalTrauma, it won't work due to operator precedence. (addition vs bitwise shift)

– Michael M. – 2014-05-29T22:29:47.757

2

PHP, 138 110 bytes

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

Vitaly Dyatlov

Posted 2014-05-29T18:43:30.013

Reputation: 151

I count 109, not 110. Save 9 bytes with a program instead of a function and 8 more with these golfing steps: http://sandbox.onlinephpfunctions.com/code/6d6e403b7f9f188644f9b4ced77da93de13ec97b

– Titus – 2017-03-13T13:24:05.127

As there's no mention of 'no deprecation warnings', you can save a char by replacing explode('.',"$a.$b") with split('\.',"$a.$b"). – MrLore – 2014-06-02T10:22:34.237

2

Perl, 72 bytes

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

Usage:

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

This is already longer than primo's Perl program, so not too interesting.

Perl, 119 bytes, for obsolete IP address format

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

Usage:

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

This program accepts the obsolete format for IP addresses! This includes addresses with 1, 2, or 3 parts, or with hexadecimal or octal parts. Quoting the inet_addr(3) manual page,

Values specified using dot notation take one of the following forms:

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

... When a three part address is specified, the last part is interpreted as a 16-bit quantity and placed in the rightmost two bytes of the network address. ... When a two part address is supplied, the last part is interpreted as a 24-bit quantity and placed in the rightmost three bytes of the network address. ... When only one part is given, the value is stored directly in the network address without any byte rearrangement.

All numbers supplied as ``parts'' in a dot notation may be decimal, octal, or hexadecimal, as specified in the C language (i.e., a leading 0x or 0X implies hexadecimal; a leading 0 implies octal; otherwise, the number is interpreted as decimal).

Most programs no longer accept this obsolete format, but ping 0177.1 still worked in OpenBSD 5.5.

kernigh

Posted 2014-05-29T18:43:30.013

Reputation: 2 615

The fact you're using BSD is more surprising than the IP thing. – phase – 2016-04-11T03:22:52.767

2

Python 2.7, 104 bytes

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

Pablo Lucena

Posted 2014-05-29T18:43:30.013

Reputation: 21

1Thanks for the solution. Do you think you could: 1. Switch from semicolons to newlines, for readability without sacrificing length. 2. Explain how the code works? – isaacg – 2015-03-22T07:58:28.630

1

PHP, 46 Bytes

<?=abs(ip2long($argv[1])-ip2long($argv[2]))+1;

Try it online!

ip2long

Jörg Hülsermann

Posted 2014-05-29T18:43:30.013

Reputation: 13 026

1

Mathematica 9, 108 bytes

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

Ian Douglas

Posted 2014-05-29T18:43:30.013

Reputation: 111

0

Jelly, 12 bytes, language postdates challenge

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

Try it online!

Explanation

ṣ”.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

The number of elements in an inclusive range is the absolute difference of their endpoints, plus 1.

user62131

Posted 2014-05-29T18:43:30.013

Reputation:

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

RosLuP

Posted 2014-05-29T18:43:30.013

Reputation: 3 036

0

J, 25 bytes

Takes the dotted-quad IP strings as left and right arguments.

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

Explained:

>:@|@-&(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

Examples:

   '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

algorithmshark

Posted 2014-05-29T18:43:30.013

Reputation: 8 144

0

Ruby, 93 bytes

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}

Output

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

bsd

Posted 2014-05-29T18:43:30.013

Reputation: 141

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

Properly formatted

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

tia

Posted 2014-05-29T18:43:30.013

Reputation: 745

0

Factor, 73 bytes

Translation of the CoffeeScript answer.

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

cat

Posted 2014-05-29T18:43:30.013

Reputation: 4 989

0

Javascript ES6, 81 chars

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

Test:

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

PS: I'll try to optimise it a bit later.

Qwertiy

Posted 2014-05-29T18:43:30.013

Reputation: 2 697

0

Lua, 153 Bytes

It's a shame that lua doesn't have a split function, I had to define mine!

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

Katenkyo

Posted 2014-05-29T18:43:30.013

Reputation: 2 857