其他要求:
函数的输入是两个数字,不一定是整数
速度是主要问题;它应该尽可能快
不必是安全的,只要它的输出看起来足够随机。
例子:
getValue(0,0) -> 0.326458921
getValue(100,30) -> 0.598713621
getValue(5.12687, 600.471536) -> 0.21458796
编辑 澄清:输出值应该是确定性的,但看起来是随机的。
其他要求:
函数的输入是两个数字,不一定是整数
速度是主要问题;它应该尽可能快
不必是安全的,只要它的输出看起来足够随机。
例子:
getValue(0,0) -> 0.326458921
getValue(100,30) -> 0.598713621
getValue(5.12687, 600.471536) -> 0.21458796
编辑 澄清:输出值应该是确定性的,但看起来是随机的。
不知道这是否符合您的需求,这只是我自发的一个想法(使用 Java 的 String.hashCode() 的 JavaScript 实现,取自该网站:http ://werxltd.com/wp/2010/05/ 13/javascript-implementation-of-javas-string-hashcode-method/ )
<script>
String.prototype.hashCode = function(){
var hash = 0;
if (this.length == 0) return hash;
for (i = 0; i < this.length; i++) {
char = this.charCodeAt(i);
hash = ((hash<<5)-hash)+char;
hash = hash & hash; // Convert to 32bit integer
}
return hash;
}
function hash(x, y) {
var hash = Math.abs((x + "" + y).hashCode())
return hash / Math.pow(10, (hash + "").length);
}
alert(hash(5.12687, 600.471536));
</script>
unsigned int hash(int key) {
key +=~(key << 15);
key ^=(key >> 10);
key +=(key << 3);
key ^=(key >> 6);
key +=~(key << 11);
key ^=(key >> 16);
return key;
}
unsigned int localseed = hash(x^hash(y^baseSeed));
这使用 baseSeed 值,但这是可选的。基本上从 x/y 坐标创建散列。
你可以写一个哈希函数:
function hash(x, y) {
// You cast the int parts and decimal parts of your entries as 16-bits signed integers.
var xi = x & 0xFFFF;
var xf = (((x-xi) * (1 << 16)) & 0xFFFF);
var yi = y & 0xFFFF;
var yf = (((y-yi) * (1 << 16)) & 0xFFFF);
// You hash theses numbers
var r1 = ((39769 * xi) & 0xFFFF);
r1 = ((r1 + xf) * 23747) & 0xFFFF;
r1 = ((r1 + yi) * 19073) & 0xFFFF;
r1 = ((r1 + yf) * 25609) & 0xFFFF;
var r2 = ((25609 * xf) & 0xFFFF);
r2 = ((r2 + yf) * 39769) & 0xFFFF;
r2 = ((r2 + xi) * 23747) & 0xFFFF;
r2 = ((r2 + yi) * 19073) & 0xFFFF;
// And returns a floating number between 0 and 1.
return ((r1&0xFF)/(1<<24)) + ((r2&0xFFFF)/(1<<16));
}
这个函数对每个 65536 进行包装,因为我只保留了 int 部分的前 16 位,但想法就在这里,你可以修改散列函数。更好的方法是:
var arrayBuffer = new ArrayBuffer(8);
var dataView = new DataView(arrayBuffer);
function hash(x, y) {
dataView.setFloat32(0, x);
dataView.setFloat32(4, y);
var xi = dataView.getUint16(0);
var xf = dataView.getUint16(2);
var yi = dataView.getUint16(4);
var yf = dataView.getUint16(6);
// You hash theses numbers
var r1 = ((39769 * xi) & 0xFFFF);
r1 = ((r1 + xf) * 23747) & 0xFFFF;
r1 = ((r1 + yi) * 19073) & 0xFFFF;
r1 = ((r1 + yf) * 25609) & 0xFFFF;
var r2 = ((25609 * xf) & 0xFFFF);
r2 = ((r2 + yf) * 39769) & 0xFFFF;
r2 = ((r2 + xi) * 23747) & 0xFFFF;
r2 = ((r2 + yi) * 19073) & 0xFFFF;
// And returns a floating number between 0 and 1.
dataView.setUint16(0, r1);
dataView.setUint16(2, r2);
return Math.abs(dataView.getFloat32(0) % 1);
}
最后一种方法使用 WebGL TypedArray
,它可以让您访问您的条目的位,并有更好的散列方式。但是,根据我的经验,这真的很慢(我的计算机上的第一种方法每秒 8 亿次调用,第二种方法只有 200 万次 - 作为参考,经典的随机函数是 2 亿次调用/秒),而 WebGL 可能并非在所有浏览器上都可用。