Пользовательская реализация хэша для 19-значного числа

Изменить: удалено упоминание 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-значное число, которое я могу использовать для генерации. Спасибо. Пожалуйста, попросите меня прояснить что-то, если это неясно.


person Kartik Chugh    schedule 24.07.2016    source источник
comment
Ошибаетесь, hashCode() выдает int, а не long.   -  person user207421    schedule 24.07.2016
comment
Это правильно, я исправил это сейчас.   -  person Kartik Chugh    schedule 24.07.2016


Ответы (1)


Прежде всего, hashCode() возвращает int, а не long, поэтому переопределение hashCode() невозможно.

Если вы хотите сгенерировать 19-значное (т.е. 64-битное) числовое значение из String, вероятно, самый простой способ — использовать java.security.MessageDigest для «хэширования» строки в MD5, SHA1 или SHA256, извлечь 64 бита и преобразовать в long с помощью , один из методов, описанных в этом ответе StackOverflow. .

Имейте в виду, что без настройки это возвращает значение от -263 до +263-1, поэтому вам, вероятно, нужно убедиться, что бит знака выключен. Также обратите внимание, что в некоторых значениях может быть не ровно 19 десятичных цифр, так как пространство результатов включает все числа от 0 до +263-1. Из этого диапазона 10% имеют один или несколько начальных нулей, поэтому, если вы всегда хотите 19 цифр, вам нужно будет сохранить начальные нули или уменьшить диапазон до 0..1018-1 и добавить 10< суп>18.

person Jim Garrison    schedule 24.07.2016