Java конвертировать хэш в случайную строку - PullRequest
6 голосов
/ 20 февраля 2012

Я пытаюсь разработать функцию сокращения для использования в генераторе радуги.

Основной принцип функции редукции заключается в том, что она принимает хеш, выполняет некоторые вычисления и возвращает строку определенной длины.

В данный момент я использую хэши SHA1, и мне нужно вернуть строку длиной три. Мне нужно, чтобы строка была составлена ​​из любых трех случайных символов из:

abcdefghijklmnopqrstuvwxyz0123456789

Основная проблема, с которой я сталкиваюсь, заключается в том, что любая функция редукции, которую я пишу, всегда возвращает строки, которые уже были сгенерированы. А хорошая функция сокращения редко будет возвращать дублирующиеся строки.

Может ли кто-нибудь предложить какие-либо идеи о способе достижения этой цели? Или любые предложения по манипулированию хешами для строк были бы хорошими.

Заранее спасибо

Джош

Ответы [ 2 ]

6 голосов
/ 20 февраля 2012

Похоже, у вас есть 20 цифр базы 255 (длина хеша SHA1), которые вам нужно отобразить на три цифры базы 36. Я бы просто сделал BigInteger изхэш-байты, модуль 36 ^ 3 и возвращаем строку в базе 36.

public static final BigInteger N36POW3 = new BigInteger(""+36*36*36));
public static String threeDigitBase36(byte[] bs) {
  return new BigInteger(bs).mod(N36POW3).toString(36);
}
// ...
threeDigitBase36(sha1("foo")); // => "96b"
threeDigitBase36(sha1("bar")); // => "y4t"
threeDigitBase36(sha1("bas")); // => "p55"
threeDigitBase36(sha1("zip")); // => "ej8"

Конечно, будут столкновения, как при преобразовании любого пространства в меньшее, ноэнтропия должна быть лучше, чем что-то еще глупее, чем приведенное выше решение.

4 голосов
/ 20 февраля 2012

Применение принципа KISS :

  • SHA - это просто строка
  • Хеш-код JDK для String является "достаточно случайным"
  • Integer может отображаться в любой базе

Эта единственная строка кода делает это:

public static String shortHash(String sha) {
    return Integer.toString(sha.hashCode() & 0x7FFFFFFF, 36).substring(0, 3);
}

Примечание: & 0x7FFFFFFF - обнулить знаковый бит (хеш-коды могут быть отрицательными числами, которые в противном случае отображались бы с ведущим знаком минус)хэш int меньше 100 (основание 36) - это означает, что он напечатает менее 3 символов.Этот код исправляет это, сохраняя значение «random».Он также избегает вызова substring(), поэтому производительность должна быть лучше.

static int min = Integer.parseInt("100", 36);
static int range = Integer.parseInt("zzz", 36) - min;

public static String shortHash(String sha) {
    return Integer.toString(min + (sha.hashCode() & 0x7FFFFFFF) % range, 36);
}

Этот код гарантирует, что конечный хэш имеет 3 символа, заставляя его быть между 100 и zzz - самым низким исамый высокий хэш из 3-х символов в базе 36, но все еще делающий его «случайным».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...