7 ms·
IPv4 addresses are silly, inet_aton(3) doubly so
- wruza 5y agotl;dr: on some systems, inet_aton uses uint-modulo discard-overflows arithmetic to parse numbers.
- jeffparsons 5y agoI was surprised to see this in the article: $ pi=$(echo "scale=8; 4*a(1)" | bc -l) $ echo $pi 3.14159264 What? How did the last digit end up as '4'? That's no kind of rounding I've ever heard of! So I ran `bc` on my machine and tried: [jeff@prism:~/path]$ bc -l bc 1.07.1 Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006, 2008, 2012-2017 Free Software Foundation, Inc. This is free software with ABSOLUTELY NO WARRANTY. For details type `warranty'. scale=8; 4*a(1) 3.14159264 scale=16; 4*a(1) 3.1415926535897932 I guess you could say "learn bc before using it", but even after a quick skim of the man page, this is not what I would expect.
- saurik 5y agoSo I don't know what a(1) is supposed to represent (and am purposefully not looking it up before thinking about this due to your comment about the man page) but presumably it is pi/4 (as 4 times that is pi). If you take pi/4 and round it to 8 decimal digits of precision you get 0.78539816. If you multiply that by 4 (and round it to 8 decimal digits of precision, though this result already has that precision) you get 3.14159264. I guess you are assuming intermediate results somehow have tons of excess precision? (edit: After writing this I checked the man page and a is apparently arctangent.)
- schoen 5y agoa(1) here is the arctangent of 1. I hadn't thought about when bc does its truncation with the scale variable, but your explanation appears to be exactly right. With scale=8, a(1) returns .78539816, which is already truncated to 8 digits. There is some discussion on intermediate result truncation (not exactly in those terms) in the "EXPRESSIONS" section of the bc(1) man page. It notes that "Every expression has a scale", and elsewhere the man page notes that "All numbers are represented internally in decimal and all computation is done in decimal".
- patrec 5y ago> What? How did the last digit end up as '4'? That's no kind of rounding I've ever heard of! Have you memorized pi to nine significant places, or how did you even notice? BC implements arbitrary precision arithmetic with decimals (try echo 'scale=10000; 4*a(1)' | bc -l and make yourself a cup of coffee), so it's not that surprising that it will give you an incorrect final digit. To guarantee correct rounding of the last displayed digit you need to be able compute to arbitrary precision in the general case, I don't think bc does that and that scale does not just govern number of (trailing) digits displayed but also also precision of computation.
- brongondwana 5y ago> Have you memorized pi to nine significant places, or how did you even notice? Not the OP - but, yes. My memory runs to 3.1415926535 and gets a little fuzzy after that, I think it's 2949 or something without looking... hrm, nope; 8979. Good thing I wasn't sure. Definitely as much as any reasonable human scale thing and then some, but memorising a calculator screen full of Pi isn't that impressive. It used to be written above the stairwell in the maths dept at Uni, so I walked past it multiple times per week for years.
- Sharlin 5y ago> Have you memorized pi to nine significant places, or how did you even notice? At least my "go-to" approximation is 3.141592654 due to the nice descending 654 at the end.
- patrec 5y agoCan you explain how this "go-to approximation" is ever useful to you? I don't understand why anyone would memorize pi to more than 3 digits, other than by accident (such as the sibling, who just saw it on a campus wall countless times). Those 3 digits are good for ~0.05% error, plenty good enough for any mental calculation you might want to do. In any other context you would have pi trivially available as a constant anyway, right?
- Sharlin 5y ago
- gorgoiler 5y agoDotted quads are silly. IPv4 addresses look so much nicer in hexadecimal, though it breaks down when your netmasks are not divisible by 4. Count the number of 0s at the ends of each of these: >>> f('10.0.0.0'). # * '0x0a000000' >>> f('172.16.0.0') '0xac100000' >>> f('192.168.0.0') '0xc0a80000 People whinge about IPv6 not being worth it but two of the things included in its ergonomics are hexadecimal address notation and netmasks that are multiples of 4. And IPv6 addresses are long and unmemorable? Addresses that you actually need to memorise are, in practice, only as long as your routing hierarchy is deep. Your site: 2001:db8:60::/48 Your office LAN: $site:12 Your printer: $site:12::4 * >>> f = lambda q: '0x{:08x}'.format(reduce(int.__or__, (n << i * 8 for n, i in zip(map(int, q.split('.')), reversed(range(4))))))
- RL_Quine 5y agoThey look better in decimal encoding, personally. http://3509828724/ http://3509828724/ If you feel sadistic, it's also legal to use octal encoding. http://0321.0063.0274.0164/ http://0321.0063.0274.0164/
- salzig 5y agoi like to confuse co-workers sometimes by using http://0177.0.0.1 http://0177.0.0.1 for localhost ^^
- sigjuice 5y agoAlso http://0177.1 http://0177.1
- Sharlin 5y agoRust now outright disallows leading zeroes in IPv4 dotted-decimal due to https://cve.report/CVE-2021-29922 https://cve.report/CVE-2021-29922
- colejohnson66 5y agoSo instead of allowing octal addresses (as I assume the spec allows), they outright disable it?
- bvanheu 5y ago> (Looks like somebody picked up this particular example on HackerNews.) Also looks like you are blogging about known stuff: https://isc.sans.edu/forums/diary/Correctly+Validating+IP+Addresses+Why+encoding+matters+for+input+validation/27404/ https://isc.sans.edu/forums/diary/Correctly+Validating+IP+Ad...
- jmiserez 5y agoIt is the same topic, but OPs post goes into much more detail for the integer overflow example and a.b notation.
- shaicoleman 5y agoTool to generate all the permutations of an IP address representations: https://lucb1e.com/randomprojects/php/funnip.php https://lucb1e.com/randomprojects/php/funnip.php
- majke 5y agothere is so much more! https://idea.popcount.org/2019-12-06-addressing/ https://idea.popcount.org/2019-12-06-addressing/ (a) trailing whitespace "1.2.3.4\t5" (b) link-local like %1 or %eth0
- wila 5y agoIf you like this, then you might like earlier discussions about this too. [0][1] I remember seeing a very colorful page (literally) about this around 1997 and it totally blew my mind back then. Sadly I have no idea on how-to locate that page again. [0] https://news.ycombinator.com/item?id=20390759 https://news.ycombinator.com/item?id=20390759 [1] https://news.ycombinator.com/item?id=25545967 https://news.ycombinator.com/item?id=25545967
- maxdamantus 5y agoPersonally, I make use of this all the time. My home network uses the 10.0/8 subnet, so I'll naturally use 10.137 in commands like ping, ssh, curl, ifconfig. Other than web browsers and the `ip` command, virtually everything that I might enter an IP address in seems to support the two- and three-part addresses. I've always thought of the lack in `ip` as a bug [0]; `ip route add default via 10.138` seems to misinterpret the address as 10.138.0.0 (or as I would say, 10.138.0). Note that this is also nice for loopback addresses. Normally the loopback interface owns all addresses in the 127.0/8 subnet, so you can listen on any address from 127.1 to 127.16777214. [0] EDIT: looking into this, it seems that they "fixed" it at some point but then reverted the fix for legacy reasons: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=865992 https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=865992
- notwedtm 5y agoI believe IP does this because it's anticipating a CIDR range of `10.138/16` here.
- secondcoming 5y agoYou may be tempted to replace inet_aton with inet_pton, but for IPv4 inet_pton doesn't support truncated, octal or hex formats.
- mgerdts 5y agoTo get pi, all that Amazon had to do was buy it and the rest of 3.0.0.0/8 from GE. https://news.ycombinator.com/item?id=18407173 https://news.ycombinator.com/item?id=18407173
- numeromancer 5y ago> may be decimal, octal, or hexadecimal, as specified in the C language (i.e., a leading 0x or 0X implies hexadecimal; otherwise, a leading 0 implies octal; otherwise, the number is interpreted as decimal) I really want this convention to die.
- ktpsns 5y agoIt is slowly dying. I see 0o123 as a notation for octal much more frequently then in the past. On the same line with 0b010101. Octal was a thing in the past, but is really seldomly used nowadays, in my impression.