自定义哈希实现,长度为19位

时间:2016-07-24 01:35:07

标签: java algorithm long-integer random-seed

编辑:删除了提及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世纪长的我可以用来代。谢谢。如果不清楚,请让我澄清一下。

1 个答案:

答案 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