n00b data encryption for save files, pt. two

Okay, as promised, I’m going to run through the encryption method I finally ended up using in Netpack. Sorry if I’m a bit short. I haven’t looked at Netpack since the final release, and I’ve since moved on to new projects.

The old encryption method would have been fine for a simple game if I gave it a little more attention, but it didn’t feel very elegant to me. Most people could have looked at the save file a few times and guessed what was going on. So I came up with a better idea. This time, the block of data would be a mass of random characters from a 10-character “alphabet,” and the game data would be tucked away in hard-coded locations. The key would also live in a hard-coded location, as a randomly arranged 10-character string using the whole alphabet.

Then I went two steps further. Why not use three alphabets and three keys from these alphabets, so each real digit from the game data is represented by one of three possible characters?

The final block now might look like this:

All the crunching takes place inside a SaveData object. In use, the only steps are to create the object and call its save or load method. For saving, the object creates its three random yet unique alphabets, creates the random block, creates three unique keys from the alphabets and inserts them into the block, and then uses the keys to convert each digit of the game data into a char and inserts it into the block.

The example below illustrates how the keys are used:

Here’s the beginning of the save() method:

And here’s the encode_block() method.

Loading is a straightforward affair in terms of extracting the right strings and translating them back into integers (actually inserting this data back into the game and getting it to load up and play properly was a different story…). The load() method looks at the existing data block, pulls out the keys from their predefined places, and sets up a dictionary of them. Using the earlier key examples, the dictionary would look like this:

Now it’s easy to run a simple loop through each pulled data string to convert each character into numbers again.

Looking at the original block above, we can now take apart the data and sort them into the game variables (and mess with our save blocks to cheat).

Data block map

Much more could be done with this to improve obfuscation, of course. Ultimately, it’s just a silly tactic I created for fun. If I ever needed to encrypt something more serious or sensitive than arcade game data, I’d find a library.

Off the top of my head, these possible improvements for my routine come to mind:

  • Use a larger block
  • Split up each digit of each data item
  • Randomize the locations of each digit and create a key (or keys) for these positions as well

I’m left wondering how most other game devs handle saving and loading game data?

Leave a Reply