Я ищу способ создания открытых идентификаторов для моих объектов (например, facebook uid). Идентификатор должен быть уникальным, и пользователь не должен угадать его (или следующий).
Сейчас я использую это:
sha1('a fixed random string' . $this->getId())
Проблема в том, что sha1 генерирует очень длинные строки (40 символов), и я бы хотел, чтобы он был короче. Я думал об использовании MD5, но он, как известно, не сохраняется, потому что вы можете создавать конфликты. Это действительно проблема в моем случае?
Какие у меня альтернативы?
Если вы используете сильную соль (случайная строка), это не большая проблема с столкновениями MD5.
Почему у вас есть уникальные значения? Я думаю, что гораздо лучше просто использовать уникальное целое, как оно есть.
Хотя, вы действительно хотите хешировать его, посмотрите на это: http://www.php.net/manual/en/function.hash-algos.php , то есть полный список доступных хэш-функций. Проверьте, что установлено на вашем сервере.
Если вы собираетесь хранить идентификаторы в базе данных, вы можете пойти на uniqid . Если вы собираетесь использовать обычные идентификаторы (те auto_increments) в базе данных и просто хотите использовать представительский идентификатор, создайте функцию с некоторыми математическими вычислениями внутри 🙂
Используйте случайное целое число, а затем выполните преобразование базы. Идея заключается в том, что вы используете целевую кодировку многих символов, таких как AZ, az и 0-9. Таким образом, ваш номер может быть закодирован в очень короткой строке.
Для простой версии, в которой пользователи 0-9 и az вы можете использовать функцию PHP base_convert
: (http://codepad.org/9craDgbt)
echo base_convert ( 123456789132465798132 , 10 , 36 );
дает тебе
c5m8nqw9ps
Если вы хотите, чтобы он был еще короче, посмотрите на функцию «convBase» в комментариях http://php.net/manual/de/function.base-convert.php . Увеличивая количество символов в целевой кодировке, результат становится короче.
convBase($randomInt,'0123456789','0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ');
Я провел несколько тестов, чтобы узнать, как долго id будет использовать разные хэш-функции. Я также использовал convBase для преобразования из 0-9a-z в 0-9a-zA-Z, как это было предложено :
$i = mt_rand(1, PHP_INT_MAX); sha1($i): 40 322c73c44958e4219fd6679aead094192cb672fe convBase(sha1($i)): 34 1JHrlXObHSVMcbn2bHRBCBIRD3RVKQHMQzg md5($i): 32 7b09f8cd76be44403b90e971a5a61e6c convBase(md5($i)): 28 5bgdGpBZekbb3PQlILrSKMtHC24A $i: 9 107300785 convBase($i): 5 7gdPP
Таким образом, sha1 очень длинный, даже если он преобразован в другую базу. Также я до сих пор не уверен, что MD5 безопасен. Во всяком случае, с 28 символами это все равно долго, если вы хотите опубликовать его в URL-адресе на Twitter: http://mydomainsux.com/invite/5bgdGpBZekbb3PQlILrSKMtHC24A
Самое короткое решение с convBase($i)
имеет проблему не быть уникальным. Вам нужно будет проверить это вручную. Тем не менее, я думаю, что это путь, потому что, если вы используете хэш, также может быть естественный сговор, поэтому вам все равно придется проверять.
Я читал, что вы можете предварительно создать идентификатор в таблице и просто выбрать один раз, когда вам это нужно. Таким образом, вам не нужно каждый раз проверять уникальность.