Creating our own number station code

Maybe you have heard of those mysterious radio broadcasting on shortwave frequencies sequences of number. While there was never an official explanation to what exactly those broadcast are, the most common theory is they are used by governments and intelligence agencies around the world as an one way channel to communicate with their foreign agents.

In this tutorial we are going to build our own number station code, so we can easily secure message.

Let’s hack this thing

  • Because number stations only broadcast numbers we will find a way to encode a text into a series of numbers
  • Because our message will be sent on an open and public channel we need a way to make it secure with some kind of code.
  • For the most lazy, a python code will be provided at the end that replicate the encoding we used.

Although we will use an open WIFI network to allow people to download our secret message BROADCASTING it in standard AM/FM frequency is strictly forbidden. DO NOT DO IT you will get in trouble with the FCC or its equivalent in your country is not responsible if you do stupid things.

Converting a text into numbers

We could use a python script and use a modern algorithm to encrypt data such as AES. While this would be secure, it as a lot of drawback, eg: a spy would need access to a computer. When you think about it one big advantage of number stations is the relative ease to decode a message. The only hardware a spy would need to receive the message a standard radio. This also means the encoding must be as simple as possible. Think of something that can be done with a pen and paper.

Step #1 Converting letters into numbers

The message we are going to send is ’The secret urbanhacker tutorial’. To convert it into numbers we need a simple substitution table to associate a number to every letter of the alphabet.

. (dot)36

Step #2 Padding and dividing the message into chunks to break patterns

To help readability we can use the symbol dot ’.’ as a separator. This will help to split words making it easier to decode.


This would gives us the following number list

29 17 14 36 28 14 12 27 14 29 36 30 27 11 10 23 17 10 12 20 14 27 36 29 30 29 24 27 18 10 21

To make it easier we can split it in chunks of 5 characters.

29171 43628 14122 71429 36302 71110 23171 01220 14273 62930 29242 71810 21

This can reveal certain information about our message since the last group is incomplete. We can use the symbol dot ’.’ as padding at the end which would mask how many real character there are and helps to make everything looks the same.

29171 43628 14122 71429 36302 71110 23171 01220 14273 62930 29242 71810 21363 63636

Now of course we could read those number and anyone with the table above would be able to decode it. However this is as you can imagine pretty insecure. Why? Because if you run a statistical analysis to see how many times a number appears we can reveal a lot of things. Eg. We see at the end there are a lot of 36, which probably indicate some sort of padding. If we look for other 36 inside the sequence we can already separate the code into words which is even worst.

This would defeat the purpose of a secret and secure message, and you have to remember because those number station are broadcasted all over the world anyone could easily intercept those message and decode them.

Step #3 Encrypting the message with random numbers

To secure it we are going to create a sequence of random number as long as the message itself. This sequence must be shared in advance with the recipient of the message. It could be hidden in a book or in some pen. It does not have to be big and because each sequence are unique they can be destroyed afterwards leaving no evidences.

Now creating this random sequence is not necessarily trivial. In fact we could do a whole tutorial about random number generator, but that would be out of scope for this project. So we are going to use a very simple way by randomly throwing two 6 faces regular dices. Now because we can only go from 0 to 9 if the result of the dices is equal to 10 we write 0 instead. If its above 10 we can simply re-roll.

Random Sequence1146217617762308961409301966950042202142371610054622385560577853120023

To encode we are going to separate each chunk into their individual number and add the message number with the random number bellow. If when adding a number we go above 9, we simply loop back to 0 like a clock and put the reminder. Eg: 9 + 3 = 0 + ’a reminder of 2’ = 2

First message chunk29171
First random chunk11462

The final chunk of the encoded message is 30533. We need to do this for every chunks, which gives us the following result:

30533 50235 80352 50033 35603 67705 23593 03362 41334 62476 41527 27867 99894 83659

As you can see there are no obvious pattern. The padding at the end was completely hidden, and we have no idea were a word starts and ends.

Speeding things up with python

Of course if you are in the headquarter of a secret agency preparing message for your agents on the ground you do not went to do this with pen and paper. Although the system must be simple enough to work without the help of technology, we can use a python script to quickly encode and secure the message.

msg = "2917143628141227142936302711102317101220142736293029242718102136363636" 
rnd = "1146217617762308961409301966950042202142371610054622385560577853120023"

out = ""
for i in range(0, len(msg)):
    out += str((int(msg[i]) + int(rnd[i])) % 10)

In the next tutorial we are going to convert this sequence into a sound file with a voice reading our numbers. We will then create an open WIFI allowing anyone in the range to download our secret broadcast. But only those with the key will be able to decrypt it and read its content.


Images used in this tutorial:


1 comment / Add your comment below

  1. Pretty cool explanation. I think when you describe the way to convert letter into number you could expand the alphabet and reduce the size of the message to transmit by including short common words.

    Eg: 00 = THE, 01 = WHERE, 02 = GOING, etc

    This allows to encode full word into two numbers thus compressing the amount of data that must be broadcasted.

Leave a Reply

Your email address will not be published. Required fields are marked *