Представить хеш MD5 как целое число
В моей таблице базы данных пользователей я принимаю хеш MD5 адреса электронной почты пользователя в качестве идентификатора.
Пример: email([email protected]) = id(d41d8cd98f00b204e9800998ecf8427e)
К сожалению, я должен теперь представлять идентификаторы как целочисленные значения, чтобы иметь возможность использовать API, где идентификатор может быть только целым числом.
Теперь я ищу способ кодирования id в целое число для отправки декодирования его снова при получении. Как я могу это сделать?
Мои идеи до сих пор:
-
convert_uuencode()
и convert_uudecode()
для хэша MD5
- заменить каждый символ хеша MD5 на его значение
ord()
Какой подход лучше? Знаете ли вы еще лучшие способы сделать это?
Надеюсь, ты поможешь мне. Большое вам спасибо заранее!
Ответы
Ответ 1
Будьте осторожны. Преобразование MD5 в целое число потребует поддержки больших (128-битных) целых чисел. Скорее всего, API, который вы используете, будет поддерживать только 32-битные целые числа, или, что еще хуже, может иметь дело с числом в плавающей запятой. В любом случае, ваш идентификатор будет запутан. Если это так, просто назначить второй идентификатор произвольно - гораздо лучший способ справиться с вещами, чем пытаться преобразовать MD5 в целое число.
Однако, если вы уверены, что API может справиться с произвольно большими целыми числами без проблем, вы можете просто преобразовать MD5 из шестнадцатеричного в целое. Однако PHP, скорее всего, не поддерживает этот встроенный модуль, поскольку он попытается представить его как 32-битное целое число или плавающую точку; вам, вероятно, потребуется использовать PHP GMP library для этого.
Ответ 2
Есть веские причины, заявленные другими, для того, чтобы сделать это по-другому.
Но если вы хотите сделать преобразование хеша 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('[email protected]');
echo $md5 . '<br />'; // 23463b99b62a72f26ed677cc556c44e8
$dec = md5_hex_to_dec($md5);
echo $dec . '<br />'; // 0903015257466342942628374306682186817640
$hex = md5_dec_to_hex($dec);
echo $hex; // 23463b99b62a72f26ed677cc556c44e8
Конечно, вам нужно быть осторожным, используя любую строку, например, чтобы использовать их только как строковый тип, чтобы не потерять ведущие нули, гарантируя, что строки имеют правильную длину и т.д.
Ответ 3
Для 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);
Ответ 4
Вы можете использовать hexdec для анализа шестнадцатеричной строки и сохранения номера в базе данных.
Ответ 5
Не могли бы вы просто добавить другое поле, которое было полем auto-increment int?
Ответ 6
Почему ord()? md5 производит нормальное 16-байтовое значение, представленное вам в шестнадцатеричном формате для лучшей читаемости. Таким образом, вы не можете преобразовать 16-байтовое значение в 4 или 8 байтовое целое без потерь. Вы должны изменить часть своих алгоритмов, чтобы использовать это как id.
Ответ 7
как насчет:
$float = hexdec (md5 ('string'));
или
$int = (integer) (substr (hexdec (md5 ('string')), 0,9) * 100000000);
Определенно большие шансы на столкновение, но все же хороший enaugh для использования вместо хеша в DB, хотя?
веселит,
/Marcin
Ответ 8
Используйте адрес электронной почты в качестве имени файла пустого временного файла в общей папке, например /var/myprocess/example @example.org
Затем вызовите ftok на имя файла. ftok вернет уникальный, целочисленный идентификатор.
Не гарантируется, что он будет уникальным, но, вероятно, этого будет достаточно для вашего API.