4.5 Python hash function (Optional)
4.5 Python hash function
Several of you are worried about not getting all of the Runestone questions correct. In some cases there is a bug in the question or in the answer checker that would make it nearly impossible to get runestone to mark your answer correct. So I’ve rounded up all your grades to 100% if you get more than 70% correct.
Below is a table for my Runestone gradebook. To find out which row is yours, you will need to learn a little more Python. Launch a Python Console on your PC. In Sublime you can reveal your Python console at the bottom of the Sublime Text window by selecting “Show Console ctrl-`” under the View Menu. If you installed Anaconda on your PC, in your Anaconda app launcher the Python console is called “iPy” or “QtConsole”. In Anaconda, you could also use Jupyter Notebook to run this Python code.
Big thanks to Jesse for reminding me that the built-in hash function is inconsistent between instances of the Python interpreter. However, the random module has a seed function that you can use to force everyone’s hash value to be consistent. I had to create my own hash function so I could be sure it would work the same for you as it does for me.
With a Python console open, you can find out the random integer value (hash value) I used to hide your phone number by running this code:
>>> import random
>>> last4_phone = int('0070')
>>> random.seed(last4_phone)
>>> random.randint(0, 10_000)
1940
>>> random.seed(70)
>>> random.randint(0, 10_000)
1940
Notice that if you can ignore any leading zeros in the last 4 digits of your phone number, because int('007') is the same as int(7).
Technically this is not a very secure way to hide your grades. If you are uncomfortable with a clever friend who knows your phone number being able to see your Runestone grades, please send me an Inbox message and I will hide your information more securely.
What is a hash function?
A hash function is uses a one-way math equation that computes a large, random-looking (called “pseudo-random”) integer from a string.
A hash function is designed to make it super-easy for you or anyone else to calculate a hash integer y from any string value x.
But it is really, really hard for you, or anyone else, to guess the value of x that someone used to create a particular value of y.
It is virtually impossible to “solve for x” in an equation like y = hash(x), even if you have millions of examples of x and y, or have all of the the Python code and the math formula for the hash function.
However, the built-in Python hash function is not designed to be used for cryptography! It would be possible for a clever student to figure out all the last 4 digits of everyone’s phone number using this list of hashes. If you are taking a cyber security class, this would be an ethical hacking challenge to try for yourself. And if you attend an office hours session with me. You can send me a message on the Canvas Inbox to schedule a one-on-one if you can’t attend one of the prescheduled office hour sessions.
Do not use the Python hash function for cryptography, except to play around with toy ethical hacking challenges with your friends. Can you guess what the Python hash function is used for in the real world? It turns out there are some really cool ways to use a hash function to organize data in a super-fast data structure called a “hash map.” You can think of a hash map as the GPS latitude and longitude global map of all the data in a dataset.
A hash map makes it possible to find any piece of data very very quickly, even if it’s hidden in a super-huge heap of data.
In Python we call this clever data structure a dictionary (dict)!
Almost every object in Python has a hidden dict behind the scenes doing the hard work of keeping track of where everything is in the memory on your computer.
If you want to see an example of one of these hidden dictionaries, just type globals() in any Python console, and you will see a big dictionary of the things it’s keeping track of for you when you type Python commands.
There are some very useful hidden variables and functions in this globals()dictionary.
It can be a lot of fun playing around in a Python console to discover new ways of doing things or trying to figure out how Python works.
Runestone Gradebook
| Hash | Module01 | Module02 | Module03 | Module04 |
|---|---|---|---|---|
| 2669 | 1 | 1 | 1 | 0.108108 |
| 3753 | 0 | 0 | 0 | 0 |
| 5571 | 1 | 0.0238 | 0 | 0 |
| 7094 | 1 | 1 | 1 | 0 |
| 322 | 1 | 0.5238 | 0 | 0 |
| 2401 | 0.6087 | 0 | 0.0370569 | 0 |
| 8462 | 1 | 1 | 0.0370569 | 0 |
| 8212 | 1 | 1 | 1 | 0 |
| 9308 | 1 | 1 | 1 | 0 |
| 6819 | 1 | 0.5238 | 0 | 0 |
| 3083 | 0 | 0 | 0 | 0 |
| 9920 | 1 | 1 | 1 | 0 |
| 7277 | 0 | 0 | 0 | 0 |
| 4026 | 1 | 1 | 1 | 0.432432 |
| 8045 | 1 | 1 | 1 | 0.108108 |
| 8540 | 1 | 1 | 1 | 0 |
| 1284 | 1 | 1 | 1 | 0 |
| 4393 | 1 | 1 | 1 | 0 |
| 6361 | 1 | 0 | 0 | 0 |
| 1592 | 0 | 0 | 0 | 0 |
| 9874 | 1 | 1 | 1 | 1 |
| 611 | 1 | 1 | 1 | 0 |
| 2997 | 1 | 1 | 1 | 0 |
| 9794 | 0 | 0 | 0 | 0 |
| 6288 | 1 | 1 | 1 | 0 |
| 1563 | 1 | 1 | 1 | 0 |
| 1700 | 1 | 1 | 1 | 0 |
| 1521 | 1 | 1 | 1 | 0.0810811 |
| 523 | 0 | 0 | 0 | 0 |
| 8825 | 1 | 1 | 1 | 0 |
| 7717 | 1 | 1 | 0.333298 | 0 |
| 1344 | 0 | 0 | 0 | 0 |
| 4542 | 1 | 1 | 1 | 0 |
| 5723 | 1 | 0.5476 | 0 | 0 |
| 6471 | 1 | 1 | 1 | 0 |
| 316 | 1 | 1 | 1 | 0.648649 |
| 1027 | 1 | 1 | 0.222234 | 0 |
| 7591 | 1 | 1 | 1 | 0 |
| 2805 | 1 | 0.6429 | 1 | 0.243243 |
| 2542 | 1 | 1 | 1 | 0 |
| 2044 | 1 | 1 | 1 | 0.594595 |
| 4438 | 1 | 1 | 1 | 0 |