18
\$\begingroup\$

Write the shortest function to convert an IP address into it's integer representation and output it as an integer.

To change an IPv4 address to it's integer representation, the following calculation is required:

  • Break the IP address into it's four octets.
  • (Octet1 * 16777216) + (Octet2 * 65536) + (Octet3 * 256) + (Octet4)

Sample Input

192.168.1.1           10.10.104.36           8.8.8.8

Sample Output

3232235777            168454180              134744072
\$\endgroup\$
2
  • 2
    \$\begingroup\$ I think this would be better if there was a restriction in place prohibiting a language's built-in functions. \$\endgroup\$ Commented Feb 6, 2011 at 20:04
  • \$\begingroup\$ @George - Yea, it would have been, but people had already done it before the I could put that in - I honestly didn't think about it. \$\endgroup\$ Commented Feb 7, 2011 at 5:51

52 Answers 52

11
\$\begingroup\$

PHP - 21 Characters

<?=ip2long($argv[1]);
\$\endgroup\$
8
\$\begingroup\$

MySQL - 20 Characters

SELECT INET_ATON(s);
\$\endgroup\$
8
\$\begingroup\$

Ruby (no builtins/eval) - 47

s=->s{s.split(".").inject(0){|a,b|a<<8|b.to_i}}

Test:

s["192.168.1.1"]
3232235777
\$\endgroup\$
8
\$\begingroup\$

C: 79 characters

main(i,a)char**a;{i=i<<8|strtol(a[1],a+1,0);*a[1]++?main(i,a):printf("%u",i);}

EDIT: removed C++, would not compile without headers; with GCC, the printf and strtol function calls trigger built-in functions, hence headers can be skipped. Thx to @ugoren for the tips. This will compile as is without additional options to gcc.

EDIT2: return is actually redundant :)

\$\endgroup\$
10
  • \$\begingroup\$ very clever use of main() :) .. my version was 116bytes. \$\endgroup\$
    – akira
    Commented Feb 15, 2011 at 14:21
  • \$\begingroup\$ I get a segmentation fault. \$\endgroup\$ Commented Feb 19, 2011 at 3:11
  • \$\begingroup\$ @George, what is your input and how are you running it? \$\endgroup\$
    – Nim
    Commented Feb 21, 2011 at 10:43
  • \$\begingroup\$ I'm running it with my UserScript through codepad.org \$\endgroup\$ Commented Feb 21, 2011 at 19:33
  • \$\begingroup\$ This won't work in C++, you can't call main recursively. \$\endgroup\$ Commented Feb 26, 2012 at 17:40
7
\$\begingroup\$

Golfscript -- 16 chars

{[~]2%256base}:f

As a standalone program, this is even shorter at 11.

~]2%256base

Extremely straightforward. Evaluates the input string (~) and puts it into an array []. Since the .s in the string duplicate the top of the stack, we only take every other term in the array (2%). We now have an array which basically represents a base 256 number, so we use a built-in function to do the conversion. (256base).

\$\endgroup\$
4
  • \$\begingroup\$ very clever. i guess base256 is treated differently to say base10 or base16 then where 48=>0? \$\endgroup\$
    – gnibbler
    Commented Feb 6, 2011 at 20:05
  • \$\begingroup\$ @gnibbler: I'm not sure what you're suggesting -- the base function handles all bases the same way, e.g. {:B;{\B*+}*}:base (although the real function is overloaded for conversions the other way). Interesting to note is that base conversion for strings is the same as arrays (as strings are just arrays without nesting, but with a different output format). \$\endgroup\$
    – Nabb
    Commented Feb 6, 2011 at 20:27
  • \$\begingroup\$ yeah i was thinking of base conversions of strings, so i didn't look closely enough at base for my answer \$\endgroup\$
    – gnibbler
    Commented Feb 7, 2011 at 0:20
  • \$\begingroup\$ Very clever. Now do that for an IPv6 address. :) \$\endgroup\$ Commented Feb 29, 2012 at 17:28
7
\$\begingroup\$

Befunge - 2x11 = 22 characters

So close, Befunge will win one day.

>&+~1+#v_.@
^*4*8*8<

Explanation

The biggest distinguishing feature of Befunge is that instead of being a linear set of instructions like most languages; it is a 2d grid of single character instructions, where control can flow in any direction.

>      v
^      <

These characters change the direction of control when they are hit, this makes the main loop.

 &+~1+

This inputs a number and pushes it onto the stack (&), pops the top two values off the stack, adds them and pushes them back onto the stack (+), inputs a single character and places its ascii value on the stack (~), then pushes 1 onto the stack and adds them (1+).

The interpreter I've been using returns -1 for end of input, some return 0 instead so the 1+ part could be removed for them.

      #v_.@

The # causes the next character to be skipped, then the _ pops a value off the stack and if it is zero sends control right, otherwise sends it left. If the value was zero . pops a value off the stack and outputs it as an integer and @ stops the program. Otherwise v sends control down to the return loop.

^*4*8*8<

This simply multiplies the top value of the stack by 256 and returns control to the start.

\$\endgroup\$
2
  • \$\begingroup\$ Pardon my ignorance, but should that be 19 chars? I understand why you say 2x11, but why does it work that way? \$\endgroup\$ Commented Feb 4, 2011 at 19:08
  • \$\begingroup\$ Befunge is a 2d language, if you look for the >v<^ that is actually the main loop in this program. I guess in this case control doesn't actually pass through those last 3 spaces on the bottom, but I find it easiest to just count Befunge programs as the smallest bounding rectangle; and if you were to try and count control flow you get into trouble with self-modifying programs. \$\endgroup\$
    – Nemo157
    Commented Feb 4, 2011 at 22:37
5
\$\begingroup\$

Ruby (40)

q=->x{x.gsub(/(\d+)\.?/){'%02x'%$1}.hex}

->

q["192.168.1.1"]
=> 3232235777
\$\endgroup\$
3
  • \$\begingroup\$ Nice idea of using regexp. \$\endgroup\$
    – Hauleth
    Commented Feb 28, 2012 at 14:56
  • \$\begingroup\$ Very clever! Also you can write to_i 16 as hex to save some characters. \$\endgroup\$ Commented Mar 1, 2012 at 21:54
  • \$\begingroup\$ thanks @chron that made both this and link 4 characters shorter \$\endgroup\$
    – jsvnm
    Commented Mar 2, 2012 at 8:35
4
\$\begingroup\$

Ruby - 46 chars

require"ipaddr"
def f s;IPAddr.new(s).to_i;end
\$\endgroup\$
1
  • \$\begingroup\$ I think that constitutes cheating. ;-) \$\endgroup\$ Commented Feb 2, 2011 at 12:10
4
\$\begingroup\$

AWK in ~47 chars

First-timer here... Um, not sure how to count this, but without the 'echo' it's 47 chars in AWK. (Not exactly bogey golf, but it's in the hole.)

echo $addr | /bin/awk -F\. '{print $1*16777216+$2*65536+$3*256+$4}'

Full day early for #tbt, too, so I actually met a schedule!!! *8-)

Banner day.

\$\endgroup\$
1
  • 2
    \$\begingroup\$ Welcome! You'd only count the body of what you'd put into an awk script. See this answer. In your case you'd count only {print $1*16777216+$2*65536+$3*256+$4}. Of course you'd have to move the field separator into the program, rather than specifying it as a flag. \$\endgroup\$
    – Jonah
    Commented Nov 13, 2018 at 2:00
4
\$\begingroup\$

Bash - 46

Table of content

You will find 4 differently golfed version:

echo $[_=32,`printf "%d<<(_-=8)|" ${1//./ }`0]                        # 46chr
set -- ${1//./ };echo $[$1<<24|$2<<16|$3<<8|$4]                       # 47chr
v=('|%d<<'{24,16,8,0});printf -vv "${v[*]}" ${1//./ };echo $[0$v]     # 65chr
mapfile -td. i<<<$1;for((a=o=0;a<4;o+=i[a]<<(3-a++)*8)){ :;};echo $o  # 68chr

New version! 2018-11-15 More golfed, 46 char

echo $[_=32,`printf "%d<<(_-=8)|" ${1//./ }`0]

Explanation

  • I used $_ for more golfing.
  • Syntax ${1//./ }will substitute every dots . by spaces .
  • so printfwill render something like 192<<(_-=8)|168<<(_-=8)|1<<(_-=8)|1<<(_-=8)|
  • then we will add a 0 after last OR | and
  • preset _ to 32. will read construct from left to right, so $((_-=8)) make 24 at 1st shift, 16 on second, and so on.

in action:

set -- 192.168.1.1
echo $[_=32,`printf "%d<<(_-=8)|" ${1//./ }`0]
3232235777

For fun: trying to get $_ content, after this:

echo $_
3232235777

;-b

set -- 192.168.1.1
echo $_ $[_=32,`printf "%d<<(_-=8)|" ${1//./ }`0] $_
192.168.1.1 3232235777 0

Ok, that's correct 32 - 4 x 8 = 0

In a function:

ip2int() {
    echo $[_=32,`printf "%d<<(_-=8)|" ${1//./ }`0]
}
ip2int 192.168.1.1
3232235777
ip2int 255.255.255.255
4294967295
ip2int 0.0.0.0
0

or into a loop: -> 60

ip2int() {
    for i;do
        echo $[_=32,`printf "%d<<(_-=8)|" ${i//./ }`0]
    done
}

ip2int 192.168.1.1 10.10.104.36 8.8.8.8 1.1.1.1 255.255.255.255 0.0.0.0
3232235777
168454180
134744072
16843009
4294967295
0

bash (v4.1+): 47

First post

set -- ${1//./ };echo $[$1<<24|$2<<16|$3<<8|$4]

Explanation:

  • Syntax ${1//./ }will substitute every dots . by spaces .
  • set -- set positional parameters ($@=($1 $2 $3...))
  • So set -- ${1//./ } will split $1 by dots and set $1, $2, $3 and $4 if string containg 3 dots (and no spaces).

in action:

set -- 192.168.1.1
set -- ${1//./ };echo $[$1<<24|$2<<16|$3<<8|$4]
3232235777

or in a function:

ip2int() {
    set -- ${1//./ }
    echo $[$1<<24|$2<<16|$3<<8|$4]
}
ip2int 192.168.1.1
3232235777
ip2int 0.0.0.0
0

or into a loop: -> 61

for i;do set -- ${i//./ };echo $[$1<<24|$2<<16|$3<<8|$4];done

in action:

ip2int() {
    for i;do
        set -- ${i//./ }
        echo $[$1<<24|$2<<16|$3<<8|$4]
    done
}

ip2int 192.168.1.1 10.10.104.36 8.8.8.8 1.1.1.1 0.0.0.0
3232235777
168454180
134744072
16843009
0

Another version differently golfed: 65

v=('|%d<<'{24,16,8,0});printf -vv "${v[*]}" ${1//./ };echo $[0$v]

Sample:

ip2int() {
    v=('|%d<<'{24,16,8,0});printf -vv "${v[*]}" ${1//./ };echo $[0$v]
}

ip2int 255.255.255.255
4294967295
ip2int 10.10.104.36
168454180

In a loop (+14): 82

ip2int() {
    for i;do
        v=('|%d<<'{24,16,8,0})
        printf -vv "${v[*]}" ${1//./ }
        echo $[0$v]
    done
}

* or a little more ugly: 70*

v=('|%d<<'{24,16,8});printf -vv "${v[*]}" ${1//./ };echo $[0${v%<<2*}]

where printf give some string like |192<<24 |168<<16 |1<<8|1<<24 |0<<16 |0<<8 we have to cut at last <<2....

golfed with mapfile, longer: 68

ip2int() {
    mapfile -td. i<<<$1;for((a=o=0;a<4;o+=i[a]<<(3-a++)*8)){ :;};echo $o
}

or with loop: 82

ip2int() {
    for a;do
      mapfile -td. i<<<$a;for((a=o=0;a<4;o+=i[a]<<(3-a++)*8)){ :;};echo $o
    done
}
\$\endgroup\$
6
  • \$\begingroup\$ could you add a brief explanation? i've been trying to get into bash golfing and i don't follow what's happening with the set -- part. thanks. \$\endgroup\$
    – Jonah
    Commented Nov 12, 2018 at 20:27
  • \$\begingroup\$ @Jonah : set -- foo bar will populate $@ with foo as $1 and bar as $2. \$\endgroup\$ Commented Nov 13, 2018 at 17:01
  • \$\begingroup\$ @Jonah Added new version \$\endgroup\$ Commented Nov 13, 2018 at 17:18
  • \$\begingroup\$ New version! more golfed, -1 char!! \$\endgroup\$ Commented Nov 15, 2018 at 10:12
  • \$\begingroup\$ Fun: Try to look content of $_ after running echo $[_=32,`printf "%d<<(_-=8)|" ${1//./ }`0] ;-) \$\endgroup\$ Commented Nov 15, 2018 at 10:25
3
\$\begingroup\$

Golfscript - 21 chars

{'.'/{~}%{\256*+}*}:f
\$\endgroup\$
1
  • \$\begingroup\$ +1 Good solid solution. Don't you wish GolfScript provides bit-shifting operators? ;-) (Though, darned if I know which symbols they should be bound to.) \$\endgroup\$ Commented Feb 2, 2011 at 12:12
3
\$\begingroup\$

Python 56 45

c=lambda x:eval('((('+x.replace('.','<<8)+'))
\$\endgroup\$
3
\$\begingroup\$

C++ - lots of chars

#include <boost/algorithm/string.hpp>
#include <string>
#include <vector>
uint f(std::string p)
{
        std::vector<std::string> x;
        boost::split(x,p,boost::is_any_of("."));
        uint r=0;
        for (uint i = 0; i < x.size(); i++)
                r=r*256+atoi(x[i].c_str());
        return r;
}
\$\endgroup\$
1
  • \$\begingroup\$ @George Edison: using boost helps to get down with the numbers of chars? :) \$\endgroup\$
    – akira
    Commented Feb 15, 2011 at 14:24
3
\$\begingroup\$

PowerShell 66 61

Variation on Joey's answer:

filter I{([ipaddress](($_-split'\.')[3..0]-join'.')).address}

PS C:\> '192.168.1.1' | I
3232235777
PS C:\> '10.10.104.36' | I
168454180
PS C:\> '8.8.8.8' | I
134744072
\$\endgroup\$
1
  • \$\begingroup\$ Argh, I must have been stupid to have missed that ... \$\endgroup\$
    – Joey
    Commented Feb 15, 2011 at 1:59
3
\$\begingroup\$

Powershell, 47 43 bytes

$args-split'\.'|%{$r=([long]$r-shl8)+$_};$r

Test script:

$f = {

$args-split'\.'|%{$r=([long]$r-shl8)+$_};$r

}

@(
    ,("192.168.1.1",3232235777)
    ,("10.10.104.36",168454180)
    ,("8.8.8.8",134744072)
) | % {
    $s,$expected = $_
    $result = &$f $s
    "$($result-eq$expected): $result"
}

Output:

True: 3232235777
True: 168454180
True: 134744072
\$\endgroup\$
2
\$\begingroup\$

Windows PowerShell, 70

Naïve approach:

filter I{[int[]]$x=$_-split'\.'
$x[0]*16MB+$x[1]*64KB+$x[2]*256+$x[3]}

With using System.Net.IPAddress: 76

filter I{([ipaddress]($_-replace('(.+)\.'*3+'(.+)'),'$4.$3.$2.$1')).address}

Test:

> '192.168.1.1'|I
3232235777
\$\endgroup\$
2
\$\begingroup\$

Befunge-93 - 36 characters

&"~"2+::8****&884**:**&884***&++++.@
\$\endgroup\$
2
\$\begingroup\$

Perl : DIY ( for oneliners. )(40)

$j=3;$i+=($_<<($j--*8))for split/\./,$x;

# Use value in $i

DIY Function(65):

sub atoi{my($i,$j)=(0,3);$i+=($_<<($j--*8))for split'.',shift;$i}
\$\endgroup\$
2
  • \$\begingroup\$ You can split by a string, so you save a character by using split'.' rather than split/\./ \$\endgroup\$ Commented Feb 5, 2011 at 10:14
  • \$\begingroup\$ With the function version, yes, but the inline version no, because you'd need split q{.} to get around the need to escape shell quotes :/ \$\endgroup\$ Commented Feb 6, 2011 at 4:59
2
\$\begingroup\$

Haskell - 14 chars

(.) a=(256*a+)

usage in GHCi:

Prelude> let (.) a=(256*a+)
Prelude> 192. 168. 0. 1
3232235521

The only problem is that you have to put spaces left or right of the dot, otherwise the numbers will be interpreted as floating point.

\$\endgroup\$
3
  • \$\begingroup\$ mind adding a brief explanation? \$\endgroup\$
    – Jonah
    Commented Nov 12, 2018 at 20:28
  • \$\begingroup\$ the dot infix operator is redefined to do the computation, very smart indeed! \$\endgroup\$
    – memo
    Commented Nov 22, 2018 at 12:36
  • \$\begingroup\$ This is very clever, but it doesn't use the correct input format (because of the spaces) \$\endgroup\$
    – 12Me21
    Commented Nov 24, 2018 at 19:39
2
\$\begingroup\$

C# – 77 chars

Func<string,uint>F=s=>s.Split('.').Aggregate(0u,(c,b)=>(c<<8)+uint.Parse(b));
\$\endgroup\$
2
\$\begingroup\$

JavaScript (45 characters)

Requires support for the .reduce() Array method introduced in ES5 and arrow functions.

f=(x)=>x.split('.').reduce((p,c)=>p<<8|c)>>>0
\$\endgroup\$
1
  • \$\begingroup\$ Huh... I didn't know >>> worked like that (converting to unsigned 32 bit integer) \$\endgroup\$
    – 12Me21
    Commented Nov 24, 2018 at 15:30
2
\$\begingroup\$

05AB1E, 5 bytes

'.¡₁β

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ dude people are such ninjas \$\endgroup\$
    – Makonede
    Commented Apr 22, 2021 at 19:46
1
\$\begingroup\$

C# - 120 Characters

float s(string i){var o=i.Split('.').Select(n=>float.Parse(n)).ToList();return 16777216*o[0]+65536*o[1]+256*o[2]+o[3];}

My first code golf - be gentle ;)

\$\endgroup\$
2
  • \$\begingroup\$ You can remove the spaces around your first '='. However, your main problem is int overflow ;). Remember, an IP address takes up 4 full bytes. \$\endgroup\$
    – Nellius
    Commented Feb 2, 2011 at 10:49
  • \$\begingroup\$ @Nellius - quite right. I didn't even think of checking that, basically checked on compile. Thanks, will fix now. \$\endgroup\$ Commented Feb 2, 2011 at 12:35
1
\$\begingroup\$

D: 84 Characters

uint f(S)(S s)
{
    uint n;
    int i = 4;

    foreach(o; s.split("."))
        n += to!uint(o) << 8 * --i;

    return n;
}
\$\endgroup\$
1
  • \$\begingroup\$ i don't know D so forgive me if it's whitespace sensitive like python, but this doesn't look golfed. can you remove the double line breaks or the line breaks between semi-colon terminated statements? \$\endgroup\$
    – Jonah
    Commented Nov 12, 2018 at 20:25
1
\$\begingroup\$

Python 3.2 (69)

sum((int(j)*4**(4*i)) for i,j in enumerate(input().split('.')[::-1]))
\$\endgroup\$
1
\$\begingroup\$

PHP (no builtins/eval) - 54

<foreach(explode(".",$argv[1])as$b)$a=@$a<<8|$b;echo$a;
\$\endgroup\$
3
  • \$\begingroup\$ Shouldn't this open with <?php, not just <? \$\endgroup\$
    – TRiG
    Commented Sep 25, 2012 at 16:44
  • \$\begingroup\$ @TRiG, I believe you can change the PHP opening delimiter in the config file. Useful in this case. \$\endgroup\$
    – Xeoncross
    Commented Sep 25, 2012 at 16:56
  • \$\begingroup\$ @Xeoncross. Ah. Neat. I might try that one day, just to mess with my workmates' heads. \$\endgroup\$
    – TRiG
    Commented Sep 25, 2012 at 16:57
1
\$\begingroup\$

Perl, 14 characters:

sub _{unpack'L>',pop}

# Example usage
print _(10.10.104.36) # prints 168454180
\$\endgroup\$
1
  • 6
    \$\begingroup\$ How do you make that 14 characters? I count 21. \$\endgroup\$ Commented Oct 3, 2012 at 10:49
1
\$\begingroup\$

Stax, 9 bytes

üL▼ü╛tΓi╨

Run and debug it

\$\endgroup\$
1
\$\begingroup\$

Perl 6, 16 bytes

{:256[m:g/\d+/]}

Try it online!

\$\endgroup\$
1
\$\begingroup\$

C (gcc) -m32 / POSIX, 33 bytes

f(a){inet_aton(a,&a);a=ntohl(a);}

Try it online!

On a big-endian platform, you could simply define a macro with -Df=inet_aton for 13 bytes.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.