В моей таблице базы данных пользователей я принимаю хеш MD5 адреса электронной почты пользователя в качестве идентификатора.
Пример: email(example@example.org) = id(d41d8cd98f00b204e9800998ecf8427e)
К сожалению, теперь я должен представлять идентификаторы как целочисленные значения, чтобы иметь возможность использовать API, где id может быть только целым числом.
Теперь я ищу способ кодирования id в целое число для отправки декодирования его снова при получении. Как я могу это сделать?
Мои идеи до сих пор:
convert_uuencode()
и convert_uudecode()
для хеша 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.