32

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

  • 6
    "So I entered 192.168.000.008 in my settings to connect, but to no avail." – Where did you enter this exactly? – Kamil Maciorowski Jun 1 at 21:55
  • 5
    @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.) – user1686 Jun 2 at 7:18
  • 4
    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. – Thorbjørn Ravn Andersen Jun 2 at 8:08
  • 6
    @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. – user4556274 Jun 2 at 9:00
  • 5
    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". – Alexey Jun 2 at 13:19
91

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

| improve this answer | |
  • 9
    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/… – dave_thompson_085 Jun 2 at 3:16
  • 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. – user1686 Jun 2 at 5:30
  • 2
    @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" – larkey Jun 2 at 8:16
  • 1
    The leading zero means octal must be one of the most frustrating and bug-inducing misfeature from the dawn of computer history. – pipe Jun 4 at 18:16
  • Thank you for the insightful answer! – Kentaro T. Vadney Jun 5 at 0:45
16

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

| improve this answer | |
  • 1
    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. – I'm with Monica Jun 3 at 12:13
  • You're probably right. I'll update to explicitly call out what a left shift is. – searchengine27 Jun 3 at 12:53
  • 1
    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 – roaima Jun 3 at 23:32
  • @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. – searchengine27 Jun 4 at 16:19
  • Use ^24 + ^16 + ^8 if you prefer, I really don't mind. I just thought that left-shift was a less well known operation – roaima Jun 4 at 16:21
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.

| improve this answer | |
2

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.

| improve this answer | |
  • 1
    When formatting a number into text, it often takes more work to request leading zeros and a fixed width. – Kaz Jun 4 at 14:19
  • @Kaz It depends on the language. In JavaScript maybe, sure. In C or other embedded languages likely to be used on a printer, no. – MooseBoys Jun 4 at 15:30
  • 1
    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). – Kaz Jun 4 at 16:53
  • 1
    @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. – MooseBoys Jun 4 at 21:33
  • That could be partly due to the code bloat for supporting features like leading zeros. – Kaz Jun 4 at 22:37

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.