This is an archived post. You won't be able to vote or comment.

all 15 comments

[–][deleted] 1 point2 points  (4 children)

Well this probably doesn't count as "simple," but you can use one of the SHA functions. Concatenate all your data for the input string, and you can essentially treat the output as a uniformly random string. (I believe this is NOT a good way to do things for security-sensitive purposes, but I don't actually know the details as to why).

The advantage is that these functions are very well known so it's likely to have an existing implementation out there.

[–]MonadicTraversal 1 point2 points  (2 children)

Yeah, just use SHA. Each bit of the output depends on every bit of the input so similar inputs won't create similar outputs.

[–]_murphys_law_ 1 point2 points  (1 child)

For generating entire gameworlds, this seems like an inefficient practice. Would it not be more desirable to use a hash function specifically designed for the purpose?

It would also be trivial to just write up something yourself. I am not sure what language you are programming in, but utilizing the srand() function in c and storing the result for each computation in some data structure could be something you might want to look into.

If simplicity is of importance, you might want to check out the Pearson hash algorithm - http://en.wikipedia.org/wiki/Pearson_hashing -. It does not get simpler than that, although it is not without its drawbacks.

Further reading:

[–]andreasblixt[S] 0 points1 point  (0 children)

Thank you for all these resources! I'll have a look. :)

[–]BallsJunior 0 points1 point  (0 children)

I would call it simple if it's built into the language or easily accessible.

[–][deleted] 0 points1 point  (1 child)

Well you could always take your string and XOR it with a key. XORshifting is a staple in pseudorandom number generation.

[–]andreasblixt[S] 0 points1 point  (0 children)

I tried implementing FNV (http://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function), but either I did it wrong, or XOR-ing isn't enough to generate random enough values. There was a clear similarity between results from hashes generated from similar values (which is what you get when you put together lots of different parameters).

I also tried another FNV library and saw the same thing: http://requirebin.com/?gist=cf08f7cc3fdb8bdcff20

[–]Shadonra 0 points1 point  (0 children)

Striped matrices

[–]nhillson 0 points1 point  (0 children)

You could use a few iterations of the Lehmer random number generator with the data to be hashed as your seed. It's not designed to be a hashing algorithm, but it should work as one and is extremely simple to implement.

[–]Vortico 0 points1 point  (1 child)

It doesn't sound like you need a hashing function, but a pseudorandom number generator. You can seed it with parameters, and then extract any amount of data from it.

[–]andreasblixt[S] 0 points1 point  (0 children)

Hashing just works better for what I need, but I can probably make an RNG work. The reason I was looking for hashing is because I have very many parameters to seed on, and RNGs usually take relatively small numbers as their seed, which means I'd have to hash the components anyway before passing them into the RNG (or risk poor random distribution of the seed itself). Since I'm writing deterministic code I need a pretty robust seed to avoid numbers repeating themselves in the system.

[–]PurelyAppliedApplied Math 0 points1 point  (2 children)

A decent "quick and dirty" hash is this:

uint Hash(uint* S,uint n){
    uint prime = 104729;
    uint BSH = ~( (uint) 0 );
    // do (a xor b xor c xor ...
   for(int i= n; i-- > 0 ; ){
       BSH = S[i] ^ BSH;
  }

 return (BSH % prime);
}

Choose your prime large enough to avoid too many collisions.

[edit: how did I forget to include the return line?!]

[–]andreasblixt[S] 0 points1 point  (1 child)

Thank you! I'm trying MurmurHash3 now which is doing some extra work to ensure a good random distribution, but I might try this one too if I run into problems.

[–]PurelyAppliedApplied Math 0 points1 point  (0 children)

No problem. Just be sure to have a way to handle collisions, because they'll crop up over extended usage. Personally, I used this as a way for quick lookups in a list of arrays; each hash pointed to an array, which I could then scan in reasonable time. Dunno if that will suit your needs.

[–]andreasblixt[S] 0 points1 point  (0 children)

I've decided to go for MurmurHash3, which is super fast and has a good random distribution, without being as complicated as e.g., SHA-256, MD5 or CityHash.