HNHacker News
TopNewBestAskShowJobs

hddqsb

421 karma · joined September 6, 2017

submissionscomments
hddqsb··on The equinox is not when day and night have equal lengths
> I find it more satisfying and clearer to say it's when day/night are the same length everywhere on earth/for everyone on earth.

...except at the poles! (There the sun will appear to be moving along the horizon, and there is no day/night in the usual sense.)

And when you take the pedantry into account (top vs centre of sun, refraction) the length of the day/night is no longer the same around the globe, since the effect in terms of time is different at different latitudes.

hddqsb··on What if OpenDocument used SQLite? (2014)
The article assumes the caller compresses the blobs.
hddqsb··on What if OpenDocument used SQLite? (2014)
> mtimes can definitely be edited, if you have permission

It just requires you to be the owner of the file (https://serverfault.com/a/337810), no special permissions. On the other hand, editing the ctime is not easy -- it requires tricks (e.g. change the computer clock, which typically requires root privileges).

hddqsb··on What if OpenDocument used SQLite? (2014)
On Linux, the mtime ("modification time") is indeed automatically updated when the content is changed, but it can also be set arbitrarily from userspace (e.g. using `touch`) without special permissions. This is very useful, e.g. when you mirror a directory you'll typically want to preserve the mtimes, to help identify changes later.

Linux also has a ctime ("status change time"), which is automatically updated when the content or metadata (inode) are changed. It is not possible to change from userspace (you have to use tricks such as changing the computer clock or directly modifying the disk). This gives you the security benefits, but it is not commonly used e.g. in backup tools, precisely because they want to be able to set "fake" timestamps.

hddqsb··on In a Git repository, where do your files live?
Edit: To allow the corrupted object to be pruned, you should also run `git reflog expire --all --stale-fix`.
hddqsb··on My favourite API is a zipfile on the European Central Bank's website
Very good point!

If you don't mind saving the file to disk, you can do:

  sqlite3 -newline '' ':memory:' "SELECT data FROM zipfile('eurofxref-hist.zip')" \
  | sqlite3 -csv ':memory:' '.import /dev/stdin stdin' \
    "select ...;"
Doing this without a temporary file is tricky; for example `readfile('/dev/stdin')` doesn't work because SQLite tries to use seek(). Here is a super ugly method (using xxd to convert the zipfile to hex, to include it as a string literal in the SQL query):

  curl -s https://www.ecb.europa.eu/stats/eurofxref/eurofxref-hist.zip \
  | { printf "SELECT data FROM zipfile(x'"; xxd -p | tr -d '\n'; printf "')"; } \
  | sqlite3 -newline '' \
  | sqlite3 -csv ':memory:' '.import /dev/stdin stdin' \
    "select ...;"
hddqsb··on My favourite API is a zipfile on the European Central Bank's website
Per the docs (I linked them in another comment), the correct command is `gunzip <foo.zip` or `gunzip -S .zip foo.zip`.
hddqsb··on My favourite API is a zipfile on the European Central Bank's website
GNU gzip has limited support for ZIP:

> Files created by zip can be uncompressed by gzip only if they have a single member compressed with the “deflation” method. This feature is only intended to help conversion of tar.zip files to the tar.gz format.

-- https://www.gnu.org/software/gzip/manual/html_node/Overview....

hddqsb··on Don’t mess with a genius (2010)
You should use "/" instead of "-" in your equations. If you have two objects of the same density but with different sizes, the ratio of their (apparent) weights will be the same in air and in water, but the difference will be different!
hddqsb··on I built Excel for Uber and they ditched it
Tangential, but regarding footnote 7 (efficiently recomputing cells, assuming no cycles), the correct algorithm for determining the order is topological sorting (https://en.wikipedia.org/wiki/Topological_sorting). Using a breadth-first search gives a good approximation in many cases, but there are pathological cases where it can produce an inefficient order.

> Uber Sheets

Hee hee, this name is funny on a number of levels :)

hddqsb··on In a Git repository, where do your files live?
I'd first check whether `git fsck` gives you more information.

There isn't a simple and fast way to find parent objects, but here is a slow hack:

    git_find_references() {
        if [ "$#" -ne 1 ] || [ "${1#-}" != "$1" ]; then
            echo "usage: git_find_references <HASH>" >&2; return 1
        fi
        local target="$1"
        git cat-file --batch-check --batch-all-objects --unordered |
            while read -r hash type size; do
                if [ "$type" != "blob" ] && git cat-file -p "$hash" | grep -F -q "$target"; then
                    printf "%s %s\n" "$hash" "$type"
                fi
            done
    }

    # example:
    git_find_references 1cae71a9d5b24991c0d632b45186ca8a250e5d52
This will output the hashes and types of the objects that refer to the target. (The command is similar to the one posted by @Denvercoder9, but is slightly more sophisticated.)

Note that this function will be very slow on large repositories. I can't think of a way to make it faster without writing actual code. (My only tip is that you can search for multiple targets at once by changing the grep command to `grep -E -q "$target"` and then using `git_find_references "HASH1|HASH2|HASH3"`.)

Once you find the referring objects, you can use `git cat-file -p <hash>` on them to see their content, and you can repeatedly invoke this function to walk up a directory tree until you get to the enclosing commit.

---

To actually fix the corruption, you have a couple of options:

- If the corruption is in a branch that you don't care about, just delete the branch.

- Find a good copy of the object, e.g. from another repository (you said the object did not appear, but I just want to point out that you should check using `git cat-file -p <hash>` rather than by looking in .git/objects/, because objects can also be stored in packs). Or you might be able to work out what the content was (if the corrupt object is a blob, aka file, you might be able to work out the content based on the previous and next versions of that file; `git hash-object <file>` will tell you if it's exactly right, but won't give you any hints if it's slightly wrong).

- Rewrite the history to remove/replace the corrupt object. You can use a tool such as `git-filter-repo` (docs: https://htmlpreview.github.io/?https://github.com/newren/git..., in particular see --strip-blobs-with-ids). You can also use `git replace` to temporarily replace the corrupt object with a placeholder; it won't fix the commit history, but it might be useful if the corruption causes commands to fail.

hddqsb··on Don’t mess with a genius (2010)
Sure! (My explanation is basically equivalent to the combined explanations by @mafuy and @malcolp, but I'll post it anyway.)

The idea is to balance a scale with the crown on one side and an equal mass of gold on the other side (no water yet), and then submerge the entire scale in water. Now there will still be the same mass on each side, but there will additionally be a buoyancy force on each side proportional to its volume. So if the volume of the crown is different from the volume of the reference gold, the buoyancy forces will be different and the scale will tip.

hddqsb··on Don’t mess with a genius (2010)
Wikipedia has a good paragraph on this. It describes a very cool alternative method that has higher accuracy, and according to Galileo it's probable that Archimedes used this method:

> The story of the golden crown does not appear anywhere in Archimedes' known works. The practicality of the method described has been called into question due to the extreme accuracy that would be required to measure water displacement. Archimedes may have instead sought a solution that applied the hydrostatics principle known as Archimedes' principle, found in his treatise On Floating Bodies: a body immersed in a fluid experiences a buoyant force equal to the weight of the fluid it displaces.[34] Using this principle, it would have been possible to compare the density of the crown to that of pure gold by balancing it on a scale with a pure gold reference sample of the same weight, then immersing the apparatus in water. The difference in density between the two samples would cause the scale to tip accordingly.[12] Galileo Galilei, who invented a hydrostatic balance in 1586 inspired by Archimedes' work, considered it "probable that this method is the same that Archimedes followed, since, besides being very accurate, it is based on demonstrations found by Archimedes himself."

-- https://en.wikipedia.org/wiki/Archimedes#Archimedes'_princip...

hddqsb··on How to build a IP geolocation database from scratch?
Google certainly uses its geolocation DB, but it also learns based on map browsing patterns.

To clarify, the scenario I described is as follows: 1. Initially, when I open Google Maps in a clean browser it defaults to my real location. 2. I repeatedly browse some other location. 3. When I open Google Maps in a clean browser, it defaults to that other location. The only reason for Google Maps to pick that other location is my map browsing.

hddqsb··on How to build a IP geolocation database from scratch?
Somewhat relevant: Google Maps can learn the location of your IP based on which locations you browse in the map. If you browse a specific location enough times, it will use that as the default location when you open Google Maps, even if you clear all cookies. (I discovered this just from using Google Maps, and I'm a little concerned by the privacy implications, considering that multiple people may share an IP address.)
hddqsb··on What is wrong with TOML? (2019)
I can relate. But after using JSON for a while (in files that I edit by hand), I found that I really want comments and trailing commas (which leads to https://nigeltao.github.io/blog/2021/json-with-commas-commen...). Next I'd probably want multiline strings (leading to https://github.com/json5/json5).

But if you use those extensions, all your tooling breaks.

(Aside: I think the real bike-shedding would start when you want to add some syntax for raw string literals, e.g. heredocs; it's one of those features that feels redundant, until the day when you really need it and you can't bear the pain of repeatedly escaping and unescaping.)

hddqsb··on What is wrong with TOML? (2019)
The inline table syntax is awesome! Details:

https://github.com/toml-lang/toml/blob/main/toml.md#inline-t...

https://github.com/toml-lang/toml/pull/235

https://github.com/toml-lang/toml/issues/516

hddqsb··on How large is that number in the Law of Large Numbers?
There are a couple of confusions/ambiguities here.

The Law of Large Numbers is about the average, so it's not relevant here (an average of +1 would mean you got heads every single time, which is extremely unlikely for large n).

If you are looking at the sum, then the value depends on whether the number of trials (n) is even or odd. If n is odd, you would indeed get two peaks at 1 and -1, and you would never get exactly 0. If n is even, you would get a peak at 0 and you would never get exactly 1 or -1.

The expected value (aka average) is a number, not a distribution. The expected value for the sum is 0 even when n is odd and you can't get exactly 0 -- that's just how the expected value works (in the same way that the "expected value" for the number of children in a family can be 2.5 even though a family can't have half a child). If you look at the probability density function for a single trial, then it does have two peaks at 1 and -1 (and is zero everywhere else).

The curve you refer to might be the normal approximation (https://en.wikipedia.org/wiki/Binomial_distribution#Normal_a...). It's true that the normal approximation for the distribution of the sum in your gambling game has a peak at 0 even when n is odd and the sum can't be exactly 0. That's because the normal approximation is a continuous approximation and it doesn't capture the discrete nature of the underlying distribution.

hddqsb··on Visual Studio Code adds port forwarding
The answer is almost certainly "abuse". Traffic is routed through a "service hosted in Azure" (probably not GitHub specifically). They're just using GitHub sign-in to apply per-user limits etc.
hddqsb··on Undocumented Features of GitHub
I'll add: Press ? to view the keyboard shortcuts.

> Press I in a PR to hide comments.

Thank you! Comments can make it impossible to read the diff. And considering that by default anyone can post comments anywhere, this can be a serious issue. The other tips weren't that useful for me, but this one is a true gem (and is fairly well hidden -- no UI and hard to find in the docs; however when I pressed "?" it was listed in the keyboard shortcuts, which is actually how I discovered "?").

hddqsb··on Visual Studio Code adds port forwarding
It applies only to VS Code.
hddqsb··on How does Linux NAT a ping?
To save others some reading:

This trick (ping 3.3.3.3) is used to let a server behind NAT learn the IP address of a client that is also behind NAT, without requiring any non-NAT server (such as https://ifconfig.co).

The main action of this tool is to then create a UDP tunnel between the client and server.

But based on quick reading, the tool appears to assume that the NAT does not rewrite the UDP source port, so it won't work on all routers. STUN (which is used in e.g. WebRTC) implements more sophisticated techniques, and even then there are some cases where it cannot work and the only option is to use a relay (TURN).

I'm pretty sure that the same issue applies to the ping 3.3.3.3 trick -- if the NAT rewrites the ping identifier (as described in the article), the trick would break.

hddqsb··on Vale.sh – A Linter for Prose
The built-in rules only include spelling according to the docs: https://vale.sh/docs/topics/styles/#built-in-style
hddqsb··on The ideal viewport doesn't exist
Here you go:

https://i.imgur.com/9cJ13ue.png (alternative link: https://imgur.com/a/uBG5KUD)

(The area of each circle is proportional to the count, clamped to a minimum value. Axes a are linear.)

Uses the data from https://viewports.fyi/data.csv.

Code:

    import csv
    from math import sqrt
    import sys

    csv_reader = csv.reader(sys.stdin)
    headings = next(csv_reader)
    data = [tuple(map(int, row[:3])) for row in csv_reader]
    max_w = 7100 # max(row[0] for row in data) + fudge
    max_h = 7100 # max(row[1] for row in data) + fudge
    max_count = max(row[2] for row in data)

    margin = 200
    svg_width = max_w + 2*margin
    svg_height = max_h + 2*margin
    max_r = 90
    min_r = 4

    print('<?xml version="1.0"?>')
    print(f'<svg xmlns="http://www.w3.org/2000/svg" width="{svg_width}" height="{svg_height}" viewBox="{-margin} {-margin} {svg_width} {svg_height}">')
    print('<desc>Visualization of viewport sizes from https://viewports.fyi/</desc>')
    print(f'<rect x="{-margin}" y="{-margin}" width="{svg_width}" height="{svg_height}" fill="white"/>')

    print(f'<line x1="0" y1="0" x2="{max_w}" y2="0" stroke="black"/>')
    print(f'<line x1="0" y1="0" x2="0" y2="{max_h}" stroke="black"/>')
    for i in range(0, max_w, 200):
        print(f'<text font-size="64" font-family="sans-serif" x="{i}" y="-30" text-anchor="middle">{i}</text>')
        print(f'<line x1="{i}" y1="0" x2="{i}" y2="-20" stroke="black"/>')
    for i in range(0, max_h, 200):
        print(f'<text font-size="64" font-family="sans-serif" x="-30" y="{i + 20}" text-anchor="end">{i}</text>')
        print(f'<line x1="0" y1="{i}" x2="-20" y2="{i}" stroke="black"/>')

    print('<g fill="blue" stroke="darkblue">')
    for w, h, count in data:
        r = max(min_r, sqrt(count) / sqrt(max_count) * max_r)
        print(f'<circle cx="{w}" cy="{h}" r="{r}"/>')
    print('</g>')
    print('</svg>')
hddqsb··on Ffmprovisr – Making FFmpeg Easier
Yeah, the etymology suggested by the top-level comment is completely wrong. Wikipedia says

> The name of the project is inspired by the MPEG video standards group, together with "FF" for "fast forward"

Corresponding source (Fabrice Bellard himself): https://ffmpeg.org/pipermail/ffmpeg-devel/2006-February/0103...

hddqsb··on Internet search tips
> https://support.google.com/websearch/answer/2466433

> those two searches are exactly the same

Yes, that appears to be a recently-introduced typo -- the archived version from April does have a space: https://web.archive.org/web/20230412181331/https://support.g...

I submitted a feedback comment, hopefully they'll fix the typo.

(For future reference, here is a snapshot of the current version without a space: https://web.archive.org/web/20230722085337/https://support.g...)

hddqsb··on The day I locked everyone out of the company intranet
Or just: rm "~"
hddqsb··on Still Love Telnet
No, in fact telnet is worse because it's not 8-bit clean. See https://news.ycombinator.com/item?id=36179850#36180346 and https://news.ycombinator.com/item?id=36179850#36180923
hddqsb··on Still Love Telnet
If netcat is installed, just use that instead (it's also better for non-telnet protocols). If you don't even have netcat but you do have bash, you can use:

  bash -c 'exec 3<>/dev/tcp/$host/$port; cat >&3 | cat <&3'
(this uses `|` as a trick to run two processes in parallel).
hddqsb··on Still Love Telnet
Nice, thanks for sharing. Not directly related, but since you mentioned s_client, please see my warning regarding its security: https://news.ycombinator.com/item?id=36179850#36186559
← PreviousPage 2 of 8Next →