Your network scanning tool is annoyingly picky about input, and immediately crashes if you feed it an IPv4 address that contains improper characters or isn't properly formatted.

An IPv4 address is a 32-bit numeric address written as four numbers separated by periods. Each number can be zero to 255.

We need to write a tool to pre-validate the input to avoid those crashes, and our specific tool is picky: A valid format will look like a.b.c.d where a, b, c and d:

• Can be a 0 or a natural number with no leading zeros.
• Should be between 0 - 255 (inclusive).
• Should not contain special symbols like +, -, ,, and others.
• Should be decimal (base 10)

Input: A string

Output: Truthy or Falsey value (arbitrary values also accepted)

Test Cases:

Input            |  Output  |  Reason
|          |
- 1.160.10.240   |  true    |
- 192.001.32.47  |  false   |  (leading zeros present)
- 1.2.3.         |  false   |  (only three digits)
- 1.2.3          |  false   |  (only three digits)
- 0.00.10.255    |  false   |  (leading zeros present)
- 1.2.$.4 | false | (only three digits and a special symbol present) - 255.160.0.34 | true | - .1.1.1 | false | (only three digits) - 1..1.1.1 | false | (more than three periods) - 1.1.1.-0 | false | (special symbol present) - .1.1.+1 | false | (special symbol present) - 1 1 1 1 | false | (no periods) - 1 | false | (only one digit) - 10.300.4.0 | false | (value over 255) - 10.4F.10.99 | false | (invalid characters) - fruit loops | false | (umm...) - 1.2.3.4.5 | false | (too many periods/numbers) - 0.0.0.0 | true | - 0.0 0.0. | false | (periods misplaced) - 1.23..4 | false | (a typo of 1.2.3.4) - 1:1:1:1:1:1:1:1| false | (an IPv6 address, not IPv4)  This is , so fewest bytes will win! Note for the users - if you want to add some more test-cases, you're welcomed (by suggesting an edit). But, please make sure that the test-cases don't repeat themselves! Thanks • Suggest testcases: 1.1.1.1.1, 1.1.1.1., .1.1.1, 1..1.1, 1..1.1.1, 1.1.1.0, 1.1.1.-0, 1.1.1.+1, 1.1.1.1E1, 1.1.1.256, 1.1.1.0x1, 255.255.255.255, 0.0.0.0, 'or 1=1--, <empty string>, 1 1 1 1, 1,1,1,1. – tsh Oct 22 '18 at 9:11 • Suggest adding test cases "1.2.3.4.5" (to rule out too long IPs) and "999.0.0.0" (to rule out too large IPs). – Triggernometry Oct 22 '18 at 15:50 • Possibly slightly picky, but you should probably refer to "IPv4 addresses" rather than "IP addresses" - or at least, mention somewhere that you just mean IPv4 addresses - otherwise 1234:5678::1 ought to be a valid IP address (whereas from the description it's clear that that's not intended :) – psmears Oct 23 '18 at 15:51 • @Criggie The premise isn't to actually check all real IP4 rules (like the ones you mentioned), it's to ensure that the input string doesn't crash some other (presumably badly written) app that only allows input in a very specific form. Also, we're not going to change the rules of a challenge that already has 30+ answers. – BradC Oct 23 '18 at 19:03 • @Criggie Worth noting that the RFC declares that "Addresses are fixed length of four octets". I think the fringe cases you're referencing are more specialized than this challenge. – Poke Oct 23 '18 at 19:12 37 Answers X86_64 machine code: 18 16 bytes Edit: This answer doesn't quite work, as 1. I am using inet_pton from the standard C libraries, which means I need the extern. I didn't include the extern in my byte count though. 2. I used the red zone as a result for the actual address, but called a function which also could've used the red zone. It fortunately doesn't on my machine, but some odd standard library build might use it which could cause undefined behavior. And yeah, the whole thing is pretty much being done by an already written function Anyway, this is what I got: 48 89 fe 6a 02 5f 48 8d 54 24 80 e9 00 00 00 00 Assembly: section .text extern inet_pton global ipIsValid ipIsValid: mov rsi, rdi ;mov rdi, 2 ; change to 10 for ipv6 push 2 pop rdi ; thank you peter lea rdx, [rsp - 128] jmp inet_pton  Explanation: Take a look at inet_pton(3). It takes a string IP address and puts it in a buffer you can use with struct sockaddr. It takes 3 arguments: the address family (AF_INET (ipv4), 2, or AF_INET6 (ipv6), 10), the ip address's string, and a pointer to the output. It returns 1 on success, 0 for an invalid address, or -1 for when the address family is neither AF_INET or AF_INET6 (which will never occur because I'm passing a constant to it). So I simply move the string to the register for the second argument, set the first register to 2, and set the third register to the red zone (128 bytes below the stack pointer) since I don't care about the result. Then I can simply jmp to inet_pton and let that return straight to the caller! I spun up this quick test program to test your cases: #include <stdio.h> #include <arpa/inet.h> #include <netinet/ip.h> extern int ipIsValid(char *); int main(){ char *addresses[] = { "1.160.10.240", "192.001.32.47", "1.2.3.", "1.2.3", "0.00.10.255", "1.2.$.4",
"255.160.0.34",
".1.1.1",
"1..1.1.1",
"1.1.1.-0",
".1.1.+1",
"1 1 1 1",
"1",
"10.300.4.0",
"10.4F.10.99",
"fruit loops",
"1.2.3.4.5",
NULL
};

for(size_t i = 0; addresses[i] != NULL; ++i){
}
return 0;
}


Assemble with nasm -felf64 assembly.asm, compile with gcc -no-pie test.c assembly.o, and you'll get:

Address 1.160.10.240:   true
Address 1.2.$.4: false Address 255.160.0.34: true Address .1.1.1: false Address 1..1.1.1: false Address 1.1.1.-0: false Address .1.1.+1: false Address 1 1 1 1: false Address 1: false Address 10.300.4.0: false Address 10.4F.10.99: false Address fruit loops: false Address 1.2.3.4.5: false  I could make this much smaller if the caller was supposed to pass AF_INET or AF_INET6 to the function • I love that you did this in asm. And the fact you explained it to those who might not understand it (as well as test code) is even better. Which is not to say that I could have done it in asm; far too many years have passed but I remember enough to see exactly what your explanation (and therefore process) is saying (does). Good work. – Pryftan Oct 23 '18 at 13:17 • e9 00 00 00 00 is a jmp near$+5, not a jmp inet_pton. If you provide opcode, you should include the including inet_pton part, not leave a blank – l4m2 Oct 23 '18 at 16:58
• 15 bytes-TIO 32bit x86 – Logern Oct 23 '18 at 17:26
• you should include the extern in the answer title, since the program requires it and it is not available on all platforms. – qwr Oct 23 '18 at 20:07
• the "mov rdi,2" can be "push 2/pop rdi" for -2 bytes. Note also that the disassembly is wrong or the code is wrong. It's either "mov edi" (not rdi) or there's a prefix missing. – peter ferrie Oct 26 '18 at 18:42

Java (JDK), 63 bytes

s->("."+s).matches("(\\.(25[0-5]|(2[0-4]|1\\d|[1-9])?\\d)){4}")


Try it online!

Credits

• -1 byte thanks to Kevin Cruijssen
• l4m2 for showing the previously-failing case .1.1.1.1.
• You forgot to remove the trailing semi-colon. ;) And I can verify it works for all test cases, including those in the comments. Will see if I see some things to golf. – Kevin Cruijssen Oct 22 '18 at 10:00
• Failed on .1.2.3.4 – l4m2 Oct 22 '18 at 10:01
• Is it allowed to use boolean when explictly require 0/1? – l4m2 Oct 22 '18 at 10:18
• @l4m2 The original question had Valid/Invalid. So I assume any truthy/falsey value is acceptable here. – Kevin Cruijssen Oct 22 '18 at 10:20
• Output: 0 or 1 and Java has no auto bool->int – l4m2 Oct 22 '18 at 10:21

JavaScript (Node.js), 43 bytes

x=>x.split..map(t=>[t&255]==t&&[])==,,,


Try it online!

JavaScript (Node.js), 46 bytes

x=>x.split..every(t=>k--&&[t&255]==t,k=4)*!k


Try it online!

used Arnauld's part

JavaScript (Node.js), 5453 51 bytes

x=>x.split..every(t=>k--*0+t<256&[~~t]==t,k=4)*!k


Try it online!

-2B for 0+t<256, -1B from Patrick Stephansen, +1B to avoid input 1.1.1.1e-80

RegExp solution 5854 bytes

s=>/^((2(?!5?[6-9])|1|(?!0\d))\d\d?\.?\b){4}$/.test(s)  Thank Deadcode for 3 bytes • I have added some test cases! – rv7 Oct 22 '18 at 6:22 • This gives truthy for 0.0.0.0. Everything else seems to work fine. – Kevin Cruijssen Oct 22 '18 at 9:35 • @KevinCruijssen 0.0.0.0 is here true one. Just why SQL injection is here? – l4m2 Oct 22 '18 at 9:37 • Ah wait, I misinterpret the sentence in the challenge description. 0.0.0.0 is indeed truthy. That will golf my answer as well.. (And what do you mean by SQL injection? :S The link is to TIO with ALL test cases.) – Kevin Cruijssen Oct 22 '18 at 9:40 • @l4m2 I added it since we need some testcases that even not looks like an IP address. – tsh Oct 22 '18 at 9:45 PHP, 39 36 bytes <?=+!!filter_var($argv[1],275,5**9);


Try it online!

275 resembles the constant FILTER_VALIDATE_IP

5**9 is being used instead of the constant FILTER_FLAG_IPV4. This is sufficient, because 5**9 & FILTER_FLAG_IPV4 is truthy, which is exactly what PHP does in the background, as Benoit Esnard pointed out.

Here, filter_var returns the first argument, if it's a valid IPv4 address, or false if it's not. With +!!, we produce the output required by the challenge.

• Using 5**9 instead of 1048576 saves 3 bytes here: PHP uses & to test the IPv4 / IPv6 flags, so any number between 1048576 and 2097151 is valid. – Benoit Esnard Oct 22 '18 at 10:12
• I hereby downvote your answer for being (basically) my answer: codegolf.stackexchange.com/a/174470/14732 which was written at 2018-10-22 09:17:34UTC while yours was written on 2018-10-22 09:21:55UTC. Even if I revert the 1-byte optimization given by @BenoitEsnard, my answer is exactly the same as yours in functionality. – Ismael Miguel Oct 22 '18 at 15:06
• I have to apologise, I didn't see your answer, though at the time I was composing it, there was no submission in PHP on this question (as you said, the time difference is less than five minutes). – oktupol Oct 22 '18 at 15:16
• I know, and I understand it. I only noticed yours just now. I can roll back mine, and you keep the optimization. But I don't know if it makes the answer be different enough from eachother. – Ismael Miguel Oct 22 '18 at 15:33
• @IsmaelMiguel I wouldn't downvote somebody for that if it's plausible yours wasn't there when they started. With a 5 minute difference, not only is it plausible, it's almost certainly the case, which is apparent even without the author saying so himself. – Duncan X Simpson Oct 22 '18 at 17:47

echo(ip2long($argv[1])===false?0:1);  ip2long is a well-known built-in function. • 29 bytes – nwellnhof Oct 22 '18 at 10:53 • This seems to use uncodumented features present in newer versions (I presume it is from PHP7+). Keep in mind that, for PHP 4 and 5, this does accept incomplete IPs. – Ismael Miguel Oct 22 '18 at 15:10 • 27 bytes – Mark Oct 22 '18 at 17:39 • codegolf.meta.stackexchange.com/a/7146/12130 – David Mulder Oct 22 '18 at 18:02 • This will give success if you feed it any integer, such as 1 , 2 , etc. Don't think it should. And also if you feed it something as 100.100.100 – nl-x Oct 24 '18 at 9:52 Perl 6, 2221 20 bytes -1 byte thanks to Phil H. {?/^@(^256)**4%\.$/}


Try it online!

Explanation

{                  }  # Anonymous Block
/               /   # Regex match
^             $# Anchor to start/end @( ) # Interpolate ^256 # range 0..255, # effectively like (0|1|2|...|255) **4 # Repeated four times %\. # Separated by dot ? # Convert match result to Bool  • Man, I need to spend more time figuring out Perl 6's regexes. I had no either the % modifier existed. I wonder if it tries to checks all 256**4 possibilities? – Jo King Oct 22 '18 at 10:57 • Instead of <{^256}> you can just convert the range to an array @(^256) for -1 char TIO. By changing the code block to an array it also gets enormously faster (0.4s instead of >30). – Phil H Oct 25 '18 at 13:37 • @PhilH Cool, thanks. I tried $(^256) but now I realize why this didn't work. – nwellnhof Oct 25 '18 at 15:11

05AB1E, 26242322 23 bytes

'.¡©g4Q₅Ý®å®1šDïþJsJQP


-1 byte thanks to @Emigna.
+1 byte for bugfixing test case 1.1.1.1E1 incorrectly returning a truthy result.

Explanation:

'.¡              '# Split the (implicit) input by "."
©              # Save it in the register (without popping)
g4Q           # Check that there are exactly 4 numbers
₅Ý®å          # Check for each of the numbers that they are in the range [0,255],
# and push the result for each number separated onto the stack
®1šDïþJsJQ    # Check that each number does NOT start with a "0" (excluding 0s itself),
# and that they consist of digits only
P   # Check if all values on the stack are truthy (and output implicitly)

• You should be able to use Ā instead of <d – Emigna Oct 22 '18 at 9:14
• @MagicOctopusUrn I'm afraid it fails for 1.1.1.1E1, 1..1.1.1, 1.1.1.1., 192.00.0.255, and 0.00.10.255. (PS: I've fixed the 1.1.1.1E1 by adding the þ to the join-and-equal check.) – Kevin Cruijssen Oct 22 '18 at 12:32
• Fair enough, figured I missed something. – Magic Octopus Urn Oct 22 '18 at 12:33
• @MagicOctopusUrn The main issue is 05AB1E seeing numbers with leading 0s equal to those without, even as string. Which is why I use the DïþJsJQ check where ï cast it to int to remove leading 0s, and þ only leaves digits removing things like E, -, etc. :) The 1š is for test case 0.00.10.255, since 00010255 and 0010255 would be equal. – Kevin Cruijssen Oct 22 '18 at 12:34
• Yeah I went through the same nonsense, the reversal of all numbers worked pretty well though, except for those cases. Interesting when features beneficial for some problems become almost bug-like for others. – Magic Octopus Urn Oct 22 '18 at 12:35

PowerShell, 5951 49 bytes

-2 bytes, true or false allowed by author

try{"$args"-eq[IPAddress]::Parse($args)}catch{!1}


Test script:

$f = { try{"$args"-eq[IPAddress]::Parse($args)}catch{!1} } @( ,("1.160.10.240" ,$true)
,("192.001.32.47" , $false) ,("1.2.3." ,$false)
,("1.2.3" , $false) ,("0.00.10.255" ,$false)
,("192.168.1.1" , $true) ,("1.2.$.4" , $false) ,("255.160.0.34" ,$true)
,(".1.1.1" , $false) ,("1..1.1.1" ,$false)
,("1.1.1.-0" , $false) ,("1.1.1.+1" ,$false)
,("1 1 1 1" , $false) ,("1" ,$false)
,("10.300.4.0"   ,$false) ,("10.4F.10.99" ,$false)
,("fruit loops"  ,$false) ,("1.2.3.4.5" ,$false)

) | % {
$s,$expected = $_$result = &$f$s
"$($result-eq$expected):$result : $s" }  Output: True: True : 1.160.10.240 True: False : 192.001.32.47 True: False : 1.2.3. True: False : 1.2.3 True: False : 0.00.10.255 True: True : 192.168.1.1 True: False : 1.2.$.4
True: True : 255.160.0.34
True: False : .1.1.1
True: False : 1..1.1.1
True: False : 1.1.1.-0
True: False : 1.1.1.+1
True: False : 1 1 1 1
True: False : 1
True: False : 10.300.4.0
True: False : 10.4F.10.99
True: False : fruit loops
True: False : 1.2.3.4.5


Explanation:

The script tries to parse an argument string, to construct a .NET object, IPAddress.

• return $true if object created and the argument string is equal to a string representation of the object (normalized address by object.toString()) • return $false otherwise

PowerShell, 5956 54 bytes, 'don't use a .NET lib' alternative

-3 bytes, true or false allowed by author

-2 bytes, thanks to @Deadcode for the cool regexp.

".$args"-match'^(\.(2(?!5?[6-9])|1|(?!0\B))\d\d?){4}$'


Try it online!

Thanks @Olivier Grégoire for the original regular expression.

• You shouldn't need to call |% t*g since PowerShell will automatically cast the right-hand-side of -eq as a string, because the left-hand-side is a string. -- try{+("$args"-eq[IPAddress]::Parse($args))}catch{0} – AdmBorkBork Oct 22 '18 at 16:05
• You can carve 2 bytes from the "don't use a .NET lib" version by using my regex (adapted to the insert-a-period trick, which of course can't be in my version because it's a pure regex): tio.run/… – Deadcode Jan 27 at 11:03

C (gcc) / POSIX, 26 bytes

f(s){s=inet_pton(2,s,&s);}


Try it online!

Works as 64-bit code on TIO but probably requires that sizeof(int) == sizeof(char*) on other platforms.

• @TobySpeight Yes, if you're on x86, you should probably try in 32-bit mode (-m32). – nwellnhof Oct 22 '18 at 13:23
• I got it to work, by passing s as a char* (no access to a ILP32 system here), and yes, I was mixing up with inet_aton(). – Toby Speight Oct 22 '18 at 13:26

Python 3: 81787069 66 bytes

['%d.%d.%d.%d'%(*x.to_bytes(4,'big'),)for x in range(16**8)].count


Loop over all possible IPv4 addresses, get the string representation and compare it to the input. It uh... takes a while to run.

EDIT: Removed 3 bytes by switching from full program to anonymous function.

EDIT2: Removed 8 bytes with help from xnor

EDIT3: Removed 1 byte by using an unpacked map instead of list comprehension

EDIT4: Removed 3 bytes by using list comprehension instead of the ipaddress module

• I think your anonymous function can just be [str(ip_address(x))for x in range(256**4)].count. Also, 256**4 can be 16**8. – xnor Oct 22 '18 at 23:45

C# (Visual C# Interactive Compiler), 8479 65 bytes

s=>s.Split('.').Sum(t=>byte.TryParse(t,out var b)&t==b+""?1:5)==4


Try it online!

-5 and -14 bytes saved thanks to @dana!

# C# (Visual C# Interactive Compiler), 61 bytes

s=>s.Count(c=>c==46)==3&IPAddress.TryParse(s,out IPAddress i)


Try it online!

This is a work in progress. The code use System.Net (+17 bytes if you count it). if you wonder why I count and parse:

The limitation with IPAddress.TryParse method is that it verifies if a string could be converted to IP address, thus if it is supplied with a string value like "5", it consider it as "0.0.0.5".

source

As @milk said in comment, it will indeed fail on leading zeroes. So, the 61 bytes one is not working.

• @dana great. Nicely done! Four more and it will beat the 61 bytes solutions! – aloisdg Jan 29 at 17:17

Python 2, 85 82 81 bytes

-1 byte thanks to Kevin Cruijssen

from ipaddress import*
I=input()
except:r=0
print~~r


Try it online!

113 byte answer is deleted as it fails for 1.1.1.1e-80

• You can golf print 1*r to print~~r. +1 though, since it seem to work for all possible test cases suggested thus far. PS: Your 113 byte answer fails for 1.1.1.1e-80. – Kevin Cruijssen Oct 22 '18 at 10:52
• @KevinCruijssen Thanks! Didn't think about such notation of numbers – Dead Possum Oct 22 '18 at 11:11
• Isn't ipaddress a Python 3 module? – Farhan.K Oct 24 '18 at 12:55
• @Farhan.K Dunno, but it works in TIO – Dead Possum Oct 24 '18 at 13:51

Japt, 17 15 bytes

q.
Ê¶4«Uk#ÿòs)Ê


Explanation

We split to an array on ., check that the length of that array is equal to 4 AND that the length when all elements in the range ["0","255"] are removed from it is falsey (0).

                 :Implicit input of string U
q.               :Split on "."
\n               :Reassign resulting array to U
Ê                :Length of U
¶4              :Equals 4?
«             :&&!
Uk           :Remove from U
#ÿ         :  255
ò        :  Range [0,255]
s       :  Convert each to a string
)      :End removal
Ê     :Length of resulting array


PHP 7+, 3735 32 bytes

This uses the builtin function filter_var, to validate that it is an IPv4 address.

For it to work, you need to pass the key i over a GET request.

<?=filter_var($_GET[i],275,5**9);  Will output nothing (for a falsy result) or the IP (for a truthy result), depending on the result. This uses the following values directly: • 275 = FILTER_VALIDATE_IP • 1<<20 = 1048576 = FILTER_FLAG_IPV4 • 5**9 = 1953125 (which has the required bit as "1", for 1048576) Thank you to Benoit Esnard for this tip that saved me 1 byte! Thank you to Titus for reminding me of the changes to the challenge. I've looked into using the function ip2long, but it works with non-complete IP addresses. Non-complete IPv4 addresses are considered invalid in this challenge. If they were allowed, this would be the final code (only for PHP 5.2.10): <?=ip2long($_GET[i]);


Currently, it isn't explicit in the documentation that this will stop working (when passed an incomplete ip) with newer PHP versions.

After testing, confirmed that that was the case.

Thanks to nwellnhof for the tip!

• Using 5**9 instead of 1<<20 saves one byte here: PHP uses & to test the IPv4 / IPv6 flags, so any number between 1048576 and 2097151 is valid. – Benoit Esnard Oct 22 '18 at 10:09
• In newer PHP versions, ip2long doesn't allow incomplete addresses. – nwellnhof Oct 22 '18 at 10:46
• @BenoitEsnard Thank you! I've added it to the answer – Ismael Miguel Oct 22 '18 at 11:50
• @nwellnhof After testing, I confirm that that is the case. However, I don't think it is a good idea to use it, since it isn't explicitly documented. – Ismael Miguel Oct 22 '18 at 11:51
• +!! is not required; the OP now accepts arbitrary truthy values. – Titus Oct 23 '18 at 12:44

Mathematica, 39 31 bytes

Original version:

¬FailureQ[Interpreter["IPAddress"][#]]&


Modified version (thanks to Misha Lavrov)

 AtomQ@*Interpreter["IPAddress"]


which returns True if the input is a valid IP address (try it).

In case you insist on getting 1 and 0 instead, then an additional 7 bytes would be necessary:

Boole/@AtomQ@*Interpreter["IPAddress"]

• Since Interpreter["IPAddress"] returns a string for valid input, and some complicated failure object for invalid input, we can test for valid inputs with AtomQ[Interpreter["IPAddress"][#]]&, which can be further shortened to the function composition AtomQ@*Interpreter["IPAddress"]. Try it online! – Misha Lavrov Oct 22 '18 at 17:45
• Fails on an IPv6 address like 2001:0db8:85a3:0000:0000:8a2e:0370:7334. – lirtosiast Jan 27 at 1:58

JavaScript (ES6), 49 bytes

Returns a Boolean value.

s=>[0,1,2,3].map(i=>s.split.[i]&255).join.==s


Try it online!

Python 2, 938967 53 bytes

[i==int(i)&255for i in input().split('.')]!=[1]*4>_


Try it online!

Thanks to Dennis for shaving another 14 bytes on the internal comparisons and exit code.

Special thanks to Jonathan Allan for shaving 22 bytes & a logic fix! Pesky try/except begone!

Taking properly formatted strings instead of raw bytes shaves off 4 bytes, thanks Jo King.

• Your check can be golfed to i==int(i)&255 . Also, you can force an error with [...]!=[1]*4>_, since you're using exit codes anyway. Try it online! – Dennis Oct 24 '18 at 22:44
• @Dennis I don't understand what >_ does. The bitwise and is quite ingenious though... I was unsuccessful in combining those myself. – TemporalWolf Oct 24 '18 at 22:58
• If the != returns False, Python short-circuits and nothing happens; the interpreter exits normally. If it returns True, >_ raises a NameError, because the variable _ is undefined. – Dennis Oct 24 '18 at 23:00
• Figures I chain comparisons in my answer and then miss the obvious result in your comment. Thanks for the explanation. – TemporalWolf Oct 24 '18 at 23:13

sfk, 176 bytes

* was originally Bash + SFK but TIO has since added a proper SFK wrapper

xex -i "_[lstart][1.3 digits].[1.3 digits].[1.3 digits].[1.3 digits][lend]_[part2]\n[part4]\n[part6]\n[part8]_" +xed _[lstart]0[digit]_999_ +hex +linelen +filt -+1 -+2 +linelen


Try it online!

• Would first checking the error printout from nc [addr] 1 -w1 shorten this? – Rogem Oct 22 '18 at 9:23
• @Rogem nc accepts leading zeroes as well as IPv6 addresses, so I'd still have to handle those - and this is intended more as a sfk answer than a shell answer anyway. – Οurous Oct 22 '18 at 9:30

Python3 Bash* 60

*Also other shells. Any one for which the truthy/falsy test passes on a program exit code

read I
python3 -c "from ipaddress import*;IPv4Address('$I')"  Explanation The trouble with a pure Python solutions is that a program crashing is considered indeterminate. We could use a "lot" of code to convert an exception into a proper truthy/fasly value. However, at some point the Python interpreter handles this uncaught exception and returns a non-zero exit code. For the low-low cost of changing languages to your favourite Unix shell, we can save quite a bit of code! Of course, this is vulnerable to injection attacks... Inputs such as 1.1.1.1'); print('Doing Something Evil are an unmitigated threat! • (Explanation it is (not Explaination).) – Peter Mortensen Oct 25 '18 at 1:43 • @PeterMortensen Yikes. It was even underlined in red. My browser tried to save me, but I wouldn't listen. Thanks for catching that! – Sompom Oct 25 '18 at 14:50 • Full programs are allowed to output via exit codes, therefore this could be 43 bytes. – ბიმო Nov 5 '18 at 16:29 • @BMO Interesting. Thanks for pointing that out! I think the problem definiiton changed from "Truthy/Falsy" to also allowing arbitrary output since I posted this, but I could have just not noticed before :) – Sompom Nov 5 '18 at 16:40 ECMAScript pure regex, 41 bytes ^((2(?!5?[6-9])|1|(?!0\B))\d\d?\.?\b){4}$

I think the logic in this regex speaks for itself, so I will merely pretty-print but not comment it:

^
(
(
2(?!5?[6-9])
|
1
|
(?!0\B)
)
\d\d?
\.?\b
){4}
$ This can be used to shave 2 bytes off the following other answers: Here is an alternative version that allows leading zeros, but does so consistently (octets may be represented by a maximum of 3 decimal digits): ^((2(?!5?[6-9])|1|0?)\d\d?\.?\b){4}$

Or allow any number of leading zeros:

^(0*(2(?!5?[6-9])|1?)\d\d?\.?\b){4}$ • \b and \B... it's smart! – mazzy Jan 27 at 9:57 • @mazzy Yes, those two really come in handy! I could've used (?!0\d) instead, but I like \B better! – Deadcode Jan 27 at 10:05 • The powershell answer doesn't get shorter with your regexp. I'm sorry. Quotes are needed to convert an array to a string. Try it online! – mazzy Jan 27 at 10:35 • The \.?\b saved me a byte on my answer too, thanks! – Neil Jan 27 at 21:34 • Saved 3 bytes thx – l4m2 Jan 28 at 20:35 Red, 106 bytes func[s][if error? try[t: load s][return off]if 4 <> length? t[return off]s = form as-ipv4 t/1 t/2 t/3 t/4]  Try it online! Returnd true or false Explanation: f: func [ s ] [ if error? try [ ; checks if the execution of the next block result in an error t: load s ; loading a string separated by '.' gives a tuple ] [ ; each part of which must be in the range 0..255 return off ; if there's an error, return 'false' ] if 4 <> length? t [ ; if the tuple doesn't have exactly 4 parts return off ; return 'false' ] s = form as-ipv4 t/1 t/2 t/3 t/4 ; is the input equal to its parts converted to an IP adress ]  Stax, 14 bytes ∞n·Θ3ª&JH‼∙*~Γ  Run and debug it Unpacked, ungolfed, and commented, it looks like this. VB constant 256 r [0 .. 255] '|* coerce and string-join with "|"; i.e. "0|1|2|3 ... 254|255" :{ parenthesize to "(0|1|2|3 ... 254|255)" ]4* make 4-length array of number pattern .\.* string join with "\\."; this forms the complete regex |Q is the input a complete match for the regex?  Run this one • Surprised to know that you made the language Stax! it is working well. – rv7 Oct 22 '18 at 17:14 • Thanks! The space of golfing languages is surprisingly crowded, and I'm not sure if stax can justify its own existence on its merits, but my main goal was just to see if I could do it and maybe learn something. It ended up being more fun than expected. – recursive Oct 22 '18 at 17:16 Python 3, 109 93 bytes import re lambda x:bool(re.match(r'^((25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(\.(?!$)|$)){4}$',x))


Explanation

Each octet can be 0 - 255 :

• starts with 25 and having 0-5 as last digit
• start with 2, has 0-4 as second digit and any digit at the end
• starts with 1, and 00 - 99 as rest digits
• has only 2 digits - 1-9 being the first one and any digit thereafter
• or just a single digit

An octet can end with a (.) or just end, with the condition that it cannot do both , the negative lookahead (?!$) takes care of this case Thanks @Zachary for making me realize I can discard spaces (since it is code golf) Thanks @DLosc for the improvements and making me realize my mistake, its been corrected now. • Some explanation for this might help. – Stephen Leppik Oct 22 '18 at 12:04 • x: re.match=>x:re.match; , x => ,x, and ) is => )is should save 3 bytes. Also, in the regex, you can use \d for each occurrence of [0-9], and [1]=>1. This seems like a great first post, though! – Zacharý Oct 22 '18 at 14:08 • [1-9][0-9]|[0-9] can become [1-9]\d|\d (per Zacharý's advice), which can become [1-9]?\d. Also, instead of testing re.match(...)is not None, you can do bool(re.match(...)) since match objects are truthy and None is falsey. :) – DLosc Oct 22 '18 at 18:05 • Hmm. Actually, this fails on the test case 1.2.3.4.5 (and also 1.2.3.4., which isn't in the official list of test cases), because it can match a period instead of end-of-string after the fourth number. – DLosc Oct 22 '18 at 18:23 Bash, 30 bytes ipcalc -c cat;echo$(($?^1))  Try it online! • The echo$(($?)) part is not needed since programs are allowed to output their result via exit code. – ბიმო Nov 5 '18 at 16:35 Charcoal, 45 21 bytes Ｉ∧⁼№θ.³¬Φ⪪θ.¬№Ｅ²⁵⁶Ｉλι  Try it online! Link is to verbose version of code. Edit: Saved 24 bytes by porting @Shaggy's Japt answer. Explanation:  θ Input string № Count occurrences of . Literal . ⁼ Equal to ³ Literal 3 ∧ Logical And ¬ Logical Not θ Input string ⪪ Split on . Literal . Φ Filter by ¬ Logical Not ²⁵⁶ Literal 256 Ｅ Map over implicit range λ Map value Ｉ Cast to string № Count occurrences of ι Filter value Ｉ Cast to string Implicitly print  • Fails for test cases with negative integers like 123.-50.0.12 or 1.1.1.-80. Everything else seems to work fine. So the <256 check should be in [0,255] instead. – Kevin Cruijssen Oct 22 '18 at 9:55 • @KevinCruijssen Actually the code to filter out invalid characters wasn't working because I forgot to change the variable in the inner loop. Should be fixed now. – Neil Oct 22 '18 at 12:21 Retina, 46 44 bytes ^ . ^(\.(25[0-5]|(2[0-4]|1\d|[1-9])?\d)){4}$


Port of @OlivierGrégoire's Java answer, so make sure to upvote him!
-2 bytes thanks to @Neil.

Explanation:

^
.                           # Prepend a dot "." before the (implicit) input
^...$# Check if the entire string matches the following regex # exactly, resulting in 1/0 as truthy/falsey: ( # Open a capture group \. # A dot "." (25[0-5] # Followed by a number in the range [250,255] |(2[0-4]| ) \d) # or by a number in the range [200,249] |( |1\d| ) \d) # or by a number in the range [100,199] |( |[1-9]) \d) # or by a number in the range [10,99] |( )?\d) # or by a number in the range [0,9] ) # Close capture group {4} # This capture group should match 4 times after each other  • My attempt (which I didn't post because the question got put on hold at the time) was the same length, but didn't have the \d group optimisation, so you can save two bytes because you don't need the M specification on the last line. – Neil Oct 23 '18 at 0:41 • I managed to get Retina down to 42 bytes by porting the Perl 6 answer but this answer also works in 0.8.2 which my port doesn't. – Neil Oct 23 '18 at 1:13 Jelly, 11 bytes ⁹ḶṾ€ṗ4j€”.ċ  A monadic link accepting a list of characters which yields $$\1\$$ if it's a valid address and $$\0\$$ otherwise. Builds a list of all $$\256^4=4294967296\$$ addresses and then counts the number of occurrences of the input therein. Here's similar @ Try it online! that uses $$\16\$$ (⁴) rather than $$\256\$$ (⁹), since the method is so inefficient! How? ⁹ḶṾ€ṗ4j€”.ċ - Link: list of characters, S ⁹ - literal 256 Ḷ - lowered range = [0,1,2,...,254,255] Ṿ€ - unevaluate €ach = ['0','1',...,['2','5','4'],['2','5','5']] ṗ4 - 4th Cartesian power = ALL 256^4 lists of 4 of them - (e.g.: ['0',['2','5','5'],'9',['1','0']]) ”. - literal '.' character j€ - join for €ach (e.g. ['0','.','2','5','5','.','9','.','1','0'] = "0.255.9.10") ċ - count occurrences of right (S) in left (that big list)  • Why does the version with 65,536 IPs take 1.8 seconds? o_O – Dennis Oct 24 '18 at 14:41 Retina, 42 41 bytes ~(K 255* ["^(("|'|]")\.?\b){4}$"L$$.


Try it online! Based on a previous version of @nwellnhof's Perl 6 answer, but 1 byte saved by stealing the \.?\b trick from @Deadcode's answer. Explanation:

K


Clear the work area.

255*


Insert 255 characters.

["^(("|'|]")\.?\b){4}$"L$
$.  Generate the range 0..255 separated with |s, prefixed with ^((, and suffixed with )\.?\b){4}$, thus building the regular expression ^((0|1|...255)\.?\b){4}$. ~(  Evaluate that on the original input. Pip, 25 16 bytes a~=X,256RL4J"\."  Takes the candidate IP address as a command-line argument. Try it online! or Verify all test cases Explanation Regex solution, essentially a port of recursive's Stax answer.  a is 1st cmdline arg (implicit) ,256 Range(256), i.e. [0 1 2 ... 255] X To regex: creates a regex that matches any item from that list i.e. essentially (0|1|2|...|255) RL4 Create a list with 4 copies of that regex J"\." Join on this string ~= Regex full-match a against the input  JavaScript, 89 bytes (_,r=(${[...Array(256).keys()].join|}))=>RegExp(^${(r+'\\.').repeat(3)+r}$).test(_)


Try it online!

Create RegExp capture groups from indexes of an array having length 256 for range 0-255 joined with | and followed by escaped . character (^(0|1...|255)\.(0|1...|255)\.(0|1...|255)\.(0|1...|255)$) repeated 3 times closing with joined array followed by $ to match end of string, return true or false result of input passed to RegExp.prototype.test().