Mon Jun 08 20:45:35 PST numbers separated by a letter?: So, I was changing my account password with an online finance site, and they had many rules for the new password. Most of them made obvious sense ("You can't use your username in the password"). But one of the rules was "You can't have numbers separated by a letter." So "asdf7hjkl" is OK, but "asd6f7hjkl" isn't. Does anyone have any idea why? The only thing I can think of is that they're trying to make it harder to enter hexadecimal values or character escapes into the form. Any ideas?
Mon Jun 15 10:29:34 PST Superman is a Methodist: Here's an interesting page about the canonical religions of several super heroes. It includes a listing of the evidence from canonical media and a discussion of the issues, character details, and reader comments.
I particularly liked this quote from Doug TenNapel (creator of Earthworm Jim):
"Ask any person about what they think about God and you will get an amazing story. It won't just be any old story either, it will likely cut straight to the core of who that person is. It's so bizarre to me that this most personal, dramatic, amazing story device is getting pressure to be removed by story-telling industries... including the supposedly progressive comics industry.
The fact that Superman was born and raised in Kansas by conservative farmers yet he never even talks about the Bible stinks to high hell to me. It's idiotic and it ends up making these characters less human instead of more. Superman has exactly dick to do with any "Smallville" I've ever been to. This is why I actually LOVED the Red Son Superman so much; they finally gave us a contrast of what would happen if Superman didn't carry Kansas in his worldview. More of this! Less of draining worldviews and philosophies out of comics! Especially worldviews that are considered "anti-comic" like certain conservative ones.
It is the pulp nature of comics that makes it such an incredibly powerful medium. I don't think you could get funding to make a Red Son Superman movie with a 250-million-dollar budget, but you could do a limited-run book series to explore a philosophy... no harm done."
Wed Jun 17 01:20:37 PST Jek Porkins == Max Eckhardt from Batman (1989): Maybe everybody else knew this, but William Hootkins, who played Jek Porkins in Star Wars (the heavyset rebel pilot what gets blown up) is also the actor who played Max Eckhardt (the heavyset corrupt cop) in Tim Burton's Batman. I always knew that Eckhardt seemed super familiar, but I could never place him before.
(1) Thu Jun 18 19:14:19 PST Remedial Coding: Never. Assume. Anything.: I have friends who are great programmers, technologists, and scientists because they have a really remarkable clarity of thought and methodicity that translates well into programming. Programming is easy for them because they naturally structure problems the way programs are written. I'm not one of those people. My talents are more intuitive than analytical. I tend to think out loud. But that kind of approach can get you into trouble when you're doing a kernel project with a 20-minute compile-test cycle.
Writing code is like playing Operation. Anyone can do it. (Ok, 4 and up due to the choking hazard.) The question is, how many times are you going to get electrocuted in the process? Core dumps, compilers, stack traces, debuggers and print statements will shock you every time you make a mistake -- just like that buzzer and red light. But eventually, you'll get all the little bones out of the patient -- it just might be ugly along the way.
Anyway, in the past, my "fly by the seat of your pants" approach has made my programming a little like playing Operation while riding in the back of a truck. The process is painful, the end result can really be a mess, and it takes 10 times longer than it should. I try to be halfway methodical, but that just ends up being a waste of time. So, I'm trying to replace these sloppy habits with useful, meaningful structure.
My first hard-earned lesson is this: don't assume anything. You know how they say, "Don't assume, it makes an ass out of you and me?" Well, when you're programming, and you assume things, it only makes an ass out of you. I do this all the time though. I'll be writing some code, and I'll see a function named "does_stuff()" that gets called, and I'll think to myself "Oh, I know what that does." And then I spend an hour debugging my code before I think, "I guess I better figure out what that little function does..." I call these things "grey boxes". They're like black boxes, except less scary. You think you understand them, which gives you a comforting yet false sense of understanding.
I know what you're thinking. You tell me, "But does_stuff() could be doing anything! How can I know what it actually does?" Well, I'd like to remind you that it is a PROGRAM executing on a COMPUTER. Chances are, its behavior is totally deterministic. You could take half a day peppering your code with print statements until it narrates its behavior to you in the Queen's English, or you could take 5 minutes to actually look at the function. You'll probably learn something useful. Yes, sometimes it's not worth going down every rabbit hole until you understand the context surrounding it... but at some point, you will need to know what it's doing. Otherwise, you're betting the correctness of your program on something you assumed to be true. And the more code you write around grey boxes, the harder it will be for you to figure out later. You might even forget that you assumed things to begin with!
Assuming things is more pernicious than simply guessing about what does_stuff() does. It's not just functions that abstract away behavior. Function pointers, the meaning of variables, macros, goto labels, structures, methods -- in short anything that is not explicit or obvious -- could be playing games with your head. Functions snicker at programmers who naively assume things about their behavior. So do yourself a favor. Any time you hear the voice in your head say "I think that does/means X..." take 5 minutes and figure out what it ACTUALLY does. You'll thank yourself later.
Wed Jun 24 10:46:57 PST IT'S NOT A RACE CONDITION: Here's another in an embarrassing series of stupid programming mistakes:
I don't know about you, but I have a bad habit: when I encounter a strange bug in my code and I'm not sure how it could have happened, or it involves some kind of event that happened or didn't happen when I thought it was supposed to, and especially if it involves data corruption, I start thinking it's a race condition. Which, of course reminds me of a certain House, M.D. meme.
It COULD be a race condition. It's possible. Especially if I'm testing on a multi-core machine. (And these days, aren't they all?) It's also more likely to be a race if it locks the machine, or if it's unpredictable. But every time -- every single time -- I have thought that an elusive bug was a race condition, it wasn't. It was an ordinary, mundane, bone-headed move on my part.
Allow me to digress for a moment. In religious circles, you hear people talk about "sins of commission" versus "sins of omission." In the former, it's something you've done, such as stealing, murdering, or coveting your neighbor's gorgeous donkey. Sins of omission are the things you haven't done, but should have, such as failing to honor your father and mother or not loving your neighbor as much as you love yourself. It's easier to recognize the wrong things we do than to recognize the right things we fail to do. It's similar in programming. Most mundane bugs are "wrong things we do" -- erroneous code we wrote into the program. Most race conditions (in my experience) are the result of necessary things we failed to put into the program (locking and/or synchronization).
It's fundamentally hard to pore over your own work to find mistakes. You kind of have to pretend you didn't write it -- or assume that it's wrong -- because if you'd known it was broken, you wouldn't have written it that way to begin with. It can also be hard to swallow your pride and admit that your work is also the most likely source of error. Subconsciously choosing to assume that the problem is a race somehow saves face (even while it dooms you to hours of adding specious locks and fruitless poking around).
In my experience at least, you're only fooling yourself. Next time, unless you're absolutely positive it's a race -- assume that it's not, and start looking for assumptions you made in your own code. Maybe you calculated that pointer incorrectly. Or maybe your loop is exiting earlier than it should. That innocuous helper function that you skimmed may be stabbing you in the back.
(3) Thu Jun 25 13:21:45 PST Highway Throbbery: I've always wanted to get the old-timey Netscape "N" throbber working in Firefox, just for some of that retro feel. I found an old copy of the "N" throbber in my files and updated it for use with Firefox.
Here are some instructions for changing your throbber.
And here is an archive with the necessary files for that 90s feel. (Soul Asylum MP3s not included.)
The original throbber was 16 colors (EGA) and 30x30, but Firefox uses 16x16, 20x20, and 24x24 throbbers. Scaling the old dithered throbber looked awful, so I converted the GIF up to RGB, replaced the dithering with a solid color and made resized versions. However, the original GIF had an EGA palette, so converting the resized GIFs looked awful -- what I needed were more shades of the colors used in the image. With a limited palette, I could get several shades of each color within the 8-bit limit (DOOM used a similar trick). So, I stretched and blurred the RGB image and converted it back to 8-bit to make a reasonable indexed colormap (here are my source files). Then, I applied that map to my resized GIFs. Now you can party like its 1995!
Fri Jun 26 09:54:17 PST Throbbing You Blind: So, I couldn't leave well enough alone. I was also too burned out on work to make progress, so I went back and revisited the N throbber, using the simpler technique (shrink at RGB, then index colors), and also added an alpha channel. I think it looks a lot better.
But I couldn't stop there -- I did what I probably should have done first -- I made a throbbing "F" for Firefox in the style of the N throbber. See yesterday's post for instructions to install it.
Sat Jun 27 20:35:14 PST Abstraction -- Friend or Foe?: Abstraction is one of the pillars of software and systems engineering. It allows designers and developers to worry about their own specific problem (e.g., writing application A) without having to understand all the details of the system. It's almost impossible to imagine building a complicated system like an operating system or local area network without relying on abstraction to make the problem manageable. In the CS world, you're taught that abstraction, not dogs, are Man's best friend.
But abstraction comes at a cost. It can be less efficient, of course; the abstraction gives flexibility, at the cost of cycles or memory. These days, most of us are willing to pay an efficiency cost if it means for quicker development time, etc. But most people don't think about the inherent security cost of using abstractions.
Abstraction is powerful specifically because it hides the details of one system from another system, exposing only an interface. But, the devil is in the details as usual. Using an abstraction means trusting the abstraction to have whatever properties are important to you, including security properties like confidentiality and authenticity. I could provide a messaging abstraction for you that I advertise to be secure, but in reality isn't. Depending on the kind of application, you might not have any control over the abstraction or even ability to verify my claims. You might not even have a choice about the abstraction to begin with.
Consider the typical networking stack for LANs. Your network application relies on all the abstraction in your app (libraries), and every abstraction underneath it -- network layer, transport layer, etc. ARP Poisoning attacks attack the ARP resolution of Ethernet, which affects your machine's ability to communicate to the Internet. In essence, it's trivial to use ARP Poisoning to sniff portions of a LAN, or perform data modification, even on switched networks. There are very few common methods to deal with the possibility of ARP Poisoning on your average corporate network, so you just have to live with the fact that it's vulnerable.
But if Internet traffic is vulnerable, then so is DNS, and from there you're lost. Thanks to abstraction, you're actually helpless to replace those layers in the system. You might be able to replace your application libraries, but you can't easily get rid of ARP.
Tomorrow: Tradeoffs: Maybe Abstraction Is Worth It Anyway...
Unless otherwise noted, all content licensed by Peter A. H. Peterson under a Creative Commons License. |