Вопрос

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

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

К сожалению, теперь мне приходится представлять идентификаторы в виде целых значений - чтобы иметь возможность использовать API, где 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-разрядной конденсации можно было бы найти простое решение, выбрав 4 шестнадцатеричные пары (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 для анализа шестнадцатеричной строки и сохранения номер в базе данных.

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

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

о чем:

$float = шестнадцатеричный код (md5('строка'));

или

$int = (целое число) (substr(hexdec(md5('строка')),0,9)*100000000);

Определенно больше шансов на столкновение, но все же достаточно хорошо использовать вместо хэша в БД, хотя?

ваше здоровье,

/Марчин

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top