1

I am making a game, it will likely be built in JavaScript - but this question is rather platform agnostic...

The game involves generation of a random campaign, however to dissuade hacking and reduce the amount of storage space needed to save game (which may potentially be cloud-based) I wanted the campaign generation to be seed based.

Trying to think of ways to accomplish this, I considered an MD5 based approach. For example, lets say at the start of the game the user is given the random seed "ABC123". When selecting which level template to use for each game level, I could generate MD5 hashes...

MD5("ABC123" + "level1"); // = 3f19bf4df62494495a3f23bedeb82cce
MD5("ABC123" + "level2"); // = b499e3184b3c23d3478da9783089cc5b
MD5("ABC123" + "level3"); // = cf240d23885e6bd0228677f1f3e1e857

Ideally, there are only 16 templates. There will be more, but for the sake of demonstration if I were to take the first letter from each hash I have a random number out of 16 which I could re-produce with the same seed, forever.

Level 1 for this seed is always "3" (#3), Level 2 is always "b" (#11), Level 3 is always "c" (#12)

This approach has a few drawbacks I'm sure many will be quick to point out...

  • MD5 generation is CPU intensive, particularly if used in loops etc...
  • JavaScript doesn't come with an MD5 encryptor - you'll need to DIY...
  • That only gives you 16 numbers - or 128 if you use another number. How do you 'round' the number to your required range?
    • I considered this actually. Divide the number by the potential (16, or 128...), then multiply it by the random range needed. As long as the range remains the same, so too will the result... but that too is a constraint...

Given those drawbacks, is there a better approach which is simple, doesn't require an entire framework? In my case all I really need is an MD5 encryptor function and my implementation is basically complete.

Any advice is appreciated. I guess the "chosen answer" will be the suggestions or approach which is the most useful or practical given everything I've mentioned.

plasmacel
  • 8,183
  • 7
  • 53
  • 101
1owk3y
  • 1,115
  • 1
  • 15
  • 30
  • See the comments here: https://stackoverflow.com/a/521323/362536 – Brad Jun 10 '17 at 02:19
  • 1
    " dissuade hacking" - what do you mean on this? do you need cryptographical security? – plasmacel Jun 10 '17 at 07:20
  • Md5 is not really secure. Don't believe me? [Look at this](https://md5.gromweb.com/?md5=b499e3184b3c23d3478da9783089cc5b) – apokryfos Jun 10 '17 at 07:58
  • @apokryfos I asked to know whether he needs a cryptographically secure PRNG or not. – plasmacel Jun 10 '17 at 08:00
  • Back sorry, was unable to get to a computer for a few days. plasmacel I mean in terms of man-in-the-middle data manipulation while cloud-saving. If the game world is entirely seeded then there is no data to corrupt at save time. Cryptography itself isn't really relevant however since its mostly used for data generation rather than security in this instance. – 1owk3y Jun 13 '17 at 13:35
  • @apokryfos thanks for the guidance regarding MD5 security, however security isn't the key point of the hashing - its mostly for generating a set of predictably random data. – 1owk3y Jun 13 '17 at 13:36

1 Answers1

3

I think you overcomplicate the solution.

1) You don't need the MD5 hash. Actually since in your case there is no interest in the statistical quality of the hash, almost any hash function would be satisfactory. You can use any string hash algorithm which is cheaper to evaluate. If you only accept ASCII characters, then the Pearson hash is also an option - it is fast, simple and easy to port to any language.

2) Do you really need string seeds from the user, or a single integer seed is also acceptable? If acceptable, then you can use an integer hash function, which is significantly faster than a string hash algorithm, also very simple and easy to port.

3) Any decent pseudo-random number generator (PRNG) will give you radically different sequence with each different seed value. It means that with the increasing levels you can simply increase the seed by 1 as ++seed and generate random numbers by that. I recommend to use a custom simple and fast random number generator other than JavaScript's Math.random(). You can use some variant of xorshift.

With these 3 points all your listed drawbacks are addressed and no framework needed.

I wouldn't worry about hacking. As @apokryfos pointed out in the comments even your original solution with MD5 is not secure, and I think that level generation in games is not the best example where you need cryptography. Think about, even big title commercial games are hackable.

plasmacel
  • 8,183
  • 7
  • 53
  • 101
  • Whoa @plasmacel, amazingly indepth response! Compared with some of these alternatives using MD5 would be ludicrously inefficient. You're right, an integer hash function would be more than sufficient for my purposes. Even a basic implementation of xorshift might work - its a shame it only takes 4 integers as the seed input... but I may still be able to get that to work. Thanks again! – 1owk3y Jun 13 '17 at 13:47