Представить хеш MD5 как целое число

В моей таблице базы данных пользователей я принимаю хеш MD5 адреса электронной почты пользователя в качестве идентификатора.

Пример: email(example@example.org) = id(d41d8cd98f00b204e9800998ecf8427e)

К сожалению, теперь я должен представлять идентификаторы как целочисленные значения, чтобы иметь возможность использовать API, где id может быть только целым числом.

Теперь я ищу способ кодирования id в целое число для отправки декодирования его снова при получении. Как я могу это сделать?

Мои идеи до сих пор:

  1. convert_uuencode() и convert_uudecode() для хеша MD5
  2. замените каждый символ хэша MD5 на его значение ord()

Какой подход лучше? Знаете ли вы еще лучшие способы сделать это?

Я надеюсь, что вы можете мне помочь. Заранее большое спасибо!

Быть осторожен. Преобразование MD5 в целое число потребует поддержки больших (128-битных) целых чисел. Скорее всего, API, который вы используете, будет поддерживать только 32-битные целые числа, или, что еще хуже, может иметь дело с числом в плавающей запятой. В любом случае, ваш идентификатор будет запутан. Если это так, просто назначить второй идентификатор произвольно – гораздо лучший способ справиться с вещами, чем пытаться преобразовать MD5 в целое.

Однако, если вы уверены, что API может справиться с произвольно большими целыми числами без проблем, вы можете просто преобразовать MD5 из шестнадцатеричного в целое. Однако PHP, скорее всего, не поддерживает этот встроенный модуль, поскольку он попытается представить его как 32-битное целое число или плавающую точку; вам, вероятно, понадобится использовать библиотеку PHP GMP .

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

Но если вы хотите сделать преобразование хеша md5 в строку десятичных цифр (это то, что, на мой взгляд, означает «представлять целое число», поскольку md5 уже является целым числом в строковой форме) и преобразовать его обратно в ту же строку md5:

 function md5_hex_to_dec($hex_str) { $arr = str_split($hex_str, 4); foreach ($arr as $grp) { $dec[] = str_pad(hexdec($grp), 5, '0', STR_PAD_LEFT); } return implode('', $dec); } function md5_dec_to_hex($dec_str) { $arr = str_split($dec_str, 5); foreach ($arr as $grp) { $hex[] = str_pad(dechex($grp), 4, '0', STR_PAD_LEFT); } return implode('', $hex); } 

Демо-версия:

 $md5 = md5('example@example.com'); echo $md5 . '<br />'; // 23463b99b62a72f26ed677cc556c44e8 $dec = md5_hex_to_dec($md5); echo $dec . '<br />'; // 0903015257466342942628374306682186817640 $hex = md5_dec_to_hex($dec); echo $hex; // 23463b99b62a72f26ed677cc556c44e8 

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

Для 32-битной конденсации можно было бы сделать простое решение, выбрав четыре гексагона (8 символов) хеша MD5, где каждая пара представляет один байт, а затем преобразует ее с помощью intval() .

Для 32-битного без знака Int:

 $inthash = intval(substr(md5($str), 0, 8), 16); 

Для положительного значения только подписанного 32-битного Int:

 $inthash = intval(substr(md5($str), 0, 8), 16) >> 1; 

Вероятно, это будет работать только для значений до 64-разрядных (8 байтов или 16 символов) для большинства современных систем, как указано в документах.

В системе, которая может вместить 64-битные Ints, стратегия разделения, которая потребляет весь 128-битный MD5-хэш, как 2 Ints может выглядеть так:

 $hash = md5($str); $inthash1 = intval(substr($hash, 0, 16), 16); $inthash2 = intval(substr($hash, 16, 16), 16); 

Вы можете использовать hexdec для разбора шестнадцатеричной строки и сохранения номера в базе данных.

Не могли бы вы просто добавить другое поле, которое было полем auto-increment int?

Почему ord ()? md5 производит нормальное 16-байтовое значение, представленное вам в шестнадцатеричном формате для лучшей читаемости. Таким образом, вы не можете преобразовать 16-байтовое значение в 4 или 8 байтовое целое без потерь. Вы должны изменить часть своих алгоритмов, чтобы использовать это как id.

как насчет:

$ float = hexdec (md5 ('string'));

или

$ int = (integer) (substr (hexdec (md5 ('string')), 0,9) * 100000000);

Определенно большие шансы на столкновение, но все же хороший enaugh для использования вместо хэша в DB, ​​хотя?

веселит,

/ Marcin

Используйте адрес электронной почты в качестве имени пустого временного файла в общей папке, например /var/myprocess/example@example.org.

Затем вызовите ftok на имя файла. ftok вернет уникальный идентификатор целого числа.

Не гарантируется, что он будет уникальным, но, вероятно, этого будет достаточно для вашего API.