Хорошая хеш-функция для строк

Этот ответ потерпит неудачу, если value = 1.005.

В качестве лучшего решения проблему округления можно избежать, используя числа, представленные в экспоненциальном обозначении:

Number(Math.round(1.005+'e2')+'e-2').toFixed(2); // 1.01

Кредит: Деление на округление в JavaScript

142
задан Bart 23 March 2013 в 11:11
поделиться

7 ответов

Обычно хеши не суммируют, иначе стоп и горшки будут иметь одинаковый хеш.

, и вы не ограничиваете его первыми n символами, потому что в противном случае дом и дома имели бы одинаковый хэш.

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

int hash = 7;
for (int i = 0; i < strlen; i++) {
    hash = hash*31 + charAt(i);
}
151
ответ дан 23 November 2019 в 22:28
поделиться

Если вы делаете это на Java, то зачем вы это делаете? Просто вызовите .hashCode () в строке

17
ответ дан 23 November 2019 в 22:28
поделиться

Если вы хотите увидеть реализации отраслевого стандарта, я бы посмотрел на java.security.MessageDigest .

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

3
ответ дан 23 November 2019 в 22:28
поделиться
// djb2 hash function
unsigned long hash(unsigned char *str)
{
    unsigned long hash = 5381;
    int c;

    while (c = *str++)
        hash = ((hash << 5) + hash) + c; /* hash * 33 + c */

    return hash;
}

источник Логика djb2 хеш-функция - SO

5
ответ дан 23 November 2019 в 22:28
поделиться

Вероятно, вам следует использовать String.hashCode () .

Если вы действительно хотите реализовать hashCode самостоятельно:

Не поддавайтесь искушению исключить важные части объекта из вычисления хэш-кода, чтобы повысить производительность - - Джошуа Блох, Эффективная Java

Использование только первых пяти символов - плохая идея . Подумайте об иерархических именах, таких как URL-адреса: все они будут иметь один и тот же хэш-код (потому что все они начинаются с «http: //», что означает, что они хранятся в одном сегменте в хеш-карте, демонстрируя ужасную производительность.

Вот история войны, перефразированная на строковом хэш-коде из « Эффективная Java »:

Хэш-функция String реализована во всех проверенных выпусках до 1.2 не более шестнадцать символов, равномерно расположенных по всей строке, начиная с с первого символа. Для больших коллекций иерархических имен , таких как URL-адреса, эта хеш-функция { {1}} демонстрировал ужасное поведение.

37
ответ дан 23 November 2019 в 22:28
поделиться

Если речь идет о безопасности, можно использовать Java crypto:

import java.security.MessageDigest;

MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
messageDigest.update(stringToEncrypt.getBytes());
String encryptedString = new String(messageDigest.digest());
133
ответ дан 23 November 2019 в 22:28
поделиться

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

Для длинных строк (длиннее, чем, скажем, около 200 символов) можно получить хорошую производительность от хэш-функции MD4. Как криптографическая функция она была сломана около 15 лет назад, но для некриптографических целей она все еще очень хороша и удивительно быстра. В контексте Java вам придется преобразовывать 16-битные значения char в 32-битные слова, например, группируя такие значения в пары. Быструю реализацию MD4 в Java можно найти в sphlib. Вероятно, это излишество в контексте классного задания, но попробовать стоит.

5
ответ дан 23 November 2019 в 22:28
поделиться
Другие вопросы по тегам:

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