编辑:删除了提及hashCode()
我正在研究基于种子的地形生成器,这样如果用户在文本字段中输入特定的字符串,它每次都会产生相同的世界。我计划这样做的方法是使用一种产生19位长的长度(双关语)的算法。然后,程序将利用某些指数的值,或某些指标的值的组合,以及其他计算来设定世界的某些方面,如生物群落,振幅和方差。实质上,每当输入相同的种子时,算法将产生相同的内部19位长,并因此产生相同的世界。
如何创建一个自定义散列方法,为每个输入值生成一个19位长的?之前,我正在使用它:
private void generate() {
long[] seedBuilder = new long[5]; // So I can print certain parts of the process for debugging purposes
String clientSeed = seedField.getText(); // The input aka seed
if (clientSeed.equals("")) clientSeed = String.valueOf(System.currentTimeMillis()); // use time if none is given
// Basic hash of seed
seedBuilder[0] = (long)clientSeed.hashCode();
// primary-char hash * concluding-char hash (for reducing collisions)
long comboID = clientSeed.substring(0,1).hashCode() * clientSeed.substring(clientSeed.length()-1).hashCode();
// Basic hash * comboID
seedBuilder[1] = seedBuilder[0] * comboID;
// Absolute value
seedBuilder[2] = Math.abs(seedBuilder[1]);
// Raised to the 1.27
seedBuilder[3] = (long)(Math.pow(seedBuilder[2], 1.27));
// Multiplied by 10.1 until digits = 19
seedBuilder[4] = (long)(Math.pow(9.9,(19-(seedBuilder[3]+"").length())) * seedBuilder[3]);
long generator = seedBuilder[4]
}
基本上,我通过大量实验得到了这个。 1.27的功率是任意选择的,9.9只是因为10.1以上的任何东西都可以产生Long.MAX_VALUE,但我仍然希望获得19位数。问题是一些暴力随机串测试显示分布真的不均匀; 60%的结果(又名seedBuilder [4])从3或4开始,6或7作为第一个指数值出现,如5%的时间,我相信我没记错。无论第一个指数控制的世界哪个方面在很多时候都是相同的。
我想用一种不那么随意,更专业,更安全的方式来制作一个19世纪长的我可以用来代。谢谢。如果不清楚,请让我澄清一下。
答案 0 :(得分:0)
首先,hashCode()
返回int
,而不是long
,因此覆盖hashCode()
已经结束。
如果要从String
生成19位(即64位)数值,可能最简单的方法是使用java.security.MessageDigest
来"哈希"字符串到MD5,SHA1或SHA256,提取64位并使用this StackOverflow answer中描述的技术之一转换为long
。
请注意,如果不进行调整,则会返回-2 63 和+2 63 -1之间的值,因此您可能希望确保符号位为关闭。然后还要注意,某些值可能没有正好19个十进制数字,因为结果空间包含0到+2 63 -1之间的所有数字。在该范围内,10%具有一个或多个前导零,因此如果您总是需要19位数,那么您将需要保留前导零或将范围缩小到0..10 18 -1并添加10 < SUP> 18