IP address: 000 simplifies to 0?

Leading zeros are not a standard part of IPv4 address syntax, and there is no single "simplification" rule that applies to all systems. Some will outright reject such addresses, and for good reason. And those which do not, have two ways of interpreting such addresses.

Zero-padded dotted-decimal was somewhat common in earliest IPv4 documents, and these days you'll find various apps and many "embedded" systems (printers, TVs, toasters) which simply give you a fixed-size xxx.xxx.xxx.xxx input field with zero-padding. In those systems, 008 is just decimal 8.

However, on PC operating systems as well as Linux-based devices, many programs use the IPv4 address parser inherited from BSD systems several decades ago, which accepts several variations that are not part of any official syntax.

In this original 4.2BSD inet_aton() function, the individual numbers don't have to be decimal: they could also be specified in octal or hex, just like in C and various other programming languages. If the number starts with 0x then it's in hexadecimal, and if it starts with just a 0 then it's octal. And remember that octal only has digits 0–7, which means 08 is not a valid number (07 is followed by 010).

So you have two different ways to handle addresses with leading zeros, and they can result in completely different values. For example, if you enter 011, that means 11 on systems which think it's zero-padded decimal, but it becomes 9 on systems which think it's octal.

In conclusion: If the system forces you to enter addresses in this way, you can usually assume it'll just "simplify" the address by removing leading zeros. But in any other situation, do not use leading zeros because they can be interpreted in unpredictable ways.

See also: https://tools.ietf.org/html/draft-main-ipaddr-text-rep-02


You're thinking about an IPv4 address like a String, which is not what it is. In other words, you know that between each . character is typically 3 characters, so you're trying to comply to that. However, it's not a String; it's a 4 byte number. ‭3232235528‬ is a valid way to write the IPv4 address you provided. The . are logical separators between the octets to make it easier for a human being to decipher. By placing them, you're basically representing each octet as a 1 byte number, and putting that in between each . character.

To simplify a tad, what you're typing is (where X << Y is the left shift operator, indicating shift the number X to the left by Y bits):

192 << 24 + 168 << 16 + 0 << 8 + 8 << 0 = 3232235528‬

Now, I'm not saying maybe you're router's web GUI (just as a random example) will take that (some GUI's demand octet separation), but as a fun excercise for you, go to your command line (sh for linux, cmd for windows) and run

ping 2130706433.

That's the equivalent of typing

ping 127.0.0.1

and it is accepted by the ICMP command.

As more bonus facts, it might help you to know the software behind it (since what you do on a computer is written in a programming language if it's not done at the hardware level). Checkout this answer from StackOverflow Why is 08 not a valid integer literal in Java?. This answer explains what some programming languages interpret leading 0s as. C/C++ has this behavior as well. And it might interest you to know that a lot of OS's use are written in C (at the least, *nix is, and by extension OSX).

All that said, I think user1686 has a much more explicit explanation and history (which is probably more useful).


A value like "192.168.0.8" is not an IP address. It is a representation of an IP address. An actual IP address is just a 32-bit integer, such as 3232235528 or 0xC0A80008. But that's a little hard for humans to remember and compare with other IP addresses, so whenever a computer displays such an address to a human, it uses the so-called "dotted decimal" notation. The number is broken up into "octets" (bytes), and each one is represented as an integer. You can confirm this by typing "ping 3232235528" or "ping 0xC0A80008" into a shell.

It's important to realize that each number in the dotted-decimal notation is just that: a number. Mathematically, 8 = 008 = 8.000 = 008.000.

The reason why "ping 192.168.000.008" failed has to do with how ping interpreted the address. I know I said that "8 = 008" above, but to the ping utility, that's not strictly true. Historically, before hexadecimal came along, anyone wanting to do anything involving binary would use an octal representation of the binary number. Early programmers, not realizing what kind of problems this would cause, established the convention that any number written with leading zeroes is an octal number, not a decimal one. For good or ill, ping still respects this notation. The utility saw that the last octet was "008", tried to interpret that as an octal number, failed (because octal numbers only use the digits from 0 to 7), decided that the whole IP address was malformed due to that, and fell back on interpreting it as a host name, which it couldn't find. Your printer doesn't use this notation, and interprets each octet as a decimal number.