Вероятность 64-битных коллизий хэш-кода

книга численных рецептов предлагает метод расчета 64-битных хэш-кодов для уменьшения количества столкновений.

алгоритм показан на http://www.javamex.com/tutorials/collections/strong_hash_code_implementation_2.shtml и скопировано здесь для справки:

private static final createLookupTable() {
  byteTable = new long[256];
  long h = 0x544B2FBACAAF1684L;
  for (int i = 0; i < 256; i++) {
    for (int j = 0; j < 31; j++) {
      h = (h >>> 7) ^ h;
      h = (h << 11) ^ h;
      h = (h >>> 10) ^ h;
    }
    byteTable[i] = h;
  }
  return byteTable;
}

public static long hash(CharSequence cs) {
  long h = HSTART;
  final long hmult = HMULT;
  final long[] ht = byteTable;
  final int len = cs.length();
  for (int i = 0; i < len; i++) {
    char ch = cs.charAt(i);
    h = (h * hmult) ^ ht[ch & 0xff];
    h = (h * hmult) ^ ht[(ch >>> 8) & 0xff];
  }
  return h;
}

мои вопросы:

1) существует ли формула для оценки вероятности столкновений с учетом так называемого дня рождения Парадокс?

2) Можете ли вы оценить вероятность столкновения (i.e два ключа, которые хэшируют одно и то же значение)? Скажем, с 1000 ключами и с 10000 ключами?

редактировать: изменить/исправить Вопрос 3

3) Можно ли с уверенностью предположить, что столкновение разумного количества ключей (скажем, менее 10 000 ключей) настолько маловероятно, что если 2 хэш-кода одинаковы, мы можем сказать, что ключи одинаковы без какой-либо дополнительной проверки? например,

static boolean equals(key1, key2) {

  if (key1.hash64() == key2.hash64())
    return true;  // probability of collision so low we don't need further check

  return false;
}

это не для безопасности, но скорость выполнения является обязательным, поэтому избежать дальнейших проверок ключей сэкономит время. Если вероятность настолько низка, скажем, меньше (1 из 1 миллиарда для 100 000 ключей), это, вероятно, будет приемлемо.

ТИА!

4 ответов


существует ли формула для оценки вероятности столкновений с учетом так называемого парадокса дня рождения?

использование формулы парадокса дня рождения просто говорит вам, в какой момент вам нужно начать беспокоиться о столкновении. Это примерно Sqrt[n] здесь n - общее количество возможных хэш-значений. В этом случае n = 2^64 таким образом, формула парадокса дня рождения говорит вам, что до тех пор, пока количество ключей значительно меньше чем Sqrt[n] = Sqrt[2^64] = 2^32 или примерно 4 миллиарда, вам не нужно беспокоиться о столкновениях. Чем выше n, тем точнее эта оценка. На самом деле вероятность p(k) что столкновение произойдет с k клавиши приближаются к функции шага как n становится больше, где шаг происходит при k=Sqrt[n].


можете ли вы оценить вероятность столкновения (i.e два ключа, которые хэшируют одно и то же значение)? Скажем, с 1,000 ключами и с 10,000 ключи?

предполагая, что хэш-функция равномерно распределена, легко получить формулу.

p(no collision for k keys) = 1 * (n-1)/n * (n-2)/n * (n-3)/n * ... * (n-(k-1))/n

эта формула непосредственно следует из начала с 1 ключа: вероятность отсутствия столкновения с 1 ключом, конечно, 1. Вероятность отсутствия столкновения с 2 ключами 1 * (n-1)/n. И так далее для всех k ключи. Удобно, Mathematica имеет Pochhammer[]


существует ли формула для оценки вероятности столкновений с учетом так называемого парадокса дня рождения?

посмотреть: день рождения атака.

предполагая, что распределение хэшей равномерно, вероятность столкновения для n ключи приблизительно n2/265.

это с уверенностью предположить, что столкновение разумного количества ключей (скажем, менее 10 000 ключей) настолько невероятно, что если 2 хэш-кода разные, мы можем сказать, что ключи разные без какой-либо дополнительной проверки?

это безопасно только при использовании криптографической хэш-функции. Даже если вы можете допустить ошибку каждые 3*1011 раз, возможно, вам придется рассмотреть возможность того, что вход специально построен для создания хэш-столкновения, как атаки на вашу программу.


Я дам приблизительное приближение к точным формулам, приведенным в других ответах; приближение может помочь вам ответить #3. Грубая аппроксимация заключается в том, что вероятность столкновения с K ключами и n возможными хэш-значениями с хорошим алгоритмом хэширования составляет приблизительно (k^2)/2n, для k

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


1) существует ли формула для оценки вероятности возникновения столкновений учитывая так называемый парадокс дня рождения?

вероятность одного столкновения зависит от набора ключей, сгенерированного как хэш-функция однородна мы можем сделать следующее, Чтобы вычислить вероятность того, что столкновение не происходит при генерации K ключей следующим образом: -

x = hash size
p(k=2) = (x-1)/x
p(k=3) = p(k=2)*(x-2)/x
..
p(k=n) = (x-1)*(x-2)..(x-n+1)/x^n

p(k=n) ~ e^-(n*n)/2x

p(collision|k=n) = 1-p(k=n) = 1 - e^(-n^2)/2x
p(collision) > 0.5 if n ~ sqrt(x)

следовательно, если sqrt(2^64) ключи, что составляет 2^32 ключ генерируется есть больше шансов, что произойдет одно столкновение.

2) Можете ли вы оценить вероятность столкновения (i.e два ключа, которые хэш с тем же значением)? Скажем, с 1,000 ключами и с 10,000 ключи?

x = 2^64 
Use the formula pc(k=n) = 1 - e^-(n^2)/2x

3) Можно ли предположить, что столкновение разумного количества ключи (скажем, менее 10 000 ключей) настолько невероятны, что если 2 хэша коды одинаковы мы можем сказать, что ключи одинаковы без каких-либо дальше проверка?

это очень интересный вопрос, потому что он зависит от размера клавиши "пробел". Предположим, Ваши ключи генерируются случайным образом из пространства size = s и хэш-пространства x=2^64 как вы упомянули. Вероятность столкновения Pc(k=n|x) = 1-e^(-n^2)/2x. Если вероятность выбора одного и того же ключа в пространстве ключей P(k=n|s) = 1-e^(-n^2)/2s . Для того, чтобы быть уверенным, что если хэш одинаковый, то ключи одинаковы: -

P(k=n|s) > Pc(k=n|x)
1-e^-(n^2/2s) > 1-e^-(n^2/2x) 
n^2/2s > n^2/2x 
s < x
s < 2^64

следовательно, он показывает, что для ключей должно быть одинаковым, если хэш такой же, что размер набора ключей должно быть меньше, чем 2^64 approx в противном случае существует вероятность столкновения в хэше больше, чем в наборе ключей. Результат не зависит от количества сгенерированных ключей.