Wednesday, November 28, 2018

Easy Peasy Money Management Plan

This isn't something that I would normally share publicly, but I'm hoping that it will benefit a few people who really worry me too darn much!

The method below is how I manage my finances.  I learned it through trial and a lot of error.  I'm told I'm pretty good at it nowadays.  Well, this is how I do it.


  • No worries about daily living expenses.
  • The math is simple.
  • A buffer is built in to handle mistakes and emergencies.


Before we really begin, you should know that this method won't work for everybody.  Years ago, when I was making $300 a month, this method could not be done.  However, if you meet the requirements listed below, it will work for you:
  1. Two weeks of pay should cover the roof over your head.
  2. Three weeks of pay should cover both the roof over your head and basic living expenses.
If your debts, frivolous activities, and other expenses don't fit into the first three weeks too, then that's okay.  At the end, they can fit within four weeks.  Or, you can do what I do and make sacrifices to fit all bills into three weeks and have a full week's pay for other stuff.

It's all about the budget

Worry about budget usage, not bank account balance.  If I go out partying every night at the beginning of the week, that uses up my "partying budget."  I still have money for food and rent, but I can't go out partying until the next month.

Never sacrifice one budget to pay for another.  If my light bill this month is half of what I expected, I still can't go out partying if I've used that budget up.  I feel like this is where a lot of people will get tripped up.  Your budgets are hard monthly limits and can never be negotiated.

Always ignore extra money.  Extra weeks in a month that give you more pay aren't considered in your budget.  You can't spend it.  Extra money goes into your bank account and is ignored until "a rainy day."  (More on this later.)

All needed living expenses should be covered by week three.  The fourth week can be divided up however you want after the goals (scroll down) are met.

Easy Math -- Pitted Against You

Round up for expenses and down for income.  A $123.75 bill is considered to be $150.  A $310.80 paycheck is considered to be $300.  The bigger the number, the more you should round it.  You'll get a feel for what works.

For income, every month has four weeks.  For bills, every month has five weeks.  If you make $300/week, then you actually make $1200/month.  If you spend $10/week on gas, then you actually spend $50/month on gas.

Your bills that change every month are considered to be the maximum.  An electric bill that ranges from $45 to $75 throughout the year is considered to be a steady $75.

By following the above rules, you end up with extra money.

Getting Comfy

Getting comfy doesn't happen overnight.  Most people have debts, and few people seem to have money stashed away for emergencies.  To get comfy, meet the goals below by using your fourth week's pay.  I've listed the goals in order of priority.

Make Sacrifices

Until you meet all of the goals below, cut out as many extra expenses as you can.  Actually, you may realize that you don't miss something after it's gone.  I still don't own a TV even though I've been able to afford one for years!  ;)

Debt payments should be no more than half a week's pay.

At first, you should pay down your debts if the minimum payment is more than half a week's pay.  Pay them down as quickly as you can.  You'll get there.

It is a good idea to have some debt to build credit, so don't worry about paying all of it.  Just get it to a manageable state.  Do not pay more than a week's paycheck to do this though.  That money is needed elsewhere.

Have a buffer that covers the most important expenses.

A buffer comes in very handy for unexpected expenses or mistakes in budgeting.  I've found that the best amount is just enough to cover rent, utilities, gas, and cheap food.

Put money into your checking account until you can cover this for a month.  This is your buffer.  Then keep putting money in until it never drops below that amount.

Lastly, save up three months of pay.

After your debts are paid down and you have your buffer, start a savings account.  Put money in until you have a full three months of pay.  If you lose your job, you have at least three months to find another good one.

Be Comfy

Now you are very financially stable.  You have low debt, a good buffer, and a substantial savings account.  Money is not a worry because you can cover all of your bills so long as your stick to your budget.  But what do you do with that extra week and more of pay?

Ignore the fifth week.

If you make more money in months with five weeks, ignore that fifth week.  It goes into your savings account.  Don't try to budget it.  If you do, you'll end up with nasty fractions in your math.

Budget the fourth week however you want.

It isn't all just extra money that you can throw around.  You should budget this too.  You decide what you want to spend it on.  I budget $50 on visiting distant family and friends, $100 on stupid stuff, and the rest goes to my savings account.  You may choose to budget some of it for a television service.

Prune your buffer.

Over time, you'll notice that the buffer in your checking account grows.  Prune it down to the limit you set by transferring the extra money into your savings account.  I tend to do this every three months or so.

Enjoy the rainy days.

Over time, your savings account will grow.  Always keep three months of pay in there, but any extra can be used for a rainy day.  I'm saving up for a vacation next summer.  Alternatively, you can use it as an investment into a new business in the hope of making more money.

Hard Numbers

Well, not so hard numbers since I don't share my salary with anyone.  I am fine with speaking in terms of budget, so here it is for your reference:

$100/week: food and going out
$50/month: visiting distant family and friends
$100/month: stupid stuff
$XX/month: savings account

And that, my friends, is all that I consider.  I don't worry about rent, gas, and living expenses because I know that's covered.  And if I have to buy new tires for my car, I don't worry about that either because it's covered in my buffer.

Saturday, September 29, 2018

Information Security

In my line of work, I have to know a lot about information security. My focus is more on software and websites, but some of my coworkers set up secure networks and workstations. Yet even when everything is done correctly, that security may still fail. In most cases, the weakest link turns out to be the users.

I've organized this post for easy skimming if you want to just read the bold text.  Or, you can dive down into the details and hopefully gain a little more understanding.

Everything can be hacked.

The question isn't whether something can be hacked—it's how hard it is to hack. A flower shop computer is definitely easier to hack into than a nuclear reactor, but both can still be hacked if you know how to do it.

Your goal should be to make it very difficult to gain access to your data. The inexperienced hackers should not be able to figure it out, and the experienced hackers should not consider it worth their time. If you're storing government secrets, you will want to go even further, but that is not within the scope of this blog post.

Find a trustworthy tech person.

Even if you know a thing or two about computers, find someone whom you can trust for tech support. And be sure to make it worth their while to help you when needed.

Be sure that you can trust them.

You may have to give a tech access to your data for them to fix something, so trust is very important here. I'd recommend going with someone experienced, because experience will tell them that they really don't want to know what you have on your computer.

Dont' jump between multiple techs.

Each additional person adds a potential point of failure. Keep the circle small.

Secure your own computer.

The news mostly reports about websites and databases being hacked, but most of the data breaches I've seen first hand have been on personal computers. Make sure that your computer is not the weakest link.

Keep your computer updated.

Never turn off automatic updates, and routinely update the software that you use. As security holes are found, they are fixed. You want the latest fixes.

This also includes your virus protection software. Make sure that it is updated regularly so that it knows about the latest viruses.

Never turn off your firewall.

If your "trusted tech" tells you to turn off your firewall for more than a few minutes, then call them stupid and find someone else. It's okay for them to turn it off for a minute to diagnose a problem, but it should never be turned off permanently.

Be careful opening files that you didn't create.

Programs are dangerous, Word documents are questionable, and pictures are only usually safe. I say "usually" because it is possible to put a virus into any type of file. Some are easier to do this with than others, so the easier ones such as programs and documents should be given an especially thorough looking-over.

If you do not trust the person who sent you the files, or if anything looks suspicious, then don't open it until you've verified that it is safe. This can be handled a variety of ways, including: talking to the person who sent it, conferring with your "trusted tech", or simply deleting the file.

Regularly back up your files.

Even if we are super careful, we may still get into trouble. As a backup plan, you should regularly backup of all of your important files. Not only is this a good idea from a security perspective, it is also a good idea from a data retention perspective.

Surfing the 'Net

You can go overboard with security by using VPNs, proxies, and other tools, or you can just accept the fact that some websites just aren't very trustworthy. I prefer to go with the later and follow a few simple security rules.

Be careful what websites you visit.

Websites that are taboo seem to be the worst about being malicious. I'm not sure why, but it's almost as if the people who make such websites don't have very high morals.

Even websites that aren't about taboo topics may be malicious. If you don't know the website, don't trust it. You may still want to visit it, but don't enter in any of your personal information or passwords.

Get an ad blocker.

Usually, the website has little control over the ads that it serves, and some ad platforms aren't very secure. Using an ad blocker will block a lot of potentially harmful content. As an added bonus, you get legitimate advertisements blocked too!

Do not trust tech support popups.

The #1 most common way that I see people infected is by calling fake "Microsoft" because of a popup when they visited a malicious website. Instead of calling the number on the screen, call your "trusted tech" that I mentioned earlier.

Pay attention to what your browser says.

Most popular browsers will tell you in the address bar whether a connection is secure. If the website is not secure, then do not enter any sensitive information on that website. Also, if your browser stops you with a big red warning screen, that means stop and close the tab.

Social Networking

While most popular platforms are secure, they usually do sell our data. Those third parties are the weak point. A chain is only as strong as its weakest link, so these super-secure systems may not really be so secure after all. That's okay so long as you keep it in mind.

Do not share any secrets.

Not only do your friends talk, the social network does too. If you don't want something to be public, then do not share it on a social network. It will be seen by more people than you intend to see it.

Your legal notices do not work.

I see a lot of posts that go something like, "I do not give Facebook permission to share my data." People expect for that to be legally binding, but it's not.

For such a text to be legally binding, all parties must intentionally agree to it, and there must be a record of such an agreement. I've never seen Zuckerberg comment "I agree" on such posts, but I guarantee you that all of us checked "I agree" while setting up an account.

Disclaimer: While I've done my research on this topic, I am not a lawyer and this is not legal advice. Consult a lawyer if you're serious about wanting to press this issue.

Be careful what third parties you allow access to.

Those "Sign in with [whatever]" buttons are very convenient! I no longer have to create an account for every service that I use. But they come with a downside – you are giving a third party access or control of some of your data.

On all popular social networks that have this feature, you can review which third parties have an access token and what data is shared with them. Review this and revoke access to the ones that you don't want on there.


Emails are not secure. We've been throwing technologies at it for years to improve its security, but it still sucks as a secure medium. Still, the convenience of it may be worth it if you're careful.

Verify unknown senders or emails.

If you receive an email from someone's "other" account that you haven't seen before, call and verify that it's them. If you receive an email that it doesn't make sense for you to have received, call and verify that they sent it. Or, just delete the emails if they don't look important.

Encrypt or don't send sensitive information.

If you want to leave your key under the doormat, that's fine, but don't be surprised when a robber finds it. It's the same concept here. If you do not encrypt sensitive information sent over email, then don't be surprised when a hacker gets it. I use this analogy because it's really up to you whether to go with convenience or security.

Be careful of attachments.

Every time that you open an attachment, you're at risk. Even if you trust the sender, who's to say that their computer hasn't been compromised. Weigh the risks, consider the convenience, and decide whether to gamble with your security.

Is it worth it?

As a software developer, it is my job to protect computer users. My aim is for my creations to never be the weakest link, but I can never dictate what else the user may have on their computer or how they may use it. Sometimes it feels like a losing battle, but that isn't how we should look at it.

With computers, we can do so many incredible tasks that we couldn't easily do before. The cost is a little bit of security. Is the benefit worth the cost? I think that it is. We just need to be aware of the risks and take appropriate precautions.

This is by no means an exhaustive list of precautions that can be taken, but I consider these to be some of the basics. I hope that this helps some of you to be safer on computers so that you can continue to enjoy that very useful technology.

Saturday, March 10, 2018

The Exception to the Rule

Exceptions in Programming Languages

I learned a neat little construct recently: exceptions!

Okay, so it's been 13 years since I first heard about them, but it wasn't until I read this StackOverflow question that I felt like I actually understood them. I finally felt like I knew when to use exceptions and when not to use exceptions.

I don't want to focus on the details of exceptions, but perhaps a little crash course is appropriate.

What are exceptions?

Exceptions can be thrown and caught. When you "throw" an exception, your program stops dead in its tracks. It picks back up wherever you have chosen to "catch" the exception. There's a little behind-the-scenes stuff too, but that's the gist of it.

    try {
        cout << "The program gets to here... ";
        throw exception();
        cout << "... and it never gets here." << endl;
    catch (exception & e) {
        cout << "... and it picks up here." << endl;

If you run this code, it will output the following:

The program gets to here... ... and it picks up here.

It works, but is this good code? Are there better ways to do the same thing?

Pros and Cons of Exceptions

Exceptions are slow. Yes, they can be terribly slow! It is much faster to use conditionals instead of exceptions. (Or, in the case of the program above, just drop the dumb lines that are only there for the example's sake.) Exceptions are just plain slow!

However, not having an exception is faster than conditional execution (like if, while, etc.). If you /can/ throw an exception but you don't, that's super fast! They are only slow when they are actually used.

That's the gist of the answers on the StackOverflow question I linked earlier.

When do you use exceptions?

After meditating on that StackOverflow question and its answers, I feel like I finally know when to use exceptions. Bare with me, and I'll explain.

A few givens:
  • Exceptions are slow, so you don't want to use them.
  • Having exceptions but not using them is fast.
  • Conditionals are almost as fast as unused exceptions. *
* at least in the languages I cared to research last weekend.

My conclusion is that exceptions should never happen. They should never be used. They should never be thrown. They should never be caught.

The exception to the rule "exceptions should never happen" is "an exception happens".

Thoroughly confused...

I get up and go to work every morning at 7:50am. I do this every weekday. This is normal to me.

Six months ago, I got in my car at 7:50am, and it wouldn't start. This is an exception! I had to change my plans because of this unexpected event.

I have come to the realization that exceptions in programming are exactly the same thing. In normal operation, how should the program work? Use exceptions for exceptions to this rule of how things should work.
  1. Use a conditional when: It's something that needs checked or just happens sometimes. Your program is coded to handle anything amiss.
  2. Use an exception when: Uh oh! Something happened, and the program wasn't built for this!
In short, exceptions never happen, and the exception to this rule is when they happen.

I need an example.

Perfect! Let's say you've got a text editor. Usually, you'll be trying to open valid files, but sometimes the user tells you to open a file that doesn't exist.

bool openFile(const char * filename)
    this->f = fopen(filename);
    if (!f)
        return false;
    return true;

This is a member function of our TextEditor class. You try to open a file. If it doesn't exist, then no harm done. The program keeps on chugging away as usual, probably prompting them for a valid file name.

Now let's look at a different case. What if you are trying to open a configuration file for your program?

    FILE *f = fopen("myConfig");
    if (!f)
        throw exception("Config not found!");

It's different. We expect the config file to exist. If it doesn't, we just can't continue. This is an exception.

We will, of course, catch the exception somewhere. If we're good, we might try to recreate the config and try again. But, for the moment, we've hit an unexpected obstacle that needs fixed before we can continue normal operation.

Thursday, February 23, 2017

SQL Injection: What it is and how to avoid it

A while back, we (where I work) took over a project from another company. I was going to make some small changes and have it up before my second cup of coffee! Then I opened the code and realized I would be working late that day instead.

Among other issues, the code was vulnerable to SQL Injection.

SQL Injection is one of the easiest hacks to do. It's also one of the easiest to protect against. Still, it's a pretty common vulnerability! As much as I would love to have a backdoor into tons of sites, I can't help but lose sleep over this problem being out there. I have to share a few solutions.

What is SQL Injection?

For an example, let's take a very simple login page. I won't post the code, but the basic idea is to take a username and password, compare it to what's in the database, and log them in if it's a match. Easy peasy!

Here's the SQL to match it up in the database:

SELECT id FROM users WHERE username='bob' AND password='1234'

If it doesn't return anything, the username and password is wrong. If it finds a match, it returns the user's ID.

What if we change the username to bob'--?

SELECT id FROM users WHERE username='bob'--' AND password='1234'

Whoah! We just made it so that we don't even need the password! We can log in as anybody so long as we know their username!

The problems don't stop there. We can change a page that displays a list of items to sort/filter however we wish. We can increase the number of results returned and use that to do a very good DOS attack.

If the webhost is particularly unlucky, we can even execute SQL for other websites that they host -- even if those sites aren't vulnerable! (Hint: "USE abcDatabase;")

How do we protect against it?

That's easy. Sanitize your inputs!

Way 1 - Escaping data

You can properly escape the data before putting it into the SQL query.

Most languages have a function to escape out harmful characters, and it's usually pretty easy to use. This post is language-agnostic, but the basic idea in most languages is to pass in a potentially harmful string and get back a properly escaped one. The SQL query becomes the following:

SELECT id FROM users WHERE username='bob''--' AND password='1234'

As you can see, the SQL injection attempt will now be unsuccessful!

This time.

Watch out!

What if we have the following query that deletes the message with a given ID?

DELETE FROM messages WHERE messageId=12

It looks pretty harmless. Of course, we'll be sanitizing any user input anyways, right?

What if we give our code "1 OR 1=1" as the ID to delete? There are no special characters to escape. The string will get substituted as-is. What does this do to our query?

DELETE FROM messages WHERE messageId=1 OR 1=1

Oh, it just deletes everything. Even though we escaped all of the harmful characters, we are still vulnerable to SQL injection!

The quick solution is to put single quotes around every "variable" you're substituting in. It will work, but then you might run into weird logic errors when doing comparisons. A better solution is to use parameterized queries. Read on.

Way 2 - Parameterized Queries

Parameterized queries will properly escape any data, will verify that the type of data matches up, and will (hopefully) make sure everything's dandy with the character encodings. They are the best way to do SQL queries.

SELECT id FROM users WHERE username=@username AND password=@password;
DELETE FROM messages WHERE messageId=@messageId;

It might look a little different in different languages, but that's the basic idea.

Now you need the code that puts in the data. This depends a lot on the language, but the basic idea is to say what type of data each parameter is and then to set it to a value. In VB.Net, here is the code for the second query:

Dim query = "DELETE FROM messages WHERE messageId=@messageId"
Dim cmd As New SqlCommand(query, connection)
cmd.Parameters.Add("@messageId", SqlDbType.Int)
cmd.Parameters("@messageId").Value = 12

Parameterized queries are more verbose and somewhat confusing at first, but do use them. Use parameterized queries. Use parameterized queries.

Conclusion and Final Thoughts

SQL Injection is very easy to do, very common, and yet very easy to protect against. The simple solution is to just use parameterized queries everywhere. This OWASP page has some handy code snippets for your reference.

Here's a rule: Always use parameterized queries. Never insert your data directly into a query string (even if properly validated and escaped first). I don't care what your teacher or textbook says. Use parameterized queries. The only exception to this rule is when you know the risks and make an informed decision to go another route.

Saturday, January 12, 2013

Playing a Pitch in an Android App with AudioTrack

 I've been working on an android app lately that can be used to tune instruments. I've run into a road block with the pitch detection, so I'm starting over and making the code nicer. While I'm at it, I figure I may as well share some of what I've learned!

Sunday, January 6, 2013

AVL vs. Red-Black: the conclusion

    I accidentally deleted my original blog post about this, and I can't recover it despite trying all sorts of different tricks. So, here it is reposted. Sorry for any broken links.

Thursday, January 3, 2013

Year of Change

December 21, 2012 came and went, and the world is still here.  I didn't look a lot into the Mayan Calendar, but I think I remember reading that every time one of their circle calendar thingeys rolls over, it's a new era that brings change.

Every year, on December 31, people decide to make new years resolutions.  This year, why not assume the Mayans had something going right and make a resolution to see change?

People have been chanting about "change" a lot lately, but what has really changed?  And why are we still living relatively ordinary lives?  Myself, I am terrified of change!  I like my comfort zone, and I'm sure most of you prefer to not take risks, too.

We all have opportunities.  Why not take them?  You have a lot to lose, but you have even more to gain!

I stopped spending so much time programming a while back.  I got a guitar and played it until my fingers blistered and cracked.  On the 31st, I bought a new car.  Yesterday, someone called me and asked me to come work at some company.

Change.  I have an option to refuse it and continue to live in comfort.  I think I'll make a change in my habits and seek to change.  I'm taking the risk, making a gamble, and I think the odds are in my favor.  Will you join me?

I got my first blow yesterday.  I'm apparently not as great at singing and playing the guitar as I thought.  I knew I wasn't great, but am I not at least a little good?  Nope!  But I also found some encouragement in an unlikely place.  I found a youtube video of one of my favorite singers when she was younger.  I love her to death, but she just could not sing!  Now, she's going on world tours!  If she can do it, why can't I?  And if I can do it, why the hell are you still reading this?  Get out there and live a little!