Tag Archives: Math

Porting my Calculator to Python

Although the first language I actually learned was VB.NET, Python is what actually inspired me to begin programming. My dad talked me out of learning it (one of my friends suggested that I did); who knows what kind of programmer I would be today if I had learned it. My guess is that I would be better with server-sided activities and worse on the desktop. Perhaps I’d be more of a Linux guy.

Anyway, I got inspired to learn Python yesterday for whatever reason, and today, I decided to port my calculator to Python. For the sake of comparison, I stayed fairly true to my original C# program. Here’s the very annoying program I came up with (it has no way to exit and loops forever so you have to close the console if you want to close it):

# Python calculator program
# This is the first Python program I've written for a LONG time.
def main():
	while 1==1:
		try:
			number1 = float(raw_input("Enter a number, then hit enter: "))
			number2 = float(raw_input("Enter another number, then hit enter: "))
			operator = raw_input("Which operation do you want? (Choose +, -, * or /, then hit enter): ")
			if operator == "+":
				print "The sum is:", Add(number1, number2)
			elif operator == "-":
				print "The difference is:", Subtract(number1, number2)
			elif operator == "*":
				print "The product is:", Multiply(number1, number2)
			elif operator == "/":
				print "The quotient is:", Divide(number1, number2)
			else:
				print "Please choose another operator."
 
		except:
			print "Error, please try again."
 
		print "\r\n"
 
def Add(num1, num2):
	return num1+num2
 
def Subtract(num1, num2):
	return num1-num2
 
def Multiply(num1, num2):
	return num1*num2
 
def Divide(num1, num2):
	return num1/num2
 
main()

Here it is in action, running in PowerShell:

Python Calculator Image

You can do the four most basic operations over and over! Woo!

In doing this port, I noticed that my beginner-targeted C# code was way longer than it needed to be (with all the helper methods) but very easy to understand. I also noticed a lot of things about Python, some of which I liked and some of which I did not.

The Good

  • The console print command makes it very easy to concatenate variables in.
  • In the small program I had, relying on indentation instead of { } to organize code saved a lot of screen space.
  • The raw_input() function serves as an equivalent to Console.WriteLine(), Console.ReadLine() in C#, saving more keystrokes.
  • Overall simplicity and intuitiveness. I’m a C# developer, not a Python developer, but I was able to complete this port with a little help from Google. Python operators were similar to the C# ones and the syntax isn’t difficult to understand at all. I can read Python code and understand much of what it does, unlike Ruby programs which tend to make my eyes glaze over.

The Not-So-Good

  • I’m not sure how well the whole indentation thing would work in a huge program. Things are bound to get mixed up eventually. Still, I’ve spent plenty of time counting curly brackets trying to figure out why my code won’t compile, so it may just come down to preference.
  • Lack of strong typing. I’m used to seeing float number1, not just some random variable declaration. Again, things could get confusing, especially if you forget what a variable is for.
  • The variable declaration syntax. It makes copy and pasting code much easier not having to get rid of keywords, but it is nice to know that you are declaring a variable for the first time, even if it is with the var keyword in JavaScript.
  • This page says, “Java is a pair of scissors, Ruby is a chainsaw.” That’s fair enough, but where does Python figure into things? Does it have enough horsepower to get things done or should I stick with my C#?

Even with its flaws, I do rather like Python. XKCD sums it up pretty well. I think I will try writing some more programs in it. Heck, I might do some server-sided things with it. Learning another programming language can’t possibly be a bad thing.

Brute Security

DISCLAIMER: I do not endorse the use of any “cracking” methods I discuss in this article for anything but educational purposes, nor do I claim to be any sort of “security expert”. Everything here is provided “as-is” with no warranty whatsoever.

With the legal jargon taken care of, let’s discuss passwords and why you have them (note the plurality – I sure hope you don’t simply have one password!). Passwords protect your information.Without them, everyone would have access to everything with only a username. Would you feel comfortable with that? I didn’t think so.

So, if the point of a password is to protect your security, then it follows that a password should be as secure as possible. What makes a secure password? I turned to Google for some advice. Here’s the jist of what I learned:

  • Length is super-important
  • Mixing uppercase letters, lowercase letters, numbers and symbols makes the best password possible

What’s groundbreaking about that? Absolutely nothing – tips for crafting great passwords have been around for as long as I have been able to read them. The problem is that great passwords are often difficult to remember. For example, AsJ*()gM,4 is ten characters long and has at least one character from each category I just mentioned. XKCD came up with a solution to the problem, though I don’t agree with simply using lowercase letters (and Google rates the example “correcthorsebatterystaple” password as “Good” rather than “Strong”). Why only strong for such a long password? Here are two common for breaking passwords:

  • Dictionary attacks are attacks using common “passwords”, usually derived from the dictionary or other common phrases. Dictionary attacks are the easiest, fastest way to break insecure passwords. Is your password “password”, “password1″, “123456″, “qwerty”, or anything else on this list of tragically bad passwords? It will be broken with a dictionary attack.
  • Brute force attacks are exactly what they sound like – they try every password combination possible. They are useful when dictionary attacks fail, because “zebra” will be cracked by a dictionary attack, but “ze6ra!” probably won’t be. They also aren’t very much work to implement but take much, much longer than a dictionary attack. How much longer? I wanted to find out.

I wrote a very, very slow brute forcer implementation in C#. I am not going to publish the source code on the blog, but I’ll give you an idea of how it works:

  •  The brute forcer is passed a string containing every character it should try, which could be something like “abcdefghijklmnopqrstuvwxyz”. It is also passed the MD5 hash of the string it is trying to break.
  • The brute forcer uses a for loop starting at zero up to the length of the trial string raised to the power of the maximum length to look for.
  • It computes the MD5 of the generated string and compares it with the one it is trying to break. If they match, it is done.
  • There are some big slowdowns – the .NET framework (which I did my best to counteract by using the “unsafe” keyword) and that I am only using one core. Sure, I have a 3.7gHz i7, but I am only using one of eight possible cores. These passwords would break much faster if I used all of them or if I had a supercomputer.

The way this brute forcer works has taught me two things just how correct that password advice is. It’s all in the math.

Longer passwords make taking passwords way longer. Let’s examine a two character password comprised of uppercase and lowercase letters. There are 52 possible first letters and 52 possible second letters, so the total number of password permutations is 52 * 52, or 52 ^ 2. It follows that the number of permutations is 52 ^ N, where N is the length of the password. Therefore, assuming every cracking iteration takes the same amount of time (around 50 microseconds on my password cracker near the beginning, which isn’t very fast), every letter you add makes cracking take 52 times as long. If you add three characters, there will be about 140,000 times as many combinations.

Special characters make password cracking take far longer as well. Think about it – if your password is comprised solely of lowercase letters, there are 26 ^ N permutations. Add the uppercase letters, and there are 52 ^ N. With the numbers 0 – 9, there are 62 ^ N. Add ~`!@#$%^&*()_-+= and there 78 ^ N.

According to my expert Windows calculator usage (in scientific mode, which the C# calculator tutorial didn’t cover), a five-character lowercase password has 11,881,376 permutations, while a five-character password that could use every symbol I have mentioned has 2,887,174,368 permutations. That’s right – the jump is from 11.8 million to 2.9 billion. In fact, you would have to use about a seven-character (well, about 6.7-character) lowercase password to match the strength of the five-character anything-possible password.

Not convinced about the huge difference? Here are some action shots with some different password lengths (all matching against the “anything-possible” string of 78 characters):

Three-Character Password

Three-character password.

Four-Character Password

Four-character password.

Five-Character Password

Five-character password. To be fair, my computer was asleep for much of that time.

So, in going from a three character password we went from less than one million iterations to success to 2.4 billion iterations to success. Imagine how long this would take with, say, an eight-character or ten-character password.

As always, there is one big concept I want you to take away from my articles. In this case, it is that adding just one symbol to your current password (even if it as simple as putting it in parentheses or putting an asterisk in front) will strengthen it immensely. Stay secure!

Will it Rain this Weekend?

While browsing MIT+K12 open projects, I came across an entire course proposal about probability. Now, I have very little formal probability training outside of one unit in precalculus last year, but I was intrigued by the idea of writing a program to simulate 10,000 trials. Obviously, 10,000 trials isn’t enough to get a really good data set so I added a few zeros to my C# for loop and ran 1,000,000 trials.

So, in keeping with the MIT course proposal, I checked the forecast for the weekend and found out that this weekend, the chance of rain on Saturday is 10% and the chance of rain on Sunday is 30%. My first reaction was mild aggravation because I went camping last weekend in the rain and I simply could’ve waited a week. My second reaction was, “Alright. Let’s get started.”

Probability Tree Image

Mr. Whalen, I hope you’re proud of me.

The next step was to write a program to test my calculations. I came up with a program structure that I hope is “random” enough. I am going to use System.Random instead of RNGCryptoServiceProvider because it is way faster and I believe it fine for something this simple. When I originally wrote this program, I used lists, populated them with true or false values, randomized them, and picked from them over and over again. I am not sure what kind of awful state of mind I was in when I wrote that code (whatever it was, there wasn’t enough caffeine), but I’ve come up with a way more elegant solution – Random.NextDouble(). If the double is less than the probability of rain, it rained. Otherwise, it didn’t. We also need three counters – one for when it rains sometime during the weekend at least once, one for when it rains exactly once and one for when it rains twice.

There is one other case: when it doesn’t rain, but 1,000,000 – the number of times it rained at least once takes care of that. Some operators make determining which case we’re dealing with easy – XOR is true if exactly one of two cases is true, OR is true if at least one case is true, and AND is true if both cases are true.

With that taken care of, all that was left was to write the code in a console application:

static void Main(string[] args)
{
    double probRainSat = 0.1;
    double probRainSun = 0.3;
 
    int rainyWeekends = 0;
    int oneDayRainyWeekends = 0;
    int bothDayRainyWeekends = 0;
 
    Console.WriteLine("Simulating one million weekends...");
    Console.WriteLine();
 
    Random rand = new Random(Environment.TickCount);
 
    // one million trials
    for (int i = 0; i < 1000000; i++)
    {
        if (i % 100000 == 0)
        {
            Console.WriteLine("{0}...", i);
        }
 
        bool rainedSat = rand.NextDouble() < probRainSat;
        bool rainedSun = rand.NextDouble() < probRainSun;
        if (rainedSun || rainedSat)
        {
            rainyWeekends++;
        }
        if (rainedSat ^ rainedSun)
        {
            oneDayRainyWeekends++;
        }
        else if(rainedSat && rainedSun) // We can use else if because it can't rain on exactly one and both days.
        {
            bothDayRainyWeekends++;
        }
    }
 
    Console.WriteLine("Rain on only 1 day: {0}/1,000,000 ({1})", oneDayRainyWeekends, oneDayRainyWeekends / 1000000);
    Console.WriteLine("Rain during the weekend: {0}/1,000,000 ({1})", rainyWeekends, rainyWeekends / 1000000);
    Console.WriteLine("Rain on both days: {0}/1,000,000 ({1})", bothDayRainyWeekends, bothDayRainyWeekends / 1000000);
    Console.WriteLine("Rain on neither day: {0}/1,000,000 ({1})", 1000000 - rainyWeekends, (1000000 - rainyWeekends) / 1000000);
    Console.ReadLine(); // Keep the program from closing.
}

Now you can run your new creation:

Probability Simulator Results

You just simulated about 19,200 years worth of weekends.

Not bad, huh? If you round, you’re spot on with the calculations. The math predicted almost exactly what the program would do. That, my friends, is pretty cool.