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

Я пытаюсь придумать хорошую hash-функцию для строк. И я подумал, что может быть хорошей идеей суммировать значения unicode для первых пяти символов в строке (при условии, что у нее пять, иначе остановитесь, где она закончится). Будет ли это хорошей идеей, или это плохо?

Я делаю это на Java, но я бы не подумал, что это будет иметь большое значение.

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

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

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

 int hash = 7; for (int i = 0; i < strlen; i++) { hash = hash*31 + charAt(i); } 

Если это вещь безопасности, вы можете использовать криптографию Java:

 import java.security.MessageDigest; MessageDigest messageDigest = MessageDigest.getInstance("SHA-256"); messageDigest.update(stringToEncrypt.getBytes()); String encryptedString = new String(messageDigest.digest()); 

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

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

Не пытайтесь исключить значимые части объекта из вычисления хеш-кода для повышения производительности – Joshua Bloch, Effective Java

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

Вот история войны, перефразируемая на String hashCode из « Эффективной Java »:

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

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

HashFunction Guava ( javadoc ) обеспечивает приличное не-крипто-сильное хеширование.

Эта функция, предоставленная Ником, хороша, но если вы используете новую String (byte [] bytes) для преобразования в String, она не удалась. Вы можете использовать эту функцию для этого.

 private static final char[] hex = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; public static String byteArray2Hex(byte[] bytes) { StringBuffer sb = new StringBuffer(bytes.length * 2); for(final byte b : bytes) { sb.append(hex[(b & 0xF0) >> 4]); sb.append(hex[b & 0x0F]); } return sb.toString(); } public static String getStringFromSHA256(String stringToEncrypt) throws NoSuchAlgorithmException { MessageDigest messageDigest = MessageDigest.getInstance("SHA-256"); messageDigest.update(stringToEncrypt.getBytes()); return byteArray2Hex(messageDigest.digest()); } 

Может быть, это может помочь кому-то

 // 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; } 

источник Логика за hash-функцией djb2 - SO

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

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

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

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

sdbm: этот алгоритм был создан для библиотеки баз данных sdbm (публичная редоментация ndbm)

 static unsigned long sdbm(unsigned char *str) { unsigned long hash = 0; int c; while (c = *str++) hash = c + (hash << 6) + (hash << 16) - hash; return hash; } 

вот ссылка, которая объясняет много разных hash-функций, поскольку теперь я предпочитаю хеш-функцию ELF для вашей конкретной проблемы. В качестве входной информации берется строка произвольной длины.

  public String hashString(String s) throws NoSuchAlgorithmException { byte[] hash = null; try { MessageDigest md = MessageDigest.getInstance("SHA-256"); hash = md.digest(s.getBytes()); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } StringBuilder sb = new StringBuilder(); for (int i = 0; i < hash.length; ++i) { String hex = Integer.toHexString(hash[i]); if (hex.length() == 1) { sb.append(0); sb.append(hex.charAt(hex.length() - 1)); } else { sb.append(hex.substring(hex.length() - 2)); } } return sb.toString(); } 

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

  int k = key.length(); int sum = 0; for(int i = 0 ; i < k-1 ; i++){ sum += key.charAt(i)<<(5*i); } 

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

 int keyHash(string key) { unsigned int k = (int)key.length(); unsigned int u = 0,n = 0; for (Uint i=0; i 

другое, что вы можете сделать, это умножение каждого символа int parse на индекс по мере его увеличения, как слово «медведь» (0 * b) + (1 * e) + (2 * a) + (3 * r), который даст вам значение int, с которым можно играть. первая хеш-функция выше сталкивается при «здесь» и «слышит», но все же отлично подходит для получения хороших уникальных значений. одно ниже не сталкивается с «здесь» и «слышит», потому что я умножаю каждый символ с индексом по мере его увеличения.

 int keyHash(string key) { unsigned int k = (int)key.length(); unsigned int u = 0,n = 0; for (Uint i=0; i 

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

 int generatehashkey(const char *name) { int x = tolower(name[0])- 97; if (x < 0 || x > 25) x = 26; return x; } 

Что это в основном делает, слова hashируются в соответствии с их первым письмом. Итак, слово, начинающееся с ‘a’, получит hash-ключ из 0, ‘b’, который получит 1 и так далее, а ‘z’ будет 25. Числа и символы будут иметь hash-ключ из 26. Это преимущество, которое обеспечивает ; Вы можете легко и быстро вычислить, где данное слово будет индексироваться в хеш-таблице, так как все в алфавитном порядке, что-то вроде этого: Код можно найти здесь: https://github.com/abhijitcpatil/general

Давая следующий текст в качестве входного сигнала: Аттик сказал Джему однажды: «Я бы предпочел, чтобы ты выстрелил в жестяные банки на заднем дворе, но я знаю, что ты пойдешь за птицами. Стреляйте в все голубые сойки, которые вы хотите, если можете ударить их, но помните, что грех убить пересмешника. Это был единственный раз, когда я слышал, что Аттик сказал, что грех что-то сделать, и я спросил мисс Моди Это. «Твой отец прав», – сказала она. «Пересмешники не делают ничего, кроме музыки для нас, чтобы наслаждаться. Они не едят народные сады, не гнездятся в кукурузных хлопьях, они не делают ничего, кроме как петь их сердца для нас. Вот почему грех убивать пересмешника.

Это будет выход:

 0 --> aa about asked and a Atticus aa all after at Atticus 1 --> but but blue birds. but backyard 2 --> cribs corn can cans 3 --> do don't don't don't do don't do day 4 --> eat enjoy. except ever 5 --> for for father's 6 --> gardens go 7 --> hearts heard hit 8 --> it's in it. I it I it's if I in 9 --> jays Jem 10 --> kill kill know 11 --> 12 --> mockingbird. music make Maudie Miss mockingbird.” 13 --> nest 14 --> out one one only one 15 --> people's 16 --> 17 --> right remember rather 18 --> sin sing said. she something sin say sin Shoot shot said 19 --> to That's their thing they They to thing to time the That to the the tin to 20 --> us. up us 21 --> 22 --> why was was want 23 --> 24 --> you you you'll you 25 --> 26 --> “Mockingbirds ” “Your 'em “I'd 
Interesting Posts

как сделать saveAsTextFile НЕ разделить вывод на несколько файлов?

Как заставить Chrome открыть все ссылки на текущей вкладке?

403 Запрещенная ошибка в Mac OS X Localhost

Почему мое приложение не появляется на планшетах в Google Play?

Неверная длительность звука с помощью ffmpeg

Как отправить электронное письмо с прикрепленным файлом в Android

Зачем нам нужно новое ключевое слово и почему поведение по умолчанию скрывается и не отменяется?

Какой алгоритм я должен использовать для хеш-паролей в моей базе данных?

Являются ли MAC-адреса уникальными при выходе из завода?

Каков наилучший способ использования R-скриптов в командной строке (терминале)?

Какова категория значений операндов операторов C ++, когда они не указаны?

Могу ли я отключить олицетворение только в нескольких экземплярах

Экспорт базы данных MySQL в базу данных SQLite

Нечувствительный к регистру «Содержит (строка)»

Сброс реестра одного пользователя по умолчанию

Давайте будем гением компьютера.