Есть ли способ шифрования, который может взять строку любой длины и создать хэш размером менее 10 символов? Я хочу создать достаточно уникальный идентификатор, но на основе содержимого сообщения, а не случайным образом.
Я могу жить с ограничением сообщений целыми значениями, если строки произвольной длины невозможны. Однако в этом случае хеш не должен быть одинаковым для двух последовательных целых чисел.
encryption
uniqueidentifier
rath3r
источник
источник
Ответы:
Вы можете использовать любой общедоступный алгоритм хеширования (например, SHA-1), который даст вам немного более длительный результат, чем тот, который вам нужен. Просто обрежьте результат до желаемой длины, что может быть достаточно хорошо.
Например, в Python:
источник
hash(a)
сталкивается с,hash(b)
тоbase64(hash(a))
также сталкивается сbase64(hash(b))
.sha1
коллизии, но это уже другая история). Если у вас есть хэш из 10 символов, вы получите более высокую энтропию, если он закодирован с помощьюbase64
vsbase16
(или hex). Насколько выше? Сbase16
вы получаете 4 бита информации на символ, сbase64
этой цифрой 6 бит / символ. Всего "шестнадцатеричный" хэш из 10 символов будет иметь 40 бит энтропии, а base64 - 60 бит. Так что он немного более устойчивый, извините, если я не был супер ясен.Если вам не нужен алгоритм, устойчивый к преднамеренной модификации, я нашел алгоритм под названием adler32, который дает довольно короткие (~ 8 символов) результаты. Выберите его из раскрывающегося списка, чтобы попробовать:
http://www.sha1-online.com/
источник
Вам нужно хешировать содержимое, чтобы получить дайджест. Доступно много хешей, но 10 символов - это довольно мало для набора результатов. Раньше люди использовали CRC-32, который выдает 33-битный хеш (в основном 4 символа плюс один бит). Также существует CRC-64, который производит 65-битный хэш. MD5, который производит 128-битный хэш (16 байтов / символов), считается сломанным для криптографических целей, потому что могут быть найдены два сообщения с одинаковым хешем. Само собой разумеется, что всякий раз, когда вы создаете 16-байтовый дайджест из сообщения произвольной длины, у вас будут дубликаты. Чем короче дайджест, тем выше риск столкновений.
Однако ваше беспокойство о том, что хэш не будет одинаковым для двух последовательных сообщений (будь то целые числа или нет), должно быть истинным для всех хешей. Даже одно изменение бита в исходном сообщении должно привести к совершенно иному итоговому дайджесту.
Итак, использование чего-то вроде CRC-64 (и базового 64 для результата) должно привести вас к тому району, который вы ищете.
источник
Просто резюмируя ответ, который был мне полезен (отмечая комментарий @ erasmospunk об использовании кодировки base-64). Моей целью было получить короткую строку, которая была бы в основном уникальной ...
Я не эксперт, поэтому, пожалуйста, исправьте это, если есть какие-либо явные ошибки (в Python снова, как принятый ответ):
result
Здесь используется больше , чем просто шестнадцатеричных символов (то , что вы получите , если вы использовалиhash.hexdigest()
) , так что это менее вероятно столкновение (то есть, должны быть более безопасными , чем укоротить гекс переваривать).Примечание. Использование UUID4 (случайное). См. Http://en.wikipedia.org/wiki/Universally_unique_identifier для других типов.
источник
Вы можете использовать существующий алгоритм хеширования, который производит что-то короткое, например MD5 (128 бит) или SHA1 (160). Затем вы можете сократить это еще больше, объединяя разделы дайджеста с другими разделами. Это увеличит вероятность коллизий, но не так плохо, как простое усечение дайджеста.
Кроме того, вы можете включить длину исходных данных как часть результата, чтобы сделать его более уникальным. Например, операция XOR первой половины дайджеста MD5 со второй половиной приведет к получению 64 бита. Добавьте 32 бита для длины данных (или меньше, если вы знаете, что длина всегда умещается в меньшее количество бит). Это приведет к 96-битному (12-байтовому) результату, который затем можно преобразовать в 24-символьную шестнадцатеричную строку. В качестве альтернативы вы можете использовать кодировку base 64, чтобы сделать ее еще короче.
источник
Если вам нужно,
"sub-10-character hash"
вы можете использовать алгоритм Fletcher-32 , который производит 8-символьный хеш (32 бита), CRC-32 или Adler-32 .CRC-32 медленнее Adler32 в 20% - 100%.
Флетчер-32 чуть надежнее Адлера-32. У него более низкие вычислительные затраты, чем у контрольной суммы Адлера: сравнение Флетчера и Адлера .
Ниже приводится пример программы с несколькими реализациями Флетчера:
Вывод:
Соответствует тестовым векторам :
Adler-32 имеет слабость к коротким сообщениям с несколькими сотнями байтов, потому что контрольные суммы для этих сообщений плохо покрывают 32 доступных бита. Проверь это:
Алгоритм Adler32 недостаточно сложен, чтобы конкурировать с сопоставимыми контрольными суммами .
источник
Просто запустите это в терминале (в MacOS или Linux):
Длина 8 символов.
источник
Вы можете использовать библиотеку hashlib для Python. В shake_128 и shake_256 алгоритмы обеспечивают переменные хешей длины. Вот рабочий код (Python3):
Обратите внимание, что с параметром длины x (в примере 5) функция возвращает хеш-значение длины 2x .
источник
Сейчас 2019 год, и есть варианты получше. А именно xxhash .
источник
Недавно мне понадобилось что-то вроде простой функции сокращения строк. По сути, код выглядел примерно так (впереди код C / C ++):
Вероятно, у него больше коллизий, чем можно было бы ожидать, но он не предназначен для использования в качестве криптографической хеш-функции. Вы можете попробовать различные множители (например, изменить 37 на другое простое число), если у вас слишком много коллизий. Одна из интересных особенностей этого фрагмента заключается в том, что, когда Src короче, чем Dest, Dest заканчивается входной строкой как есть (0 * 37 + value = value). Если вы хотите что-то «читаемое» в конце процесса, Normalize скорректирует преобразованные байты за счет увеличения коллизий.
Источник:
https://github.com/cubiclesoft/cross-platform-cpp/blob/master/sync/sync_util.cpp
источник
DestSize
больше 4 (32 бита), если сам хеш такой дерьмовый? Если вам нужна стойкость к столкновениям, обеспечиваемая выходом, превышающим int, вы должны использовать SHA.