Как я генерирую хэш-код от массива байтов в C#?

Вы используете целочисленное деление.

Вместо этого попробуйте 7.0/10.

47
задан Peter Mortensen 26 June 2015 в 01:24
поделиться

9 ответов

Хэш-код объекта не должен быть уникальным.

правило проверки:

  • хэш-коды равны? Тогда назовите полное (медленным) Equals метод.
  • разве хэш-коды не равны? Тогда эти два объекта определенно не равны.

Все, что Вы хотите, GetHashCode алгоритм, который разделяет Ваш набор на примерно даже группы - это не должно формировать ключ, поскольку HashTable или Dictionary<> должен будет использовать хеш для оптимизации извлечения.

, Сколько времени Вы ожидаете, что данные будут? Как случайный? Если длины варьируются значительно (скажите для файлов), тогда просто возвратите длину. Если длины, вероятно, будут подобным взглядом на подмножество байтов, которое варьируется.

GetHashCode должно быть намного более быстрым, чем Equals, но не должен быть уникальным.

Две идентичных вещи никогда не должны иметь различные хэш-коды. Два различных объекта не должны иметь тот же хэш-код, но некоторые коллизии должны ожидаться (в конце концов, существует больше перестановок, чем возможные целые числа на 32 бита).

59
ответ дан stakx supports GoFundMonica 26 November 2019 в 19:21
поделиться

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

Здесь Вы идете... Измененный Хеш FNV в C#

http://bretm.home.comcast.net/hash/6.html

    public static int ComputeHash(params byte[] data)
    {
        unchecked
        {
            const int p = 16777619;
            int hash = (int)2166136261;

            for (int i = 0; i < data.Length; i++)
                hash = (hash ^ data[i]) * p;

            hash += hash << 13;
            hash ^= hash >> 7;
            hash += hash << 3;
            hash ^= hash >> 17;
            hash += hash << 5;
            return hash;
        }
    }
49
ответ дан 26 November 2019 в 19:21
поделиться

Одалживая у кода, сгенерированного программным обеспечением JetBrains, я обосновался на этой функции:

    public override int GetHashCode()
    {
        unchecked
        {
            var result = 0;
            foreach (byte b in _key)
                result = (result*31) ^ b;
            return result;
        }
    }

проблема только с XOring байты - то, что 3/4 (3 байта) возвращенного значения имеет только 2 возможных значения (все на или все прочь). Это распространяет биты вокруг немного больше.

Установка точки останова в Равняется, было хорошее предложение. При добавлении приблизительно 200 000 записей моих данных к Словарю, занимается 10, Равняется вызовам (или 1/20,000).

12
ответ дан 26 November 2019 в 19:21
поделиться

Вы имеете по сравнению с SHA1CryptoServiceProvider. Метод ComputeHash ? Это берет массив байтов и возвращает хеш SHA1, и я полагаю, что это вполне прилично оптимизировано. Я использовал его в Обработчик Identicon , который работал вполне прилично при загрузке.

3
ответ дан Jon Galloway 26 November 2019 в 19:21
поделиться

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

самым простым хешем, который я когда-либо изучал, был просто XORing все байты вместе. Это легко, быстрее, чем большинство сложных хеш-алгоритмов и промежуточный достойный хеш-алгоритм общего назначения для небольших наборов данных. Это - Пузырьковая сортировка хеш-алгоритмов действительно. Так как простая реализация оставила бы Вас с 8 битами, это - только 256 хешей... не настолько горячих. Вы могли блоки XOR вместо individal байтов, но тогда алгоритм становится намного более сложным.

Поэтому, конечно, криптографические алгоритмы, возможно, делают некоторый материал, в котором Вы не нуждаетесь..., но они - также огромный шаг в качестве хеша общего назначения. Хеш MD5, который Вы используете, имеет 128 битов с миллиардами и миллиардами возможных хешей. Единственным путем Вы, вероятно, доберетесь, что-то лучше должно взять некоторые репрезентативные пробы данных, которые Вы ожидаете проходить свое приложение и пробовать различные алгоритмы на нем для наблюдения, сколько коллизий Вы добираетесь.

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

1
ответ дан Lee 26 November 2019 в 19:21
поделиться

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

1
ответ дан denis phillips 26 November 2019 в 19:21
поделиться

Хотите ли Вы идеальный hashfunction (различное значение для каждого объекта, который оценивает для равенства), или просто довольно хороший всегда является компромиссом производительности, обычно требуется время для вычисления хорошего hashfunction и если набор данных является небольшим, Вы лучше из с быстрой функцией. Самой важной (поскольку Ваше второе сообщение указывает) является правильность, и достигнуть этого всего Вам нужно, должен возвратить Длину массива. В зависимости от Вашего набора данных, который мог бы даже быть в порядке. Если это не (скажите, что все Ваши массивы одинаково долги), можно пойти с чем-то дешевым как рассмотрение первого и последнего значения и XORing их значения и затем добавить больше сложности, поскольку Вы считаете целесообразным для своих данных.

А быстрый способ видеть, как Ваш hashfunction работает на Ваших данных, состоит в том, чтобы добавить все данные к хеш-таблице и рассчитать, количество раз Равняется функции, назван, если это слишком часто, у Вас есть больше работы, чтобы сделать на функции. Если Вы делаете это просто имеет в виду, что размер хеш-таблицы должен быть установлен больше, чем Ваш набор данных, когда Вы запускаете, иначе Вы собираетесь перефразировать данные, которые инициируют, повторно вставляет, и больше Равняется оценкам (хотя возможно более реалистичный?)

Для некоторых объектов (не этот) быстрый HashCode может быть сгенерирован ToString ().GetHashCode (), конечно, не оптимальный, но полезный, поскольку люди склонны возвращать что-то близко к идентификационным данным объекта из ToString (), и это точно, что GetHashcode ищет

Мелочи: худшая производительность, которую я когда-либо видел, состояла в том, когда кто-то по ошибке возвратил константу из GetHashCode, легкого определить с отладчиком, хотя, особенно если Вы делаете много поисков в Вашей хеш-таблице

1
ответ дан Daniel Daranas 26 November 2019 в 19:21
поделиться

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

я не знаю C# вообще, и я не знаю, может ли он связаться с C, но здесь его реализация в C.

1
ответ дан Peter Mortensen 26 November 2019 в 19:21
поделиться

RuntimeHelpers. GetHashCode мог бы помочь:

Из MSDN:

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

0
ответ дан jfs 26 November 2019 в 19:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: