I'm surprised this hasn't come up in a challenge yet.

Output the IP address of the machine you're running on. You are required to output both the local and external IP addresses.

Local IP address, ie along the default format of 192.168.x.x

Public IP address can be verified by using google https://www.google.co.uk/search?source=hp&q=whats+my+ip

Output can be in any format. IPv4 or IPv6 or any mix of each is allowed, however they must be the only output. Code can be a full program or a function.

rules apply so shortest code wins.

Standard Loopholes are forbidden.

EDIT: As per @Peter Taylor's comment, in the case where multiple of either type of address are present, you can choose to either output the first one, or as many as you can access. So long as at least one local and one public are present.

  • 3
    \$\begingroup\$ I think the 0/1 thing adds in unnecessary fluff to the challenge. \$\endgroup\$ – Mr. Xcoder Aug 18 '17 at 9:48
  • 5
    \$\begingroup\$ This is underspecified. In particular, it doesn't clearly address cases where there are multiple local IP addresses and/or multiple public IP addresses. Furthermore, there's no reliable way of telling whether I have multiple public IP addresses, and if so what they are. \$\endgroup\$ – Peter Taylor Aug 18 '17 at 11:08
  • 5
    \$\begingroup\$ What if the host doesn't have any RFC 1918 addresses? It looks like there's no reliable answer to this, except on machines that have at least one private network. \$\endgroup\$ – Toby Speight Aug 18 '17 at 12:12
  • 4
    \$\begingroup\$ ... and even one network interface can have multiple IP addresses. \$\endgroup\$ – Kaz Aug 18 '17 at 13:26
  • 14
    \$\begingroup\$ Actually, I don't see how you could solve half of this without fetching from an external source, which is one of the standard loopholes you have expressly forbidden. \$\endgroup\$ – Octopus Aug 18 '17 at 16:50

20 Answers 20


Bash + curl + iproute2, 54 50 49 48 33 bytes

ip r g 1|awk '$0=$7'
curl eth0.me

Thanks @DomHastings for golfing off 1 byte!

Thanks @Sisyphus for coming up with a shorter URL!

Thanks @zeppelin for golfing off 9 bytes!

  • \$\begingroup\$ @DomHastings Your last golf attempts returns some garbage along with the ip address, at least on Ubuntu 16.04.3 LTS \$\endgroup\$ – Ferrybig Aug 18 '17 at 13:05
  • \$\begingroup\$ @Ferrybig Yeah, the 1/0 part outputs an error to STDERR, but that is ignored by default, if you get different output for ip route though, that could just be the version I was running on my machine. Shame! \$\endgroup\$ – Dom Hastings Aug 18 '17 at 16:19
  • \$\begingroup\$ The first line prints 1000 for me... ip route get 1 output: ptpb.pw/pixx \$\endgroup\$ – Majora320 Aug 18 '17 at 22:04
  • \$\begingroup\$ When I run that code I get this output: RTNETLINK answers: Network is unreachable \$\endgroup\$ – kasperd Aug 18 '17 at 23:51
  • 1
    \$\begingroup\$ You can also optimize your AWK expression a bit: awk 'NR<2&&$0=$7' \$\endgroup\$ – zeppelin Aug 19 '17 at 6:59

Bash 37 31 27 bytes

This is inspired by the answer by Bruce Forte. That answer only works with IPv4 which means it doesn't work for me. I have rewritten it into a version that (only) works with IPv6:

ip r g b::|awk '$0=$9" "$9'

This is tested on Ubuntu 14.04.5 connected through PPPoE and since IPv6 is designed to be used without any NAT it will output the same IP address twice.

-6 bytes thanks to zeppelin, -2 bytes thanks to Ferrybig, -2 bytes thanks to Markasoftware.

  • \$\begingroup\$ On my Ubuntu 16.04.3 LTS, I had to change '{print$11,$11}' to '{print$9,$9}' to make the command work, your command returned 1024 2 times, Your command works on my Ubuntu 16.04.2 machine \$\endgroup\$ – Ferrybig Aug 19 '17 at 15:46
  • \$\begingroup\$ @Ferrybig Probably depends on network configuration then. I tested this on a network where addresses are auto-configured from router advertisements. \$\endgroup\$ – kasperd Aug 19 '17 at 15:55
  • \$\begingroup\$ For machines where the ip address is manually configured (static), ip route doesn't output the proto ra part, you could use this as a feature to golf your answer further \$\endgroup\$ – Ferrybig Aug 19 '17 at 16:00
  • \$\begingroup\$ @Ferrybig At the moment I am pondering whether I can find a way to make it work in both cases without the size blowing up. Btw. on my 16.04.3 machine which received its configuration using router advertisements it says proto static not proto ra, though that difference doesn't matter to this code. \$\endgroup\$ – kasperd Aug 19 '17 at 16:37
  • \$\begingroup\$ To golf it a bit, use awk '$0=$9" "$9' instead of {print$11,$11}. Many systems (including my Arch one) use the 9th word, so it's shorter than 11, and also using this syntax is smaller than print$9,$9 \$\endgroup\$ – markasoftware Aug 24 '17 at 21:06

AutoIt, 56 53 bytes


@IPAddress1 is a macro that returns

IP address of first network adapter

_GetIP() returns

the public IP address.

-3 bytes thanks to @mınxomaτ

  • 3
    \$\begingroup\$ Neat, a fellow AutoIt (not IT) -er. You can delete the spaces in this code. \$\endgroup\$ – mınxomaτ Aug 18 '17 at 13:22
  • \$\begingroup\$ @mınxomaτ Thanks for the correction :) \$\endgroup\$ – Daniel Aug 18 '17 at 16:45

Mathematica, 17 bytes

Mathematica has a builtin for everything


As described in the documentation, this builtin command lists all IP addresses (both local and external) associated with your device.

  • \$\begingroup\$ The documentation doesn't say anything about external addresses. \$\endgroup\$ – kasperd Aug 19 '17 at 12:04
  • \$\begingroup\$ If this command also lists the ipv6 address, then you can say the ipv6 address is the expected result \$\endgroup\$ – Ferrybig Aug 19 '17 at 15:57
  • 5
    \$\begingroup\$ This produces a list of several IP addresses for me, but none of them seem to be my external address; I may not be interpreting things correctly, though. I can get my external IP address from something like WolframAlpha["ip address", {{"IPAddress:InternetData", 1}, "ComputableData"}][[1,2]] but I don't know how to get at that more directly. \$\endgroup\$ – Mark S. Aug 19 '17 at 16:17
  • \$\begingroup\$ @MarkS. That is odd; I get my external IP address when I run the command (the last entry seems to be it). This command won't work on Wolfram Sandbox, though. Perhaps this is a bug; what OS and Mathematica version are you using? \$\endgroup\$ – JungHwan Min Aug 20 '17 at 19:14
  • \$\begingroup\$ @JungHwanMin Student Edition gives me 6 things that I assume are IPv6, then, and three addresses beginning with 169.254. But my external address begins with 69. \$\endgroup\$ – Mark S. Aug 21 '17 at 23:13

C#, 196 194 188 163 bytes

namespace System.Net.Sockets{using Linq;_=>Dns.GetHostEntry("").AddressList.First(i=>(int)i.AddressFamily==2)+" "+new WebClient().DownloadString("http://eth0.me")}

Saved 2 bytes thanks to @Xynos.
Saved 25 bytes thanks to @Nick.

Full/Formatted Version:

namespace System.Net.Sockets
    using Linq;

    class P
        static void Main()
            Func<object, string> f = _ =>
                    .First(i => (int)i.AddressFamily == 2) + " " + new WebClient().DownloadString("http://eth0.me");


  • \$\begingroup\$ cant you save two bytes by removing the whitespace around the == ? \$\endgroup\$ – MysticVagabond Aug 18 '17 at 10:54
  • \$\begingroup\$ @Xynos Of course, didn't realise I hadn't removed it. \$\endgroup\$ – TheLethalCoder Aug 18 '17 at 10:58
  • \$\begingroup\$ The golfed version does not compile and is not a standalone function. It doesn't seem fair to mix a standalone function with the shortcut of using the Sockets namespace, so I'd suggest picking one option and going with it. That said, you can save some bytes by casting i.AddressFamily to int instead of casting 2 to AddressFamily, and you can replace Dns.GetHostName() with the empty string. \$\endgroup\$ – Nick Aug 18 '17 at 22:42
  • \$\begingroup\$ @Nick I will try that when I get a chance and the namespace trick is fairly common for C#. If you think it shouldn't be allowed you can post on meta about it but at the moment it is fair game and a neat trick in shortening usings. \$\endgroup\$ – TheLethalCoder Aug 19 '17 at 15:58

PowerShell v4+, 40 36 bytes

NetIPAddress|% IPA*
iwr eth0.me|% C*

(Only works on Server 2012 R2 or above, or Windows 8.1 or above. Doesn't work on TIO.)

Does exactly what it says on the tin. Gets the local network IP addresses and selects just the IPAddress portion thereof (e.g., filters out the subnet mask, the gateway, etc.).

The second is a Invoke-WebRequest to http://eth0.me which simply gets the Content thereof; i.e., just the public IP address.

Ungolfed version:

(Invoke-WebRequest eth0.me).content
  • \$\begingroup\$ An anonymous user suggests removing Get- \$\endgroup\$ – Stephen Aug 18 '17 at 22:16
  • \$\begingroup\$ @StepHen Indeed. Works great. \$\endgroup\$ – AdmBorkBork Aug 21 '17 at 12:39

Unix Shell + stunclient, 40 bytes

stunclient stun.vo.lu|cut -d: -f2|sed 1d

Makes use of a STUN protocol:

Session Traversal Utilities for NAT (STUN) is a protocol that serves as a tool for other protocols in dealing with Network Address Translator (NAT) traversal. It can be used by an endpoint to determine the IP address and port allocated to it by a NAT

The STUN server name is from the Public STUN server list.

The output format is:


Note that both lines will be indented with a single space, but I believe this does not break the output rules as written.

Sample output:

curl (bash one-liner): 27 bytes

curl -w%{local_ip} eth0.me

The result is printed on stdout and looks like this:
# no trailing newline, use "curl -w%{local_ip}\\n eth0.me" for it

curl should be at least of version 7.29.0 (from Feb 6, 2013).

The answer is based on https://codegolf.stackexchange.com/a/139538/66016.


Go, MacOS only, 10 bytes

In macOS this killswitch could be used, it can print current private active IP and public IP:

$ killswitch 
Interface  MAC address         IP
en1        bc:34:36:d2:81:ba

Public IP address:

No VPN interface found, verify VPN is connected

This is not a built-in tool but tries to simplify the process of finding the proper IP's.

The output could get by using commands like:

$ route get

$ ifconfig | pcregrep -M -o '^[^\t:]+:([^\n]|\n\t)*status: active'

$ networksetup -listnetworkserviceorder

$ scutil --dns

Public IP:

$ dig o-o.myaddr.l.google.com @ns.google.com txt +short
  • 2
    \$\begingroup\$ Hi! Welcome to PPCG! This question is tagged code-golf. Could you provide golfed code with a language and a byte count? \$\endgroup\$ – Stephen Aug 21 '17 at 12:48

Python 3, 124 133 bytes

from urllib2 import urlopen
import socket
print a,b
  • \$\begingroup\$ Don't you also need to print a,b? Interestingly, this does output two IPs on my system (Win7), but neither one of them is my actual local IP address. b is actually the IP of a virtual adapter and not my Local Area Connection. \$\endgroup\$ – Octopus Aug 18 '17 at 16:31
  • \$\begingroup\$ Arguably though, that is still a local Ip address. I left a comment on the Question to ask for clarification on that. \$\endgroup\$ – Octopus Aug 18 '17 at 16:43
  • \$\begingroup\$ @Octopus you're right about printing, updated \$\endgroup\$ – Teo Aug 18 '17 at 17:22
  • \$\begingroup\$ In a suggested edit, @David suggested this: 113 bytes (Review here) \$\endgroup\$ – Stephen Aug 18 '17 at 17:48

PowerShell v3+ (alternative answer for windows 7+)

((ipconfig) -match "v4").split(":")[1]
Invoke-RestMethod eth0.me
  • 2
    \$\begingroup\$ Welcome to PPCG! \$\endgroup\$ – Stephen Aug 18 '17 at 21:06
  • 1
    \$\begingroup\$ You can remove the spaces surrounding -match to save a couple bytes. \$\endgroup\$ – AdmBorkBork Aug 21 '17 at 12:42

Bash + Awk + Curl, 43 bytes

using only built in tools for Mac and Linux

ifconfig|awk '/bro/{print $2}';curl eth0.me
  • 1
    \$\begingroup\$ *bash you mean . \$\endgroup\$ – Suici Doga Aug 19 '17 at 4:42
  • \$\begingroup\$ bash + awk + curl \$\endgroup\$ – Alex Nikiforov Aug 19 '17 at 8:18
  • \$\begingroup\$ i edited the question to say bash since it works on my linux laptop not just macos \$\endgroup\$ – Suici Doga Aug 19 '17 at 8:48
  • \$\begingroup\$ thx, I improved since bash is a shell per se (should work on tcsh, sh and any other shell), you need to have ifconfig, awk and curl also \$\endgroup\$ – Alex Nikiforov Aug 19 '17 at 9:35
  • 1
    \$\begingroup\$ This isn't "MacOS/Linux", it's Bash. Just mark it as such. \$\endgroup\$ – LyricLy Aug 19 '17 at 10:31

Node.js (JavaScript) 224 223 194 175 173 130 bytes


Ungolfed version:

require('dns').lookup(require('os').hostname(), (err, loc, fam) => console.log(loc));
require('http').get('http://eth0.me', res => {
    res.on('data', chunk => console.log(chunk + ""));

  • Saved 1 byte (due to unnecessary semicolon).
  • Saved 29 bytes thanks to @AndrewLi (used arrow functions for shorter code).
  • Saved 19 bytes thanks to @MiniGod (used .get() instead of .request() - .end(); removed).
  • Saved 2 bytes thanks to @Zacharý (parentheses not needed around a lone parameter of an arrow function).
  • Saved 43 bytes thanks to @Birjolaxew (stored require and console.log in single-letter variables, passed url directly to require('http').get, logged output directly from data event).
  • \$\begingroup\$ Can't you use arrow functions for shorter code? \$\endgroup\$ – Andrew Li Aug 18 '17 at 17:11
  • \$\begingroup\$ @AndrewLi Great suggestion, thanks. :) \$\endgroup\$ – user73540 Aug 18 '17 at 17:48
  • \$\begingroup\$ You can use .get() instead of .request(). Then you also don't need the .end();. \$\endgroup\$ – MiniGod Aug 18 '17 at 17:56
  • 1
    \$\begingroup\$ You don't need parens around a lone parameter of an arrow function. ((a)=> => a=>), IIRC. \$\endgroup\$ – Zacharý Aug 18 '17 at 18:37
  • 1
    \$\begingroup\$ @AndrewLi Hmm, the problem is that when the code is run in the REPL, it prints out extra info (e.g. the request information), which is prohibited in the question. I could add extra code to hide this output, but it might counteract the reduction of bytes which result from leaving out the require calls, so I'll leave it for now. Thanks for the suggestion anyway. \$\endgroup\$ – user73540 Aug 18 '17 at 20:48

Python 2.7.13 128 bytes

print __import__("urllib").urlopen("http://eth0.me").read(),__import__("socket").gethostbyname(__import__("socket").getfqdn())

Windows' Batch File, 116 bytes

@for /f "tokens=1-2 delims=:" %%a in ('ipconfig^|find "v4"')do @echo%%b
@powershell -Command "(iwr eth0.me).content"

The first line iterates through the results of running ipconfig and gets your local IPv4 address.

For the public IP part, I had to steal a bit from the marvelous Powershell answer because, as far as I know, there is no way to get the machine's public IP using solely batch scripting.

We start with an @ sign, to suppress echoing the prompt (C:\...\path>), then run the Powershell command Invoke-WebRequest (with its alias, iwr) and extract the content part of that.

I experimented with not using (...).content and, instead, only running the command and extracting the actual information from the complete output, using batch. But that proved to be way longer than this solution, so I kept it.

Tested on Windows 10.0.15063.


R, 142, 140, 137 bytes


Tested on win10 and R (3.4.1).
Thanks for @Bruce-Forte for short URL.

Ungolfed version:

system("ipconfig",int=T) %>% 
     regmatches(.,regexpr("v4.+",.)) %>% 
      {a <- nchar(.)
       substr(., a - 14, a)}
  • \$\begingroup\$ Down to 120 bytes Try it online! \$\endgroup\$ – BLT Aug 23 '17 at 20:21
  • \$\begingroup\$ @BLT nice solution. You can save 3 bytes, by replacing a <- nchar(x) with a=nchar(x) \$\endgroup\$ – AndriusZ Aug 24 '17 at 11:30
  • \$\begingroup\$ @AndruisZ thanks, but it's really your solution -- I just de-magrittr'd it. \$\endgroup\$ – BLT Aug 24 '17 at 15:37

Bash + Curl, 24 bytes

hostname -i;curl eth0.me
  • \$\begingroup\$ This doesn't work.. From the man page: "This option enumerates all configured addresses on all network interfaces. [...] Do not make any assumptions about the order of the output." \$\endgroup\$ – ბიმო Dec 19 '17 at 8:13
  • \$\begingroup\$ Doesn't -I (capital) have a different use than -i (lowercase). The bit you quoted was from the -I section. \$\endgroup\$ – Probably Dec 19 '17 at 13:50
  • \$\begingroup\$ True, sorry about that. But even worse it says "Avoid using this option", either way this doesn't work (at least on my machines).. \$\endgroup\$ – ბიმო Dec 19 '17 at 20:29
  • \$\begingroup\$ Right, admittedly I did not read the full documentation before posting. Oddly enough it seems to work fine on a few of my machines. But this inconsistency would make this solution unreliable at best. \$\endgroup\$ – Probably Dec 20 '17 at 13:38

MS-SQL, 59 bytes

SELECT TOP 1 local_net_address
FROM sys.dm_exec_connections

Returns the client-facing IP address of the SQL instance executing the query.


VBA, 58 Bytes

Whoops, does not handle local address - fix in progress

Note: Uses reference to

Microsoft Internet Controls

Anonymous VBE immediate window function that takes no input and outputs the user's IP address via an Internet Explorer window

Set i=New InternetExplorer:i.Visible=1:i.Navigate"eth0.me"

Bash — 29 bytes (linux)

curl ipinfo.io/ip
hostname -i

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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