08 September 2019

NYC High Line views in contrasting directions

I walked the most recent section of the NYC High Line and noted a striking contrast within the course of a minute. On one side, the reflecting silver and glass of Hudson Yards and parked LIRR trains:

And on the other side, the painted scrollwork of a streetlight overhanging the West Side Highway:

I hope that their contrasts will continue to coexist.

01 September 2019

Increasing cloudiness

I've been a long-time Dropbox user, mostly for making files conveniently movable and accessible to myself and family members across Linux, MacOS, iOS, and (less frequently) Windows platforms. I wanted something based outside my local LAN, so that I could synchronize when away from home. Dropbox's free service seems to be becoming more restrictive, notably in terms of Linux file system support and with regard to numbers of synchronized devices per account. The lowest paid tier provides 2TB of storage, which is far more than the few GB I need for my usage model, where I don't use the cloud storage as a long-term repository for massive amounts of data. Apple's iCloud offers a reasonably-priced package with 200GB, but lacks a native Linux client. So, I looked into other alternatives, and quickly gravitated to a quasi-DIY approach.

I've had good recent experience with DigitalOcean, as I discussed a few months back. It was easy to create another small droplet hosting a snap of Nextcloud and, "viola", I've instantiated my own cloud storage facility, with available clients for all of my platforms and enough storage within a minimal 25GB droplet to satisfy my current usage requirements. Even with a new domain name registration to address it, the additional $5/month droplet cost is fine to satisfy my purposes, and I like having my own control over it.

11 July 2019

People used to pay like that to talk? Really?

The idea of time- and distance- based charges for communications is fast fading into memory, and newer generations may find it as curious or odd as rotary dials. I was recently asked whether it would have been feasible for family members to talk to each other across the Atlantic in the 1950s rather than writing letters, which led me to undertake the little history project graphed above. For many decades, telephone service was available in principle but staggeringly expensive in practice, a precious resource usually reserved for rare, rushed occasions or critical business negotiations. As an illuminating report observes, "In 1930, the cost per minute for a 200 mile call was about 10 times the cost of sending a first class letter." Also in 1930, a 3-minute call between the US and the UK (which would have been routed by radio, as the first telephone cable across the ocean didn't come into service until 1956) would have cost about $450 if expressed in 2019 dollars. Technological advances (and, later, increased competition) pushed the numbers down the logarithmic scale through the years. And, yes, the downward trend continued beyond 1990, eventually approaching zero with Internet telephony, but competitive and complex discount plans make it harder to extract accurate and representative data for later dates. The overall conclusion's clear, though; it's become a lot cheaper to communicate electronically.

A note on sources and data: while I won't attempt to enumerate a full set of bibliographic citations for a blog post, I was impressed to find the Internet Archive's downloadable collection of telephone directories dating back to the early 1900s; thanks, Brooklyn Public Library, for scanning them. Also, thanks to Andrew Odlyzko for his excellent papers and articles on communications history. And, to the US FCC for their 1997 reports discussing communications costs and their evolution over time. And, to the Internet itself, for bringing such sources to my laptop quickly and without need for paper correspondence or physical travel to remote libraries. The numbers as graphed reflect peak-hour ("standard") rates as I found them, with some adjustments like using nearby years based on availability and scaling where lengths of rated calls were different. I applied inflation adjustments using the BLS CPI calculator.

14 June 2019

Puffin love and more

I went on a Mass Audubon trip to far Downeast Maine last weekend - out where the population thins and the cell phones roam to Canadian carriers in New Brunswick - and got to visit the unique and amazing Machias Seal Island which is officially disputed territory between the US and Canada but which Canada administers as a migratory bird sanctuary. (No passport required to visit, interestingly.) Fortunately, the day's weather was perfect; many would-be visitors are disappointed to
find, after booking their spots well in advance, that the conditions aren't suitable for getting out towards the island or to get ashore. I took many close-view pictures of the trademark Atlantic Puffins (who seem affectionate in this view),
as well as other species like Razorbills, Arctic Terns, and Common Murres (as depicted below: I think the Murre looks like an orchestral conductor for the Razorbills below, though I'm clearly anthropomorphizing that...)
Quite the site!

12 June 2019

My birds in the cloud

As I mentioned a few posts ago, I recently embraced my inner geek by building a small site with Python and Django, in a DigitalOcean droplet. The result may be a bit extreme ('ya think?) for its purpose of organizing and displaying a personal collection of bird photographs, but I've been enjoying it as it's been running for a few weeks. I like being able to use the uploader to add new pictures and species into the database and display, and the ability to specify search terms and ordering. Django makes such facilities easy to implement (along with the ever-popular automated species count!) but I'm still working with the challenge of layering multiple search criteria (e.g., month and name) in a way that presents an intuitive UI. I've written up some tech-oriented notes about the site's technology and development for anyone who may be curious, but the photos themselves may have more general interest.

30 April 2019

I've always found the skyline impressive

I was glad to be on the left side of an airplane yesterday looking down at Manhattan, and was pleased and rather surprised to see how much detail I could get in a picture taken through an airplane window. Contrast enhancement definitely helped.

24 April 2019

Cameras like to focus on high contrast images

... and this Black-and-white Warbler could almost be a living test pattern!

21 April 2019

And didn't you need a juvenile eider today? For spring?

I think he seems pleased with himself.

I see you knocking but don't want you in

A few days back, I set up a "droplet" at DigitalOcean to host a Django application that I'd been building, and so I now have a small net-facing Ubuntu VM there. As a security person, I've been, er, interested to see just how interesting my site has quickly become to, er, unexpected visitors. Looking at its first-ever auth.log, it went active at:

Apr 16 15:33:23  systemd-logind[1385]: 
Watching system buttons on /dev/input/event0 (Power Button)

The sshd logged its first preauth disconnect at 15:38:27 (just over 5 minutes later), from an IP address that whois resolved to country code IR. Since I didn't have an associated domain registered at this time, I assume that this was a random address scan.

I started an Apache server about an hour later, at 16:47. Following some of my own testing (and a domain name registration), its first unexpected visit came at 17:40 in the form of a POST from an IP address in St. Petersburg, RU.

I can see that my droplet's sshd and apache have been busy rejecting varied streams of "knocks" since, and am applying best practices of firewalling unneeded ports and disabling passworded access to ssh. Still, I've been surprised at just how quickly and broadly my site was discovered. If more of my prior experience had fallen on the operational response vs. architectural development side of security, maybe I'd be less surprised. Anyway, a valuable learning experience and reminder. Stay safe!

03 April 2019

Partly ludicrous, with gusty winds?

Sunday night through Tuesday...
Rather low confidence in sensible weather across the northeast
during this timeframe due to model solution spread.

I saw the above excerpt in my local National Weather Service forecast discussion this morning. I realize that the word "sensible" has a particular meaning in the context of meterorology, as in something that can be sensed, but couldn't avoid drawing the conclusion that I should instead be more than usually alert for nonsense falling from the sky early next week.

29 March 2019

https redirects: a learning experience

I had maintained an additional blog besides this one, emphasizing aspects of security technology. I hadn't posted there in a while, and decided to consolidate its content here alongside other posts. Since it was a security-oriented blog after all, it had seemed like an obvious Right Thing to set up the options so that it was accessed (or at least accessible) via an https:// url.

I closed the account on the old blog's hosting provider, and wanted to redirect any visitors to a landing page that would inform them of the change and point them at the blog you're now reading. I went to my domain registrar's admin UI, and had no problem setting up such a redirect for the http:// form of the old blog's url. The plot thickened for the https:// form, though. Reasonably enough, you have to have a certificate corresponding to a domain (and, of course, the ability to wield its corresponding private key) in order to deliver valid, authenticated content for that domain via https. And, an https redirect is a (small, but significant) example of such content; if you're relying on the security https is designed to provide, you wouldn't want an attacker without the appropriate key to be able to mislead by redirecting you elsewhere.

I could probably have arranged to get a certificate enabling my domain registrar to issue a valid https redirect to my domain's landing page, but that seemed like a lot of work just to support redirection rather than more comprehensive hosting. It was easier to solve the problem by pointing the domain's name servers to where I'd put the landing page, at a provider that was equipped to serve that page whether accessed via http:// or https://. (Thanks again, FastMail.)

05 March 2019

Ceci n'est pas un hibou

As I've revealed recently, I particularly enjoy occasional opportunities to see and photograph owls. I thought I had one the other day, which looked promising from a distance:

But, no, it was a wooden, lichen-covered non-owl composed of a broken tree branch, despite the convincingly-placed "ears" and "tail feathers". Tempting sight, though.

30 January 2019

MD5: nice to see you here, old friend!

I recently assembled a new desktop computer system. In the course of moving my data to it from its predecessor, I managed to corrupt the database that my photo organizer (Shotwell) uses to manage my photo collection. I rebuilt a new database from the photos themselves, but this lost metadata like comments and edits that I'd applied. I hoped, though, that I'd be able to recover that information later from the older versions of the database tables. I managed to do this, thanks in part to one, er, key element in the database structure.

In Shotwell's database, each photo has a row in the PhotoTable, with many columns containing information about it. There's a unique ID for each photo, but the IDs generated as photos were imported into the earlier database couldn't be assumed to be the same as when I reimported them into the new database. It would clearly be a Bad Thing to apply the tags for photo #457 in the old database to photo #457 in the new database. What to do?

Looking at the PhotoTable columns, I noticed that each photo had an entry for an MD5 hash of the image. Hash functions are great and useful things. It's unlikely (and, I mean, highly, probabilistically, unlikely) that I'm going to encounter two different images in my collection that yield the same MD5 value. (Even though MD5 isn't recommended today for security-relevant applications, it's still doing its job here in distinguishing among image files that came out of my cameras, which haven't generally acted as hostile attackers.) I expect that Shotwell's code uses the stored MD5 as a quick and effective means to determine whether or not a photo has already been imported into its database. When I saw the MD5 column in the table, I realized that it also provided me with a means to find the correspondence between photo entries and their IDs in the old table with their entries in the new table. Thusly armed, SQL of this form followed:

REPLACE INTO PhotoTable ( named-columns )
SELECT named-columns
FROM old-PhotoTable src
INNER JOIN PhotoTable dest ON src.md5 == dest.md5

which took less than a second to replace corresponding metadata into a table representing about 23,000 photos. I restarted Shotwell with the resulting table, and found my edits accurately restored. I was pleased to have been able to accomplish this. I was glad to have been using an open source organizer with an accessible and documented database representation, and emerged with refreshed respect for the power and value of hash functions.

29 January 2019

I thought it was a nice owl

There are things worth getting outdoors to see, even in winter, and I thought this screech owl last week was a good example. And, it's been a while since I've posted a picture here, so here one is. If you're viewing, thanks, you're welcome.

This and many more collected bird images can be found here, now augmented with improved site navigation capabilities. Ah, projects!

13 January 2019

Cold Days for Code Monkeying

I've taken and enjoyed a number of online courses in technical topics like programming and web technology, such as this example which I'm doing now. For no cost or a nominal fee, MOOCs often offer valuable means to refresh and update skills, providing opportunities to pursue engaging projects and inspiration for others. There's nothing like the satisfaction of building something and making it work. And, there's no better season for such indoor activities than wind-chilly winter days, so I've been doing that lately. Having been through this experience a number of times now, I find that the usual (or at least my usual) flow tends to fall into a sequence of four phases:
  1. The "how will I ever assemble this project" phase, associated with pondering, hesitation, and sometimes procrastination.
  2. The "OK, I'll get started" phase, setting up prerequisites and frameworks and assembling components to the reassuring point where a basic code skeleton operates.
  3. The "Check the boxes" phase, where I go through the project requirements and add support for them one or a few at a time. This usually breaks down nicely into a series of coding and testing sessions, each of which adds a few features.
  4. The "Cleanup and Embellish" phase, where I get rid of false starts accumulated during the prior phases and customize the overall result to add features that seem intriguing or add further capabilities.
After these steps, I'll submit the code, but it's not as if its grading is a primary goal. The point is the learning, and the enjoyment of the process that gets there.

07 January 2019

Making coffee: unit conversions in everyday life

We replaced our coffee grinder and coffee maker. This fact wouldn't ordinarily be blog-worthy; we've generally found these everyday appliances to have a useful life of a few years, after which point they don't seem to work as well. This replacement round brought a small puzzle and lesson, though. Our prior grinder had a dial setting, numbered in "cups", corresponding to the intended number of cups of coffee which a grinding cycle was intended to serve. I put "cups" in quotes, because it was intended to align with a corresponding measure on the same manufacturer's coffeemaker. I'd taken to calling them Arbitrary Coffee Units, or ACUs. I think that those "cups" may have been 6 ounces each, though our new coffeemaker designates its "cups" as 5 ounces. Clearly, either of those is smaller than the 8 ounces in a standard, measuring, unquoted cup.

But, our new grinder doesn't have a numbered dial. Perhaps to embrace coffee purists, other minimalists, or perhaps to avoid the cost of a timer mechanism, it just has an on-off switch. You put as much whole-bean coffee into the hopper as you need, and grind until it's done and ground. You wouldn't want to grind more, as the excess would go stale quickly. But how much whole-bean coffee do you need to brew a pot? One recommendation urged a large number of tablespoons of ground coffee, which seemed messy and inconvenient and still wouldn't answer the question of how many beans to process in order to obtain that ground result. A friend suggested their practice of weighing 66 grams of coffee to fuel their 8-cup coffeemaker - and, no, I'm not sure how large its cups are - but we didn't have a suitably precise kitchen scale and didn't want to add something else to the counter. I converted weight to volume by weighing a measuring cup with and without coffee beans on a postal scale set to metric, and found that an (8-ounce) cup of the coffee beans that I tested weighed about 72 grams, not too far off. In our kitchen for the moment, therefore, we grind a loosely-filled measuring cup of beans to yield 8 of our current ACUs and are enjoying the result.