# Sending Secret Messages with Numpy

Numpy is a prominent Python library used for numeric computation. It is very popular with data scientists and analysts who need to do some heavy number crunching. One of the defining features of Numpy is the use of ndarrays, which perform faster than standard Python lists and can be used as mathematical matrices for computation.

Now all of that might sound a little complicated, but there are some fun things you can do with Numpy, too. We’re going to learn how you can use Numpy to store and encode messages to send to a friend, which they can then decrypt and read. No scary math involved.

Let’s get started.

## Getting started

To follow along with this tutorial, you will need a couple of things:

If you don’t have Python 3 installed, you can run brew install python3 at the command line to install using Homebrew. For more information, see this guide for OSX.

Let’s set up an environment to work in:

\$ `mkdir numpy_project`

\$ `cd numpy_project`

\$ `virtualenv -p /usr/local/bin/python3 secretmsg`

\$ `source secretmsg/bin/activate`

This sets up a project folder, initializes Python 3, and activates the virtual environment. To install Numpy, we run:

\$ `pip install numpy`

Once that finishes, we’re ready to go. Let’s make some secret messages.

## Encode a secret message

Now that we’ve got everything set up, the real fun begins. How are we going to use Numpy’s arrays to encode a secret message? Well, first we need a message to encode.

## Grab some data

You can make up your own message here, or use this sample message:

Keep it secret. Keep it safe.

To start out with, don’t make an awfully long message. A few words or a phrase will do. Once you learn how to do it, you can scale this example to longer messages.

## Load it into a numpy array

This is where we start using Numpy. We need to get our message into a Numpy array, right? The first thing we need to do is translate this text into Numpy’s data format. We can do that by splitting up the message by each letter. This way, each “slot” in the array will have one character.

Let’s do that now (this assumes you’ve created a file called message.py in your project directory):

```import numpy as np

message = “Keep it secret. Keep it safe.”
orig_array = np.array(list(message))
```

What we’ve done here is twofold. First, we use the list function to split up the string character-by-character, then we pass it to np.array. The output looks something like this:

[‘K’ ‘e’ ‘e’ ‘p’ ‘ ‘ ‘i’ ‘t’ ‘ ‘ ‘s’ ‘e’ ‘c’ ‘r’ ‘e’ ‘t’ ‘.’ ‘ ‘ ‘K’ ‘e’ ‘e’ ‘p’ ‘ ‘ ‘i’ ‘t’ ‘ ‘ ‘s’ ‘a’ ‘f’ ‘e’ ‘.’]

## Encode the message

The text is now in a Numpy array. Great! But…whoever we send this to can still read the message pretty easily. Let’s change that.

### The ROT-13 Cipher

ROT-13 is one of the most common cryptographic ciphers and can be used to “scramble” the letters in a message quickly and easily. It works by “rotating” each letter in the message by thirteen places. This means that the letter ‘a’ would turn into ‘n’, ‘b’ into ‘o’, and so on. This is a very simple cipher for the sake of example, so don’t go sending any really sensitive secrets using this method.

To encode our message using ROT-13, there’s a function in the codecs package to help us do that. You’ll just need to add the import statement at the top of your file (the library is included with Python, so you don’t need to install anything extra).

`import codecs`

`encoded = codecs.encode(message, ‘rot_13’)`

Encoded now holds the message in an “encrypted” form. Our example message now looks like this:

`Xrrc vg frperg. Xrrc vg fnsr.`

Sure, you could probably figure it out with a pen and paper fairly easily, but it definitely isn’t the same message we started with. Should be enough to throw any casually wondering eyes off the trail.

We can get it back into a Numpy array using the same code we used before:

`encoded_array = np.array(list(encoded))`

Next up — let’s export and send the message.

## Send it to our friend

In order to send this message to a friend, we need to export it from our Python program. Numpy has a special function for exporting arrays called numpy.save. This serializes the data and stores it in a .npy file format. That way, our friend can load it up in Python and start using the array just as we had.

The .npy format adds an extra layer of security during transit because it’s a binary Numpy file and not a plain text file.

To export our encoded array, use the np.save function:

`with open('secret.npy', 'wb') as outfile:`

`np.save(outfile, encoded_array)`

## Decode the message

Now you can send that .npy file to the friend of your choice.

To decode the message, we do a similar process. Let’s start a new Python file called decoder.py:

```import numpy as np
import codecs

Just like we used np.save to dump the array to .npy format, we can use np.load to bring the data back. If you print the contents of encoded_array, it looks like this:

[‘X’, ‘r’, ‘r’, ‘c’, ‘ ‘, ‘v’, ‘g’, ‘ ‘, ‘f’, ‘r’, ‘p’, ‘e’, ‘r’, ‘g’, ‘.’, ‘ ‘, ‘X’, ‘r’, ‘r’, ‘c’, ‘ ‘, ‘v’, ‘g’, ‘ ‘, ‘f’, ‘n’, ‘s’, ‘r’, ‘.’]

There, it’s back, just as we left it.

But our job isn’t done yet — we have to put the message back together and figure out what it says!

To join the message back together as a string, we can use the join function:

`encoded_string = “”.join(encoded_array)`

What this does is join all the elements in encoded_array together into one string. The empty string (“”) means that we don’t want any characters in between each element of the array.

Now we’re back to:

`Xrrc vg frperg. Xrrc vg fnsr.`

There’s only one more step: decode the message using the codecs library.

`decoded = codecs.encode(encoded_string, ‘rot-13’)`

Now, all our friend needs to do is print the decoded string:

Keep it secret. Keep it safe.

And that’s that.

## Going further

At this point, you should have learned how to use Numpy arrays to store data, export it, and load it from a file. You’ve learned a basic cryptographic technique for obscuring simple messages, and now you can use these programs to exchange notes with your friends.

If you wanted to expand on this project, here are some ideas and resources: