Представить хеш 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.