MurmurHash2: различия между версиями

Материал из Википедии — свободной энциклопедии
Перейти к навигации Перейти к поиску
[отпатрулированная версия][непроверенная версия]
Содержимое удалено Содержимое добавлено
мНет описания правки
 
(не показано 25 промежуточных версий 21 участника)
Строка 1: Строка 1:
'''MurmurHash2''' - простая и быстрая хэш-функция общего назначения, разработанная Остинон Апплеби. Не является криптографически-безопасной, возвращает 32-разрядное беззнаковое число.
'''MurmurHash2''' — простая и быстрая [[хеш-функция]] общего назначения, разработанная Остином Эпплби. Не является [[Криптографическая хеш-функция|криптографически-безопасной]], возвращает 32-разрядное [[Беззнаковое число|беззнаковое]] число.


Из достоинств функции авторами отмечена простота, хорошее распределение, мощный лавинный эффект, высокая скорость и сравнительно высокая устойчивость к коллизиям. Текущие версии алгоритма оптимизированы под Intel-совместимые процессоры.
Из достоинств функции авторами отмечена простота, хорошее распределение, мощный [[лавинный эффект]], высокая скорость и сравнительно высокая устойчивость к [[Коллизия хеш-функции|коллизиям]]. Текущие версии алгоритма оптимизированы под [[Intel]]-совместимые процессоры.


== Пример кода ==
== Пример кода ==
Строка 7: Строка 7:
<source lang="C">
<source lang="C">


unsigned int MurmurHash2 ( char * key, unsigned int len)
unsigned int MurmurHash2 (char * key, unsigned int len)
{
{
const unsigned int m = 0x5bd1e995;
const unsigned int m = 0x5bd1e995;
Строка 16: Строка 16:


const unsigned char * data = (const unsigned char *)key;
const unsigned char * data = (const unsigned char *)key;
unsigned int k = 0;


while (len >= 4)
while (len >= 4)
{
{
unsigned int k;

k = data[0];
k = data[0];
k |= data[1] << 8;
k |= data[1] << 8;
Строка 35: Строка 34:
data += 4;
data += 4;
len -= 4;
len -= 4;
}
}


switch (len)
switch (len)
{
{
case 3:
case 3:
h ^= data[2] << 16;
h ^= data[2] << 16;
Строка 46: Строка 45:
h ^= data[0];
h ^= data[0];
h *= m;
h *= m;
};
};


h ^= h >> 13;
h ^= h >> 13;
Строка 56: Строка 55:
</source>
</source>


== MurmurHash 2A==
== MurmurHash 2A ==


Вторая версия хэш-функции имеет некоторые недостатки. В частности, это проблема коллизий на небольших строках. Исправленный вариант имеет структуру типа Merkle-Damgard, выполняется немного медленнее (примерно на 20%), но показывает лучшую статистику.
Вторая версия хеш-функции имеет некоторые недостатки. В частности, это проблема коллизий на небольших строках. Исправленный вариант имеет структуру типа [[Структура Меркла — Дамгора|Merkle-Damgard]], выполняется немного медленнее (примерно на 20 %), но показывает лучшую статистику.


<source lang="C">
<source lang="C">
Строка 72: Строка 71:


unsigned int h = seed;
unsigned int h = seed;
unsigned int k;


while(len >= 4)
while(len >= 4)
{
{
unsigned int k = *(unsigned int*)data;
k = *(unsigned int*)data;


mmix(h,k);
mmix(h,k);
Строка 102: Строка 102:
}
}
</source>
</source>

== MurmurHash2 — коллизии ==
Коллизи для алгоритма '''MurmurHash2''' для текста в кодировке cp866:

30f0fa9f: ПО-АВГУСТОВСКИ
ПРОЛЕПЕТАЛА


3128688e: DEADSORBIMENTO
ОБРАЩЕННОМУ


== Ссылки ==
== Ссылки ==
* [http://www.partow.net/programming/hashfunctions/#RSHashFunction Хеш-функции общего назначения]

* [http://www.partow.net/programming/hashfunctions/#RSHashFunction Хэш-функции общего назначения]
* [http://vak.ru/doku.php/proj/hash/sources Исходные тексты хеш-функций общего назначения]
* [http://vak.ru/doku.php/proj/hash/sources Исходные тексты хэш-функий общего назначения]
* [http://sites.google.com/site/murmurhash/ Страничка функции]
* [http://sites.google.com/site/murmurhash/ Страничка функции]
* [http://amsoftware.narod.ru/algo.html Статистика коллизий MurmurHash и ее модификация]
* [http://amsoftware.narod.ru/algo.html Статистика коллизий MurmurHash и её модификация]
* [http://www.strchr.com/hash_functions#results Статистика производительности популярных хеш-функций]

{{Шаблон:Хеш-алгоритмы}}


{{Хеш-алгоритмы}}
[[en:MurmurHash]]

Текущая версия от 14:16, 8 июня 2022

MurmurHash2 — простая и быстрая хеш-функция общего назначения, разработанная Остином Эпплби. Не является криптографически-безопасной, возвращает 32-разрядное беззнаковое число.

Из достоинств функции авторами отмечена простота, хорошее распределение, мощный лавинный эффект, высокая скорость и сравнительно высокая устойчивость к коллизиям. Текущие версии алгоритма оптимизированы под Intel-совместимые процессоры.

Пример кода

[править | править код]
unsigned int MurmurHash2 (char * key, unsigned int len)
{
  const unsigned int m = 0x5bd1e995;
  const unsigned int seed = 0;
  const int r = 24;

  unsigned int h = seed ^ len;

  const unsigned char * data = (const unsigned char *)key;
  unsigned int k = 0;

  while (len >= 4)
  {
      k  = data[0];
      k |= data[1] << 8;
      k |= data[2] << 16;
      k |= data[3] << 24;

      k *= m;
      k ^= k >> r;
      k *= m;

      h *= m;
      h ^= k;

      data += 4;
      len -= 4;
  }

  switch (len)
  {
    case 3:
      h ^= data[2] << 16;
    case 2:
      h ^= data[1] << 8;
    case 1:
      h ^= data[0];
      h *= m;
  };

  h ^= h >> 13;
  h *= m;
  h ^= h >> 15;

  return h;
}

Вторая версия хеш-функции имеет некоторые недостатки. В частности, это проблема коллизий на небольших строках. Исправленный вариант имеет структуру типа Merkle-Damgard, выполняется немного медленнее (примерно на 20 %), но показывает лучшую статистику.

#define mmix(h,k) { k *= m; k ^= k >> r; k *= m; h *= m; h ^= k; }

unsigned int MurmurHash2A ( const void * key, int len, unsigned int seed )
{
	const unsigned int m = 0x5bd1e995;
	const int r = 24;
	unsigned int l = len;

	const unsigned char * data = (const unsigned char *)key;

	unsigned int h = seed;
	unsigned int k;

	while(len >= 4)
	{
		k = *(unsigned int*)data;

		mmix(h,k);

		data += 4;
		len -= 4;
	}

	unsigned int t = 0;

	switch(len)
	{
	case 3: t ^= data[2] << 16;
	case 2: t ^= data[1] << 8;
	case 1: t ^= data[0];
	};

	mmix(h,t);
	mmix(h,l);

	h ^= h >> 13;
	h *= m;
	h ^= h >> 15;

	return h;
}