IP address: 000 simplifies to 0?

6,377

Solution 1

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://datatracker.ietf.org/doc/html/draft-main-ipaddr-text-rep-02

Solution 2

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).

Solution 3

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.

Solution 4

The other answers do a good job explaining the various representations of IP addresses as text input. But the reason your printer reports its IP as 192.168.000.008 is most likely just lazy programming. When formatting a number into text, it's simpler to assume a fixed number of characters.

Share:
6,377
Kentaro T. Vadney
Author by

Kentaro T. Vadney

I love learning about tech and finance!

Updated on September 18, 2022

Comments

  • Kentaro T. Vadney
    Kentaro T. Vadney almost 2 years

    I was setting up my Ubuntu with brother printer driver and was trying to use my printer's IP to connect my pc to the printer.

    On my printer, the IP address is 192.168.000.008. So I entered this in my settings to connect, but to no avail.

    However, when I entered 192.168.0.8 it worked. I can also connect to localhost:192.168.0.8 to connect to the printer settings server.

    Does this mean that by default, if an IP address has 000 it simplifies to 0? If there are zeros before a number, like 008 will it simplify to 8?

    What are the simplification rules for IP addresses? Are there any others that I am missing? If I am wrong, then why did the simplified 192.168.0.8 work while 192.168.000.008 did not?

    update:

    I was following this tutorial here:https://kbpdfstudio.qoppa.com/install-printer-driver-on-linux/

    when I got to Step7 in the above tutorial, I entered Y (in my default terminal, not web browser @Kamil Maciorowski @T.J. Crowder), and then selected "enter IP address" to connect. I initially didn't include this since I mainly wanted to know what's up with the IP shortening thing. Sorry for this missing information! I had a tough time downloading printer driver for ubuntu so hopefully, this helps out some people!

    Also attached here is the picture of my weird IP @barlop: weird IP on brother display

    • Kamil Maciorowski
      Kamil Maciorowski about 4 years
      "So I entered 192.168.000.008 in my settings to connect, but to no avail." – Where did you enter this exactly?
    • barlop
      barlop about 4 years
      Please include pictures of this very odd looking IP Address
    • Gizmo
      Gizmo about 4 years
      FYI: You can also shorten IP's that have 0's in-between them, 10.0.0.4 is the same as 10.4, try ping 10.4 ;)
    • user1686
      user1686 about 4 years
      @Gizmo: That's another of those features that only exist in BSD inet_aton but won't be accepted by the other half of the world. Official syntax is four 8-bit decimals and nothing else. (This abbreviating goes back to the "classful addressing" era and does a bit more than just omitting middle zeros -- I'm sure there was a great post explaining this somewhere on this site but I can't really find it.)
    • Thorbjørn Ravn Andersen
      Thorbjørn Ravn Andersen about 4 years
      An IPv4 address is just a 32-bit number, which for convenience is taken one byte at a time rendered in decimal. It is the last bit you've hit a snag in.
    • user4556274
      user4556274 about 4 years
      @user1686 in which half of the world will ping 10.4 not ping the address 10.0.0.4 ? I just got the same result on OpenBSD, OSX, and several Linux distributions.
    • MSalters
      MSalters about 4 years
      @Gizmo: It's not that you "drop zeroes", you add 65536 times the second number and 256 times the third number to the 4th. Of course, 65536*0 + 256*0 + 4 = 4.
    • Alexey
      Alexey about 4 years
      The parts of IP address are just numbers. There is no simplification going on. Writing "000" de denote zero or writing "008" to denote eight is uncommon. Usually zero is written as "0", and eight as "8".
    • Davidw
      Davidw about 4 years
      In IPv6, if you have a block of 0000:0000:0000:0000's, (of any length, as long as it's contiguous and not more than one block interrupted by other values) you can condense them down to one :0:, or even a double colon: ::.
    • Zan Lynx
      Zan Lynx about 4 years
      ping 0x08080808 Hehehe
    • eagle275
      eagle275 about 4 years
      You entered string-data but depending on used programming language it is possible that this string is processed step wise to integer - and some languages treat a number in string format with leading zero as base 8 ... and base 8 number cannot contain bigger digits (or octits?) than 7 .. hence the number was illegal and couldn't be processed
    • eagle275
      eagle275 about 4 years
      @user4556274 interesting .. even my windows 7 does this .....
    • Joker_vD
      Joker_vD about 4 years
      @user1686 "Official syntax"? There is no RFC that establishes official syntax for IPv4, funnily enough. Even RFC1123, 2.1, strictly speaking, doesn't outlaw support for octal/hex input, only specifies that decimal numbers SHOULD be possible to enter.
    • phuclv
      phuclv about 4 years
    • Naili
      Naili about 4 years
      @Kentaro - Out of curiousity, what browser were you using with your router's GUI? I have a suspicion why it didn't work typing the leading zeros, but it's browser-specific.
    • Toby Bartels
      Toby Bartels about 4 years
      @eagle275 Also ping 0x7F000001
    • justhalf
      justhalf about 4 years
      I read the question in HNQ and thought, "of course 000 would be 0". Now I learned something new. Thanks question asker (and answerer)!
  • dave_thompson_085
    dave_thompson_085 about 4 years
    011 becomes nine, which is decimal 9; 012 becomes ten, which is decimal 10 but hex A. There was never an RFC for this, but it is in the POSIX standard (via XPG, IIRC) with the more common name inet_addr Compare superuser.com/questions/857603/… and serverfault.com/questions/837450/…
  • user1686
    user1686 about 4 years
    Yes, that's what I get when writing answers while nearly asleep... It might be a POSIX standard for inet_ntoa specifically, but hopefully it is not a standard for the more recent IPv4-related functions (inet_ntop or getaddrinfo) that programs should be using anyway.
  • ljrk
    ljrk about 4 years
    @user1686 It is definitely in the standard: pubs.opengroup.org/onlinepubs/9699919799/functions/… "address strings using Internet standard dot notation as specified in inet_addr are valid", where inet_addr is described alongside inet_ntoa which specifies the shorting rules and that the parts "may be decimal, octal, or hexadecimal"
  • I'm with Monica
    I'm with Monica about 4 years
    I take it that << is the left shift operator? - I believe that the intersection of the set of all persons knowing that operator with the set of all persons having the same question as the OP is very, very small.
  • searchengine27
    searchengine27 about 4 years
    You're probably right. I'll update to explicitly call out what a left shift is.
  • roaima
    roaima about 4 years
    Would still be easier to understand in terms of a multiplication by 256, i.e. for a.b.c.d you would have ((a*256+b)*256+c)*256+d
  • Kaz
    Kaz about 4 years
    When formatting a number into text, it often takes more work to request leading zeros and a fixed width.
  • MooseBoys
    MooseBoys about 4 years
    @Kaz It depends on the language. In JavaScript maybe, sure. In C or other embedded languages likely to be used on a printer, no.
  • searchengine27
    searchengine27 about 4 years
    @roaima So to be clear, you're OK with all the talk about system calls, octals, interpretation of diffferent base numbers, but left shift! you've gone too far! And the way you said it is not simpler. Even the way you wrote out what you're trying to say is simpler isn't the traditional way of doing it, which wouldn't even be ordered in a way that logically makes sense. If you had said 192 * 2 ^ 24 + 168 * 2 ^16 ... then I might be on board with you. But the way you wrote it is just logically not going to get you on the same page with the rest of the web, even if it equates the right answer.
  • roaima
    roaima about 4 years
    Use ^24 + ^16 + ^8 if you prefer, I really don't mind. I just thought that left-shift was a less well known operation
  • Kaz
    Kaz about 4 years
    C: printf("%d.%d.%d.%d", 192, 168, 0, 1) for no leading digits versus versus printf("%03d.%03d.%03d.%03d", 192, 168, 0, 1).
  • searchengine27
    searchengine27 about 4 years
    fyi, N^24 is a drastically different number than N * 2^24. Left shift is less known than elementary school arithmetic, sure. Nobody can argue that. But it's easier to visualize when you know that take the bits represented by N and left shift them the number of bits by Y, and that is your new value. It's harder to arrive at the why of the answer if you just start throwing multiplication together. In fact, even I know the why (i.e.192 * 2 ^ 24 + ... and even I'm having a hard time looking at the ((a*256+b)*256... and trying to figure out how you got there. I just dont buy easier is all
  • pipe
    pipe about 4 years
    The leading zero means octal must be one of the most frustrating and bug-inducing misfeature from the dawn of computer history.
  • MooseBoys
    MooseBoys about 4 years
    @Kaz That assumes you have the stdlib available, which often you do not in embedded contexts. I specifically had a case where linking in sprintf overflowed the chip's 4KiB ROM capacity.
  • Kaz
    Kaz about 4 years
    That could be partly due to the code bloat for supporting features like leading zeros.
  • Kentaro T. Vadney
    Kentaro T. Vadney about 4 years
    I understand << since I learned bit manipulation in a data structures class. This was super interesting. Thank you to everyone! This was my first post and I really didn't expect such an intriguing and deep response.
  • Kentaro T. Vadney
    Kentaro T. Vadney about 4 years
    Thank you for the insightful answer!
  • HiddenWindshield
    HiddenWindshield about 4 years
    @Kaz Assuming a fixed-form input field with leading zeroes would generally reduce the size of embedded code.
  • justhalf
    justhalf about 4 years
    Also, when using ^, make sure to clarifies that it is the exponent operator, not XOR...
  • searchengine27
    searchengine27 about 4 years
    I'll update to disambiguate the ^ though. EDIT: oh wait, I never put the ^ in my answer, brain fart.