Я пытаюсь придумать хорошую хэш-функцию для строк. И я подумал, что может быть хорошей идеей суммировать значения unicode для первых пяти символов в строке (при условии, что у нее пять, иначе остановитесь, где она закончится). Будет ли это хорошей идеей, или это плохо?
Я делаю это на Java, но я бы не подумал, что это будет иметь большое значение.
Ответ 1
Обычно хэши не будут делать суммы, иначе stop
и pots
будут иметь одинаковый хеш.
и вы не ограничили бы его первыми n символами, потому что иначе дом и дома имели бы тот же самый хеш.
Обычно хеши принимают значения и умножают их на простое число (что делает его более вероятным для создания уникальных хэшей). Таким образом, вы могли бы сделать что-то вроде:
int hash = 7;
for (int i = 0; i < strlen; i++) {
hash = hash*31 + charAt(i);
}
Ответ 2
Если это вещь безопасности, вы можете использовать криптографию Java:
import java.security.MessageDigest;
MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
messageDigest.update(stringToEncrypt.getBytes());
String encryptedString = new String(messageDigest.digest());
Ответ 3
Вероятно, вы должны использовать String.hashCode().
Если вы действительно хотите реализовать hashCode самостоятельно:
Не поддавайтесь соблазну исключать значимые части объекта из вычисление хэш-кода для улучшения производительность - Джошуа Блох, Эффективная Java
Использование только первых пяти символов - плохая идея. Подумайте об иерархических именах, таких как URL-адреса: все они будут иметь один и тот же хэш-код (потому что все они начинаются с "http://", что означает, что они хранятся под одним и тем же ведром на карте хэша, демонстрируя ужасную производительность.
Здесь военная история перефразирована на String hashCode из Эффективная Java":
Реализована функция хеша строки во всех выпусках до 1,2 рассмотренных не более шестнадцати символов, равномерно разбросанные по всей строке, начиная с первым персонажем. Для больших коллекции иерархических имен, таких как URL-адреса, эта хеш-функция показало ужасное поведение.
Ответ 4
Если вы делаете это на Java, то почему вы это делаете? Просто вызовите .hashCode()
в строке
Ответ 5
Guava HashFunction
(jsdoc) обеспечивает приличное некриптовое сильное хеширование.
Ответ 6
Эта функция, предоставленная Ником, хороша, но если вы используете новую строку String (byte []) для преобразования в 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());
}
Может быть, это может помочь кому-то
Ответ 7
// 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
Ответ 8
FNV-1, по слухам, является хорошей хэш-функцией для строк.
Для длинных строк (длиннее, например, около 200 символов) вы можете получить хорошую производительность из MD4 хеш-функции. Как криптографическая функция, она была разрушена около 15 лет назад, но для не криптографических целей она по-прежнему очень хороша и удивительно быстро. В контексте Java вам придется преобразовать 16-разрядные значения char
в 32-битные слова, например. группируя такие значения в пары. Быстрая реализация MD4 в Java можно найти в sphlib. Вероятно, излишнее в контексте задания в классе, но в противном случае стоит попробовать.
Ответ 9
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;
}
Ответ 10
Если вы хотите увидеть отраслевые стандартные реализации, я бы посмотрел на java.security.MessageDigest.
"Рассылки сообщений - это безопасные односторонние хэш-функции, которые берут данные произвольного размера и выводят хэш-значение фиксированной длины".
Ответ 11
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();
}
Ответ 12
здесь ссылка, которая объясняет много разных хеш-функций, на данный момент я предпочитаю хеш-функцию ELF для вашей конкретной проблемы. В качестве входной информации берется строка произвольной длины.
Ответ 13
Хорошая идея работать с нечетным числом при попытке создать хорошую функцию hast для строки. эта функция принимает строку и возвращает значение индекса, пока что ее работа очень хорошая. и имеет меньшее столкновение. индекс колеблется от 0 до 300, может быть, даже больше, чем тот, но я еще не получил выше, даже с длинными словами, такими как "электромеханическая инженерия"
int keyHash(string key)
{
unsigned int k = (int)key.length();
unsigned int u = 0,n = 0;
for (Uint i=0; i<k; i++)
{
n = (int)key[i];
u += 7*n%31;
}
return u%139;
}
Другая вещь, которую вы можете сделать, - это умножение каждого символа 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<k; i++)
{
n = (int)key[i];
u += i*n%31;
}
return u%139;
}
Ответ 14
Вот простая хэш-функция, которую я использую для хэш-таблицы, которую я создал. Его в основном для приема текстового файла и сохраняет каждое слово в индексе, который представляет собой алфавитный порядок.
int generatehashkey(const char *name)
{
int x = tolower(name[0])- 97;
if (x < 0 || x > 25)
x = 26;
return x;
}
В основном это означает, что слова хэшируются в соответствии с их первой буквой. Итак, слово, начинающееся с 'a', получит хэш-ключ из 0, 'b', который получит 1 и так далее, а 'z' будет 25. Числа и символы будут иметь хэш-ключ из 26. Это преимущество, которое обеспечивает; Вы можете легко и быстро вычислить, где данное слово будет индексироваться в хеш-таблице, поскольку все это в алфавитном порядке, что-то вроде этого:
Код можно найти здесь: https://github.com/abhijitcpatil/general
Предоставление следующего текста в качестве входного сигнала: Аттик сказал Джему однажды: "Идиот, вы стреляли в жестяные банки на заднем дворе, но я знаю, что вы пойдете после птиц. Выстрелите все голубые сойки, которые вы хотите, если можете ударить их, но помните его грех, чтобы убить пересмешника". Это был единственный раз, когда я когда-либо слышал, что Аттик сказал, что грех что-то сделать, и я спросил мисс Моди об этом. "Твои отцы правы", - сказала она. "Пересмешники не сделайте одно, кроме музыки для нас, чтобы наслаждаться. Они не съедают сады людей, не гнездятся в кукурузных шпаргах, они не делают ничего но петь их сердца для нас. Вот почему его грех, чтобы убить пересмешник.
Это будет выход:
0 --> a a about asked and a Atticus a a 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