Уменьшение длины MD5

slavegirl
На сайте с 25.06.2012
Offline
396
4689

Здравствуйте!

Я ищу способ сокращения длины результата работы функции md5() с целью экономии пространства под хранение этих результатов. По умолчанию данная функция генерирует строку, состоящую из 32 символов. Существует ли проверенный и безопасный способ уменьшение этой строки, например, до 16 символов (а лучше до 10)? Под "безопасный" я имею в виду минимизацию вероятности возникновения коллизий.

Речь идет не о безопасности сайта или хранении хэшированных паролей. Функция md5() используется для получения отпечатка неких данных, которые поступают в очередь, с дальнейшей проверкой на уникальность (чтобы в очередь не попадали данные, которые уже там присутствуют).

Всего используется 2 разные очереди:

- данные в первой очереди имеют средний размер 40-80 байт, максимальный размер очереди 50,000 элементов;

- данные во второй очереди имеют средний размер 1-2 Кбайт, максимальный размер очереди 10,000 элементов.

Одним из вариантов решения задачи рассматриваю простое усечение результата MD5, то есть, хранение только первых 16 символов хэша. Но у меня возник вопрос: действительно ли вероятность коллизии первой половины хэша будет равняться вероятности коллизии второй половины? Дело в том, что насколько я знаю, функция md5() итерационная, то есть результат хэширования последних блоков, на которое разбивается исходный текст, зависит от результатов вычислений над первыми блоками. Что можно ожидать в ситуации, когда первые части исходных сообщений будут иметь сравнительно похожее содержимое?

Попробую продемонстрировать вопрос более наглядно:

c15c49a8f55a3dd0da7c8eda0e7485f9

Равна ли вероятность коллизии в этих двух блоках?

А если разделить хэш на целых 3 части (по 10 символов), будет ли вероятность коллизии в этих частях одинаковой?

c15c49a8f55a3dd0da7c8eda0e7485f9

Заранее огромное спасибо за советы!

❤️ АЛЬТЕРНАТИВА ADSENSE, ВЫПЛАТЫ В USDT ––  https://t.me/Keep2Share/23758
Алексей Барыкин
На сайте с 04.02.2008
Offline
272
#1

Не представляйте хеш как строку, и получите вместо 32 байт - 16 (как и должно)

Хеш содержит 128 бит (16 байт) и обычно представляется как последовательность из 32 шестнадцатеричных цифр.

http://ru.wikipedia.org/wiki/MD5

Glueon
На сайте с 26.07.2013
Offline
172
#2

Немного не по теме отвечу, но MD5 можно запихнуть, например, в два BIGINT поля. Разрезать его пополам, сделать UNHEX в одно и второе поле.

BIGINT занимает 8 байт. Т.е. в сумме будет 16.

CHAR(32), соотвественно, 32 байта. VARCHAR(32) - 33.

Уже выгода. Касательно вероятности коллизий - надо подумать.

---------- Добавлено 04.08.2013 в 14:00 ----------

Либо BINARY(16).

Есть много IP-сетей в аренду под прокси, парсинг, рассылки (optin), vpn и хостинг. Телега: @contactroot ⚒ ContactRoot команда опытных сисадминов (/ru/forum/861038), свой LIR: сдаем в аренду сети IPv4/v6 (/ru/forum/1012475).
slavegirl
На сайте с 25.06.2012
Offline
396
#3
Алексей Барыкин:
Не представляйте хеш как строку, и получите вместо 32 байт - 16 (как и должно)

То есть, полученный результат из 16-разрядной системы счисления нужно перевести в какую-то другую, которая будет использовать больше символов для одной позиции (например, не [a-f0-9], а [a-z0-9])? Даже не представляю, как это можно сделать...

Glueon
На сайте с 26.07.2013
Offline
172
#4
slavegirl:
То есть, полученный результат из 16-разрядной системы счисления нужно перевести в какую-то другую, которая будет использовать больше символов для одной позиции (например, не [a-f0-9], а [a-z0-9])? Даже не представляю, как это можно сделать...

Если речь идет о PHP - в функцие md5 есть второй параметр "raw output". Поэтому md5( $str, true ) вернет BINARY(16). Если же у вас уже есть HEX представление MD5 в виде 32-х символов - можете сделать, как я написал в прошлом сообщении.

slavegirl
На сайте с 25.06.2012
Offline
396
#5

Glueon, к сожалению, речь идет не о PHP, а о Javascript. Но вмешаться в алгоритм работы функции у меня просто не хватает знаний. Также хранить хэш у меня есть возможность только в виде строки: 1 символ = 1 байт (даже если результатом окажется число).

Glueon
На сайте с 26.07.2013
Offline
172
#6
slavegirl:
Glueon, к сожалению, речь идет не о PHP, а о Javascript. Но вмешаться в алгоритм работы функции у меня просто не хватает знаний. Также хранить хэш у меня есть возможность только в виде строки: 1 символ = 1 байт (даже если результатом окажется число).

Касательно MD5 в JS - http://pajhome.org.uk/crypt/md5/instructions.html там есть возможность сделать raw string.

А хранится-то где, что ячейка - обязательно CHAR? БД, но структуру БД не поменять?

C
На сайте с 04.02.2005
Offline
291
#7

м....

md5 - это ЧИСЛО длиной 128 бит, но представленное в 16-ричной системе

т.е.

128 / 8 = 16байт

1 байт= 2hex символа

md5 как строка - 32байта (в данном случае - символа)

num_md5 = val_int(md5('что-то'),16)

slavegirl
На сайте с 25.06.2012
Offline
396
#8
Glueon:
А хранится-то где, что ячейка - обязательно CHAR? БД, но структуру БД не поменять?

Хранится в банальном текстовом файле в виде кэша (используется пара iMacros + Javascript).

C
На сайте с 04.02.2005
Offline
291
#9

slavegirl, объясните цель экономии.

slavegirl
На сайте с 25.06.2012
Offline
396
#10

Chukcha, цель экономии - увеличение скорости загрузки/сохранения кэша из текстового CSV-файла. Чем больше размер кэша в байтах (в моем случае это 5-6 Мб), тем дольше выполняются с ним операции ввода-вывода. Большую роль в работе скрипта играет даже экономия 0.5 секунды. Вот и возникла идея уменьшить md5-хэши, которые занимают в файле ~70% места.

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий