Monday, December 27, 2010

Where's the "Numerical Recipes in Pseudocode?"

You know the little saw that comes on Swiss Army Knives? It looks awesome and potentially useful; right up to the point that you actually need it. At that point, you realize it's just a toy. Any piece of wood that could actually be sawed with it could easily be snapped with your foot, if not your bare hands, and any piece too substantial won't even be phased. That's exactly what Numerical Recipes in C is. It looks awesome and potentially useful; right up to the point that you actually need it.

I was doing some heavy-duty numerical programming at my last job, so my boss bought me Numerical Recipes in C as a reference. Most of the time I didn't need to use any of the code from the book; I was mostly converting some existing MATLAB code to C. The Numerical Recipes book just kinda sat on my desk, every once in a while I would crack it open and read about a random subject. The chapter about pseudo-random number generators was pretty interesting, but I never really looked to far into the actual code. See, each subject has a few pages of high level explanation followed by a few printed C programs. The explanations were interesting and pretty easy to understand. As I wold find out though, the code was a complete mess.

At some point we needed to add a three dimensional interpolator to our program. My boss and I found a cubic spline interpolator in the book that looked pretty good, so logically he had me use that one instead of bothering a scientist to come up with a new one. It didn't take long for me to figure out that incorporating the Numerical Recipes code wasn't going to be fun. The authors of the book are mathematicians as opposed to programmers, and their coding style definitely shows it. At first glance I noticed that variables aren't given meaningful names; instead they're given two or three letter names that appear random. For their sake I like to assume the names were acronyms for things I've never heard of and weren't mentioned in the book, but the effect is pretty much the same as random. Of course being a hotshot programmer like I like to think I am, I wasn't phased. The next thing I noticed was a cardinal rule of C programming being egregiously violated; the authors used macros to essentially make their own programming language. Memory allocation, deallocation, and basic data types were all defined by macros, and were just different enough from regular C to throw me off. What's worse is that the macros being used were defined in various places throughout the appendix of the book, so about every other line of code required me to search through the appendix to find out what was going on. As if reading source code wasn't already difficult, I now had to keep track of nonsensical variable names, convert their bizarre C-like language to regular C in my head, and constantly flip back and forth between the code and the appendix. Eventually I got all of the code into my program, but the amount of modification I did in the process left my code and their code pretty much unrecognizable from each other. That made debugging really difficult when the code crashed with a weird memory error.

After I spent about an entire work day working through every line of the code, scrapping it and starting over, going through it again and still getting the same memory error, my boss decided to write me a new interpolator in MATLAB himself. I still have no idea what was causing the error. I could have translated the code incorrectly, it could be that I was running the code with a different compiler on a different system, or it could just be a typo in the book. The only thing I know for sure is that if I never see their code again it will be too soon. Anyway, once I got the code from my boss, I translated it into C and got it running in the program in about 45 minutes.

The whole ordeal got me thinking. If I could translate MATLAB code into my C program faster and less error-prone than their botched C code, why did they put the programs in C in the first place? Did they want C programmers to be able to read it? No it can't be that, they went pretty far out of their way to ensure that reading their code was out of the question. Did they use C so that programmers could just copy and pase the code directly into their programs, even without understanding it? Obviously not, the input and output values are non-standard, macro-defined data types, and macros are used egregiously throughout the code. The only way you could copy and paste any of their code and have it run would to also copy and pase an entire appendix of macros and complie them into your entire existing code base (in other words it's out of the question). The only reasonable answer I can come up with is that I'm looking at it all wrong. Mabye I'm simply not the intended audience for this book. Perhaps C programmers working on numerical software were the furthest thing from their mind when the authors were writing a book titled "Numerical Recipes in C." As reasonable as that answer sounds, it raises another, more serious question though. If a C programmer writing numerical software can't get any value out of the book, who can? The explanations in the book are interesting, but not thorough enough to actually be useful to a professional mathematician or programmer, and the code isn't usable in any serious way. You can play around with the preloaded software on their CD, but don't even think about incorporating the code into your software unless you're ready to overhaul your entire code base to accommodate their ridiculous coding conventions. You can attempt to reverse engineer their code like I failed to do, but I'll warn you right now that if your time has any value you're better off getting a mathematician to come up with something from scratch. If you don't have access to any mathematicians, quit your job right now; the only kind of company that would have you write numerical software without any mathematicians on staff is the unsuccessful kind.

With professional programmers and professional mathematicians ruled out, the only possible audience left for this book is non-professionals; reducing the status of this book from tool to toy. Like the swiss army saw before it, it's a toy dressed up as a tool. Moreover, it's a toy that you should, under no circumstances, use as a toy.

Wednesday, December 22, 2010

A Clever Phising Attempt?

There are a couple of hard and fast rules of the interweb I like to teach my less-than-tech-savy family and friends that can keep them out of a lot of trouble. Things like making sure that the website you're typing your e-mail address and password into is the actual website you're logging into. You can't trust the look of the site, you need to look at the URL, especially if you got to the page through a link. Also don't respond to unsolicited messages asking for any kind of account or personal information, even if they look reputable. These are the types of things that phishers catch unsuspecting internet users in all the time, and unfortunately they're very effective. A while ago I received a phishing attempt that was a bit more clever than the standard Prince of Nigeria story, but even those basic rules were plenty to foil it.
XKCD tells it like it is.
Click to enlarge.

I got a phone call from an unknown number, which I naturally let go to voicemail. I later listened to it just in case it was someone actually trying to get a hold of me from some strange phone system; mostly I expected it to be another telemarketer. To my un-amazement it was a computerized voice, just like the majority of the other telemarketers that have called. It claimed to be calling on behalf of Best Buy reminding me that I had some kind of "reward points" that I needed to redeem before they expire, and all I needed to do was go to my reward zone dot com and create an account. Immediately there were red flags, alarm bells, and just about every other cautionary type of signal being emitted from the rational part of my brain; it was obviously a phishing attempt. Here are the red flags my brain threw up as I listened to the message:

First, the computerized voice. There are some legitimate circumstances in which a reputable organization would make an automated call using a computerized voice. For instance, a doctor's office calling to remind you of <your name>'s upcoming appointment on <date and time of appointment>. You see, they could have a computer program working with their appointment database which calls each appointee a couple days before their appointment automatically. Because the <your name> and <date and time of appointment> need to be filled in for each phone call, it would be impossible for a person to prerecord the messages, requiring a computer to read an automatically generated message. Other than circumstances like that though, the computerized voice probably has a more nefarious purpose, like a mass distributed spam message. This certainly wasn't a call from anything like a doctors office, it was supposedly coming from a commercial company which, best case scenario, would be trying to sell me something. Any company worth my time isn't going to have an automated voice call me and try to sell me something, let alone tell me that they would be needing my personal information. And maybe my standards for trust are unreasonably high, but a computerized voice needs to do more than just claim to be calling on behalf of a reputable company for me to start taking orders from it.

Second, the voice claimed to be calling from Best Buy, but I could think of no reason that Best Buy would need to contact me by phone, and I don't even remember giving them my phone number. I hadn't even bought anything at Best Buy in over a year. And why would a reputable company like Best Buy be calling me with a computerized voice? Don't they have employees who speak English and are capable of recording a real-life human voice message, giving the message at least a modicum of credibility? I don't believe for a second that Best Buy is resorting to these kinds of marketing tactics.

Third, the URL that the message gave me didn't even have "Best Buy" anywhere in it. I would expect a phisher to have at least obtained a URL like "bestbuyrewards.com" or something, at least giving the illusion that the website was associated with the actual Best Buy. It was like they weren't even trying.

Some of the common ways to
identify a phishing attempt
Here's what I think happened. A phisher made a website to look like it was a part of Best Buy's website which would ask for some personal information (e-mail, name, address, phone number, maybe even credit card). They got it hosted at my reward zone dot com because it was the most Best Buy sounding URL they could get, even though it wasn't very good. Then they wrote what would appear to be an official message from Best Buy, telling people to go to my reward zone dot com to collect some rewards. They didn't read out loud and record it, that would be too much work. The phisher's voice probably wouldn't sound right, and if he was caught the voice in the message could possibly be traced back to him. So instead, he had a text-to-speech function on the computer do it. Once it was recorded, he paid a black-hat marketing company to play the message to a bunch of phone numbers. All he had to do was wait, and personal information would come rolling in. And if you didn't know, personal information is very valuable to both legitimate and illegitimate internet marketing companies, and even more valuable to people who steal identities.

Out of morbid curiosity I went to the site to see what kind of phishing attempt was going on. Maybe I would take a screenshot and post it to my facebook to warn my less-technical friends about the lame phishing attempt going around.

What I found at the site absolutely disgusted me. I was absolutely shocked and appalled. The site...I can't even say it... The site was actually Best Buy. It was actually Best Buy's reward zone website, and the phone message was legitimately trying to remind me that I had reward points from a laptop I had purchased a while ago. It was worse than the phishing attempt I had expected. Much worse. It was like Best Buy was part of some collusion to legitimize phishing techniques. In the world of mainstream internet usage, there are a few bad habits that get people into a lot of trouble, and it's like Best Buy just validated all of them.

Imagine a unkempt, heavyset, 50 year old man driving an old beat up van. The windows of the van are blacked out, and he's driving through a nice suburban neighborhood where he stands out, and nobody recognizes him. He pulls up to a local park where children are playing...and waits. Some kids are playing hide and seek, and eventually one of the unsuspecting children finds a hiding spot near the van; completely unaware of the man who is intently watching. The man quietly slides the door open and whispers, "psst... hey kid!" The kid looks over quickly, startled to realize that someone is watching him. "I've got some candy over here in my van" the man continues, "do you want some?" "Awesome!" the kid thinks to himself as he starts to walk over, "I love candy!" The man hands him a bag of his favorite candy and says, "Alright, have fun playing hide and seek!" The man drives off, leaving the kid content with his new candy.

That's what Best Buy just did to internet users.

Best Buy is a pedophile-looking old man in a beat up van waiting outside of a park, giving kids candy. I'm trying to be the responsible adult, teaching kids how not to get abducted, and Best Buy just messed it all up.

Friday, December 17, 2010

Basic Maintenance of a Windows Machine

I figured it would be a good idea to start off this blog by answering the questions I'm asked most frequently as professional software developer; namely how to fix <random relative>'s malfunctioning windows machine.  That way instead of answering the same questions over and I can simply use this post as a place to redirect my mentally inferior family members (hi dad!).  That being said, here are the steps I pretty much always take when I'm given a machine to fix.

1. Restart the computer.
How to actually restart the computer.
Hibernate and sleep don't have the same effect.
You'd be amazed what this can fix.  You see, in the course of usage, the operating system is constantly loading and unloading "stuff" from memory, continually causing memory fragmentation and paging.  Basically, the performance of the computer goes down as the amount of usage from last reboot goes up.  Compounding this problem is that modern windows laptops (the only type of computer anyone in my family has), don't exactly encourage you to restart them.  With the default settings, the computer will automatically "turn off" by either sleeping or hibernating, both of which reduce power usage but neither of which actually restart the computer.  The way to do it is simple though; click the windows menu, click the little arrow next to where is says "shut down," then click "restart" from the menu that comes up.

2. Decrease windows starting overhead
The msconfig dialog.  It's ugly but you'll
learn to love it.
If you followed step one and are like most of my family members, you're probably reading step 2 about 20-30 minutes later due to the amount of time it took for the computer to start.  Take a look at the bottom right corner of the screen, right next to where the clock is.  You should see a bunch of icons of programs, click the little arrow next to them to see them all.  You're probably looking at around 20 icons of programs that you didn't even know that you had, and have no idea what they do or why you might need them.  These are all programs that automatically started when the computer started, generally they're "quick loaders" or auto-updaters.  They're generally added to your startup procedure without your knowledge or permission, and they generally don't benefit you in any conceivable way.  The only tangible effect they have is that they increase your boot up time while decreasing your overall performance.  Getting rid of them is a bit more complicated than restarting, but it's still not bad.  Go to the start menu and you should see a text field that says "search."  In it, type "msconfig" and hit enter.  You should get a dialog that is titled "System Configuration."  Click on the tab that says "startup."  You'll see a long list of check-boxes with unintelligible descriptions next to them.  The trick is to uncheck as many of those check-boxes as possible without losing any necessary functionality.  The things that automatically can go are all of the ones with "updater" in the title.  The ones that you probably shouldn't touch are any that refer to hardware, like audio, video, or pointer devices.  Also, if you've got antivirus software that's on the list you should probably keep that too.  Once you've unchecked as much as possible, you'll need to restart the computer again.

Notice how much faster it boots this time.

3. Uninstall unneeded programs
The uninstall programs dialog box.
The list is overwhelming, but stay strong.
This step takes quite a bit longer than the first two, since most people have an absolutely ridiculous amount of unneeded garbage on their computer.  Go to the start menu, click "Uninstall a program" or "add/remove programs," whichever you see.  The list might take a while to populate and the sheer size of it may be intimidating, but hang in there; this step is important.  Go through every single program listed and delete it if it doesn't fit one of these two categories:
  1. It's a program you recognize and know that you need
  2. It looks like it's important for the functionality of the computer
The programs in category one are easy to find because you recognize them.  They'll either be programs that you use frequently (Microsoft Word, Internet Explorer, antivirus software, etc.) or they're programs that you know you need even though you might not use them directly (HP printer software, Adobe Flash Player, Java, etc.).  The programs in category two are a bit harder to determine, but generally they're programs with the publisher listed as "Microsoft Corporation."  Things in this category include Microsoft Visual C++ Redistributable, MSXML SP2, etc.  Other things in this category can include software which is needed for certain hardware, like Nvidia or ATI video software, or Creative audio software.  Everything else can, and should, go.

4. Replace Internet Explorer
I'm not sure who thought toolbars would be useful,
but they were wrong.
If you're like 95% of modern computer users, using a computer is synonymous with using a web browser.  If you've got a bad web browser, you might as well have a bad computer.  Microsoft Internet Explorer is, decidedly, a bad web browser.  If a worse web browser exists, it's not in mainstream usage.  My recommendation for a new web browser is Google Chrome.  It's fast, simple, very clean looking, and doesn't suffer from the familiar but inexplicable toolbar accumulation that is ubiquitous with Internet Explorer.

5. Defragment the Hard Disk
Remember how I said memory gets fragmented as the computer is used?  Well the same thing is happening to the disk over the life of the computer, except that the disk is permanent.  That means it isn't fixed by a simple restart.  Making matters worse is that the disk is already slow; even at it's optimal level of performance, it is by far the slowest critical component of the modern computer.  The way disks work make fragmentation very bad, a badly fragmented disk could easily be 20 or 30 times slower than if the data were optimally arranged.  The solution is actually pretty simple, it just takes a while to run.  Go to the start menu and in the search box type "defrag."   A couple of things will probably come up, but click the one called "Disk Defragmenter."  To run it now, just select the drive you want to defragment (probably C:), and click "Defragment Disk."  That's a good start, but the key is to defragment the disk on a regular basis.  To do this, just click the "Configure Schedule" button and change the settings to have the disk be defragmented automatically either once a week or once a month.  You'll probably want to have it do it at a time that you won't be using the computer, since the computer will slow down dramatically while the defragmenter is running.  I have mine run every Wednesday at 1am but that's a bit aggressive, once a month should be plenty.

And that's pretty much it.  Follow these steps every couple of months and you'll be guaranteed to lower my phone bill.

Also it should be noted that these instructions are for a Windows 7 machine, but Windows Vista and XP are very similar.  If you're having trouble figuring out how to do something on another version of windows, just google something like "Windows Vista uninstall programs" (or whichever windows version you have and whatever it is you're trying to do that I didn't explain well enough), and you should find detailed instructions.