Есть ли способ сгенерировать хеш строки, чтобы сам хеш имел определенную длину? У меня есть функция, которая генерирует 41-байтовый хэш (SHA-1), но мне нужно, чтобы он был не более 33 байтов (из-за определенных аппаратных ограничений). Если я усекаю 41-байтовый хэш до 33, я, вероятно (конечно же!) Потеряю уникальность.
Или, на самом деле, я полагаю, что алгоритм MD5 хорошо бы подошел бы, если бы я мог найти для него код на C с вашей помощью.
Обновлено: Спасибо всем за быстрые и знающие ответы. Я выбрал хеш MD5, и он отлично подходит для моей цели. Уникальность - важная проблема, но я не ожидаю, что количество этих хэшей будет очень большим в любой момент времени - эти хэши представляют собой программные серверы в домашней локальной сети, поэтому при максимальном количестве запущенных будет 5, может быть, 10.





Я считаю, что алгоритм хеширования MD5 дает 32-значное число, поэтому, возможно, это будет более подходящим.
Обновлено: для доступа к функциям MD5 должна быть возможность подключиться к библиотекам openssl. Однако вы упомянули об аппаратных ограничениях, поэтому в вашем случае это может быть невозможно.
похоже, что Стейл победил меня в этом
Способ вычисления хэшей, к сожалению, невозможен. Чтобы ограничить длину хэша 33 байтами, вам придется его сократить. Вы можете выполнить xor первые и последние 33 байта, так как это может сохранить больше информации. Но даже с 33 байтами у вас мало шансов на коллизию.
md5: http://www.md5hashing.com/c++/
Кстати. md5 составляет 16 байтов, sha1 - 20 байтов, а sha256 - 32 байта, однако в качестве шестнадцатеричных строк они все удваиваются по размеру. Если вы можете хранить байты, вы даже можете использовать sha256.
Ваш BTW - настоящий ответ. Если у вас мало памяти, не храните свои хэши в виде шестнадцатеричных строк!
md5 «более нарушен», чем SHA1 и sha256. Лучше обрезать и использовать дополнительные 12 байтов энтропии.
Мне нравится идея XOR подстрок вместе. По крайней мере, вы «вводите ключ» подстроки, которую будете использовать с остальными байтами, которые вы изначально сгенерировали.
Во-первых, хеширование осуществляется не в байтах, а в символах. Во-вторых, md5 - это 32 символа, а не 16.
Вместо MD5 или SHA-X вы можете использовать Эльфийский хеш (с кодом <- C) или другую простую хеш-функцию. Они небезопасны, но их можно настроить на любую нужную вам длину.
/*****Please include following header files*****/
// string
/***********************************************/
/*****Please use following namespaces*****/
// std
/*****************************************/
static unsigned int ELFHash(string str) {
unsigned int hash = 0;
unsigned int x = 0;
unsigned int i = 0;
unsigned int len = str.length();
for (i = 0; i < len; i++)
{
hash = (hash << 4) + (str[i]);
if ((x = hash & 0xF0000000) != 0)
{
hash ^= (x >> 24);
}
hash &= ~x;
}
return hash;
}
Пример
string data = "jdfgsdhfsdfsd 6445dsfsd7fg/*/+bfjsdgf%$^";
unsigned int value = ELFHash(data);
Выход
248446350
Вероятность 33-байтовой коллизии составляет 1/2 ^ 132 (по парадоксу дня рождения).
Так что не беспокойтесь о потере уникальности.
Обновление: я не проверял фактическую длину байта SHA1. Вот соответствующий расчет: коллизия размером 32 полубайта (33 байта шестнадцатеричного кода - 1 символ завершения) происходит только тогда, когда количество хешированных строк становится около sqrt (2 ^ (32 * 4)) = 2 ^ 64.
Здесь - это реализация MD5 на C.
Хэши по определению уникальны только для небольшого количества данных (и даже тогда это все еще не гарантируется). Невозможно однозначно сопоставить большой объем информации с небольшим количеством информации в силу того факта, что вы не можете волшебным образом избавиться от информации и вернуть ее позже. Имейте в виду, что сжатие не происходит.
Лично я бы использовал MD5 (если вам нужно хранить в тексте) или хэш 256b (32B), например SHA256 (если вы можете хранить в двоичном формате) в этой ситуации. Усечение другого хеш-алгоритма до 33B тоже работает и МОЖЕТ увеличить вероятность генерации хеш-коллизий. Это во многом зависит от алгоритма.
Кроме того, еще одна реализация MD5 на языке C, созданная людьми, которые ее разработали.
Вероятность столкновения с подстрокой (sha_hash, 0, 33) не больше, чем с любым другим хешем длиной 33 байта, из-за способа разработки алгоритмов хеширования (энтропия равномерно распределена в результирующей строке).
Это не совсем верно из-за способа вычисления хэшей. Математика сложна, но частичные столкновения генерировать намного проще, чем полные.
монооксид: Да, они легче пропорциональны количеству битов. 16 байт SHA1 не менее безопасны, чем MD5. Если бы было иначе, хэши не были бы безопасными.
1/2 SHA1 на самом деле сейчас считается более безопасным. MD5 `` сломан '', чем SHA1
1/2 SHA1 (80 бит) короче MD5 (128 бит). Я сомневаюсь, что это было бы безопаснее из-за того, насколько он короткий. А неисправность MD5 (и SHA1) зависит от приложения. Я согласен с тем, что в целом SHA1 - лучший выбор.
If I truncate the 41-byte hash to 33, I'd probably (certainly!) lost the uniqueness.
Что заставляет вас думать, что теперь у вас есть уникальность? Да, очевидно, что вероятность коллизии выше, когда вы играете только с 33 байтами вместо 41, но вы должны полностью осознавать, что коллизии всегда маловероятны, а не невозможны в любой ситуации, когда имеет смысл использовать хеш в первую очередь. Если вы хешируете более 41 байта данных, очевидно, что возможных комбинаций больше, чем доступных хешей.
Я не знаю, лучше ли вам усечь хэш SHA-1 или использовать более короткий хеш, такой как MD5. Я думаю, что буду более уверен в хранении всего хэша, но MD5 имеет известные уязвимости, что может быть или не быть проблемой для вашего конкретного приложения.
Дело не столько в том, что у них есть уязвимости, сколько в том, что вычисления продвинулись до точки, когда грубая форсировка теперь становится практичной при наличии правильных инструментов. При правильных мерах предосторожности MD5 более или менее безопасен. (читается: добавление соли)
Усечение хеша не дает вам гарантии его уникальности, и поэтому его следует избегать.
Андреас: У вас уже нет гарантии уникальности. Это хеш - он делает все возможное, чтобы придумать уникальность, но, по сути, вы всегда должны рассматривать хеши как неуникальные.
Используйте Apache DigestUtils:
Преобразует хэш в шестнадцатеричную строку из 32 символов.
Да :) Вы случайно не знаете, где я могу найти для этого код? Спасибо!