Verbose IP Range Generator

11

1

The task is simple, given two IP adresses a and b, output all addresses within that range.


Examples

Example #1:

f(a = 192.168.0.1, b = 192.168.0.4) 
    192.168.0.1
    192.168.0.2
    192.168.0.3
    192.168.0.4

Example #2 (TIO will truncate this, use a smaller range when testing):

f (a = 123.0.200.0, b = 124.0.0.0)
    123.0.200.0
    123.0.200.1
    ...            # Omitted pattern 
    123.0.200.255
    123.0.201.0
    ...            # Omitted pattern
    123.0.201.255
    ...            # Omitted pattern
    123.0.255.255
    123.1.0.0
    ...            # Omitted pattern
    123.255.255.255
    124.0.0.0

Input and Output

  • a < b in other words:
    • Defined Programatically: a[0] < b[0] || (a[0] == b[0] && a[1] < b[1]) || (a[0:1] == b[0:1] && a[2] < b[2]) || (a[0:2] == b[0:2] && a[3] < b[3])
    • Defined in Words: a will always be lower than b (so you will have to increment the subnet to reach b).
    • No, you do not have to handle a == b (if you do, kudos).
  • Output should be in order from "lowest" to "highest" (see examples).
  • For this challenge, the valid syntax for an IP is: \d{1-3}\.\d{1-3}\.\d{1-3}\.\d{1-3}.
  • You do not have to handle non-IP address input, if it's unexpected input you may error.
  • Output may be as an array or as a delimited string (using any whitespace character).

Winning

Magic Octopus Urn

Posted 2017-06-05T19:03:57.380

Reputation: 19 422

1You have "Omitted Pattern" between e.g. 123.0.200.255 and 123.0.201.0, but aren't they sequential? – nmjcman101 – 2017-06-05T19:18:48.793

@nmjcman101 did that twice, fixed. – Magic Octopus Urn – 2017-06-05T19:36:35.987

Answers

3

Pyth, 22

mj\.jd256}FmivMcd\.256

Try it online.

               cd\.       # split string by "."
             vM           # eval list (convert strings to integers)
            i      256    # convert list of base256 digits to integer
           m          Q   # map the above over implicit input list
         }F               # inclusive range
    jd256                 # convert to list of base256 digits
 j\.                      # join by "." 
m                         # map over inclusive range 

Digital Trauma

Posted 2017-06-05T19:03:57.380

Reputation: 64 644

1This inspired a change to Pyth that should make such code shorter in the future. vM will be the default for v when applied to a list. – isaacg – 2017-06-06T02:27:22.827

@isaacg cool - thanks, I'll try to remember that for next time. – Digital Trauma – 2017-06-06T05:09:39.217

3

Batch, 623 bytes

@echo off
set s=%1.%2
call:c %s:.= %
exit/b
:c
if %1==%5 goto d
call:d %1 %2 %3 %4 %1 255 255 255
set/al=%1+1,u=%5-1
for /l %%i in (%l%,1,%u%)do call:d %%i 0 0 0 %%i 255 255 255
call:d %5 0 0 0 %5 %6 %7 %8
exit/b
:d
if %2==%6 goto e
call:e %1 %2 %3 %4 %1 %2 255 255
set/al=%2+1,u=%6-1
for /l %%j in (%l%,1,%u%)do call:e %1 %%j 0 0 %5 %%j 255 255
call:e %5 %6 0 0 %5 %6 %7 %8
exit/b
:e
if %3==%7 goto f
call:f %1 %2 %3 %4 %1 %2 %3 255
set/al=%3+1,u=%7-1
for /l %%k in (%l%,1,%u%)do call:e %1 %2 %%k 0 %5 %6 %%k 255
call:e %5 %6 %7 0 %5 %6 %7 %8
exit/b
:f
for /l %%l in (%4,1,%8)do echo %1.%2.%3.%%l

Unfortunately Batch's 32-bit arithmetic can't print all IP addresses, so I have to split it up into octets.

Neil

Posted 2017-06-05T19:03:57.380

Reputation: 95 035

Is removing the @echo off an option? Not that it makes a huge difference. – Digital Trauma – 2017-06-06T05:21:53.193

@DigitalTrauma I guess it's not strictly necessary as the echo always goes to the console and so isn't part of STDOUT but it's very annoying especially on long scripts such as this one. – Neil – 2017-06-06T07:47:19.983

2

Python 2, 128 bytes

a,b=[reduce(lambda a,b:a<<8|int(b),x.split('.'),0)for x in input()]
while a<=b:print'.'.join(`a>>i&255`for i in[24,16,8,0]);a+=1

Try it online!

ovs

Posted 2017-06-05T19:03:57.380

Reputation: 21 408

2

PHP, 71 Bytes

Output as string

for($s=ip2long($argv[1]);$s<=ip2long($argv[2]);)echo long2ip($s++)," ";

Try it online! or Output as array

print_r(array_map(long2ip,range(ip2long($argv[1]),ip2long($argv[2]))));

Try it online!

Jörg Hülsermann

Posted 2017-06-05T19:03:57.380

Reputation: 13 026

2

Jelly, 18 bytes

ṣ”.V€ḅ⁹µ€r/b⁹j”.$€

Try it online!

The output appears to by a mush of digits and decimals, but is stored internally as a list of strings. Append a Y to the end (+1 byte) to join the strings by newlines.

How it Works

ṣ”.V€ḅ⁹µ€r/b⁹j”.$€ - main link, input is a list of addresses which are strings
       µ€          - for each address string,
ṣ”.                  - split on periods
   V€                - eval each element in the list (convert strings to numbers)
     ḅ⁹              - transform from base 256 to integer (⁹ is 256)
         r/        - take the inclusive range
           b⁹      - convert each element in the range from integer to base 256
             j”.$€ - join each address with periods.

fireflame241

Posted 2017-06-05T19:03:57.380

Reputation: 7 021

2

JavaScript (ES6), 104 bytes

g=s=>s.replace(/(\d+)\.256/,(_,n)=>++n+'.0')
f=(a,b)=>a==b?a:a+`
`+f(g(g(g(g(a+'.256').slice(0,-2)))),b)

This solution replaces the pattern n.256 with n+1.0, and it calls itself recursively until the two parameters are equal.

It appends '.256' to the initial input to get the ball rolling. slice(0,-2) is then used to remove the trailing '.0'.

Examples:

g=s=>s.replace(/(\d+)\.256/,(_,n)=>++n+'.0')
f=(a,b)=>a==b?a:a+`
`+f(g(g(g(g(a+'.256').slice(0,-2)))),b)

console.log('192.168.0.1 ... 192.168.0.4');
console.log(f('192.168.0.1', '192.168.0.4'));

console.log('123.255.255.0 ... 124.0.3.0');
console.log(f('123.255.255.0', '124.0.3.0'));

console.log('192.1.1.1 ... 192.1.1.1 ... kudos');
console.log(f('192.1.1.1', '192.1.1.1'));

Rick Hitchcock

Posted 2017-06-05T19:03:57.380

Reputation: 2 461

1

Java (OpenJDK 8), 339 314 282 bytes

Golfed:

long f(String i)throws Exception{return java.nio.ByteBuffer.wrap(java.net.InetAddress.getByName(i).getAddress()).getInt()&(1L<<32)-1;}void g(String[] a)throws Exception{for(long l=f(a[0]),m=255;l<=f(a[1]);)System.out.println(((l>>24)&m)+"."+((l>>16)&m)+"."+((l>>8)&m)+"."+(l++&m));}

Ungolfed:

long ipToLong(String ip) throws Exception {
    return java.nio.ByteBuffer.wrap(java.net.InetAddress.getByName(ip).getAddress()).getInt() & (1L << 32) - 1;
}

void printRange(String[] ips) throws Exception {
    for (long ip = ipToLong(ips[0]), m = 255; ip <= ipToLong(ips[1]);)
        System.out.println(((ip >> 24) & m) + "." + ((ip >> 16) & m) + "." + ((ip >> 8) & m) + "." + (ip++ & m));
}

Try it online!

Bashful Beluga

Posted 2017-06-05T19:03:57.380

Reputation: 413