You can copy the initial permutation idea from the Perlin noise: basically, you have a permanent 256-sized array which points to a numbers from 0 to 255, call it "permutations". Then your "random" hash number at a specific **integer** point would be:

int X = (int)Math.floor(x) & 255; int Y = (int)Math.floor(y) & 255; int Z = (int)Math.floor(z) & 255; int hash = permutations[X]; hash = permutations[hash + Y]; hash = permutations[hash + Z];

Also the trick is to expand the 256-sized array and clone the copy of the same numbers to the second half, so you don't need to check for array overflow when adding the coordinates.

You get more variations by interpolating between these values and blending more noises at different scales.

Perlin noise is here: http://mrl.nyu.edu/~perlin/noise/. 3D Perlin noise additionally interpolates between 12 points, plus 4 point simplex shape.

Although you would want to use improved Perlin noise, which uses 4 point simplex for 3D and 3 point triangle for 2D, which is aptly called Simplex Noise.