Более короткие GUID, чем хеширование идентификатора пользователя? - PullRequest
1 голос
/ 11 января 2011

Мне интересно, как Instapaper (букмарклет, сохраняющий текст) может генерировать URL для их букмарклета.

У меня есть скрипт, похожий на www.instapaper.com/j/AnJHrfoDTRia

Качество этихURL-адреса состоят в том, что они никогда не должны конфликтовать и не должны быть по-настоящему угаданными (так что другие люди не могут сохранить их в вашей учетной записи).

Я знаю, что простым подходом может быть MD5 - их адрес электронной почты (предположительно, былпроверил регистрацию на уникальность), но тогда я получу супер длинную строку.Это не большая проблема, но мне интересно, какие существуют методы для более коротких GUID, которые не будут сталкиваться слишком часто (это, конечно, компромисс, но, на мой взгляд, 12 символов выше довольно коротки)

Ответы [ 4 ]

2 голосов
/ 11 января 2011

Вы можете получить более короткую строку, обработав хеш MD5 как число в базе 16 (которая использует символы (0-9a-f) и преобразовав ее, например, в базу 36.

<?php
function gmp_convert($num, $base_a, $base_b) {
    return gmp_strval (gmp_init($num, $base_a), $base_b );
}

$hash = md5("hello");
$hash2 = gmp_convert($hash,16,36);
echo "$hash <br>"; //5d41402abc4b2a76b9719d911017c592 
echo $hash2; //5ir3t0ozoelrnauhrwyu1xfgy

ссылка, которую вы упоминаете, похоже, использует все буквы (верхний и нижний регистр).

Информация, извлеченная из этих вопросов и ответов

0 голосов
/ 20 июля 2012

Base64 кодирует криптографически сильный набор случайных чисел.

<?php
// get 72 pseudorandom bits in a base64 string of 12 characters

$pr_bits = '';

// Unix/Linux platform?
$fp = @fopen('/dev/urandom','rb');
if ($fp !== FALSE) {
    $pr_bits .= @fread($fp,9);
    @fclose($fp);
}

// MS-Windows platform?
if (@class_exists('COM')) {
    // http://msdn.microsoft.com/en-us/library/aa388176(VS.85).aspx
    try {
        $CAPI_Util = new COM('CAPICOM.Utilities.1');
        $pr_bits .= $CAPI_Util->GetRandom(9,0);

        // if we ask for binary data PHP munges it, so we
        // request base64 return value.  We squeeze out the
        // redundancy and useless ==CRLF by hashing...
        if ($pr_bits) { $pr_bits = substr(md5($pr_bits,TRUE), 0, 9); }
    } catch (Exception $ex) {
        // echo 'Exception: ' . $ex->getMessage();
    }
}

$uid = base64_encode($pr_bits);
?>

Это даст вам 72 бита самого чистого колумбийского из 12 символов. Этот набор содержит примерно 10 ^ 21 чисел. Это означает, что вероятность столкновения составляет около 1 на миллиард после 1 миллиона пользователей.

Это очень небольшая модификация этого ответа на стек-поток для генерации криптовалюты: Безопасное генерирование случайных чисел в PHP .

0 голосов
/ 11 января 2011
<?php

$length = 12;

$chars = array_merge(range(0, 9), range('a', 'z'), range('A', 'Z'));

$hash = '';

for ($i = 0; $i < $length; $i++) {
    $hash .= $chars[array_rand($chars)];
}

var_dump($hash);

Это даст нам 3226266762397899821056 уникальных комбинаций против 281474976710656 для md5 (что в 11 миллионов раз больше ).

Всего за 4 символа (!!!) это будет 14776336 уникальных комбинаций, которых вам может быть достаточно.

0 голосов
/ 11 января 2011

MD5 имя пользователя.Возьмите первые X символов полученного хеша MD5.Проверьте, не существует ли уже URL-токена с этим значением в БД.Если это так, возьмите первые символы X + 1 и попробуйте это (и так далее).Если нет, то у вас есть свой токен для этого пользователя.Сохраните токен в БД и отныне ищите его там - не пытайтесь заново создавать токен из имени пользователя каждый раз или еще много чего.

Возможно, вы могли бы начать с X = 7 и делать хорошо(не более 1-2 попыток для подавляющего большинства токенов).

Кроме того, вы можете захотеть добавить что-то еще в вычисление хеша (скажем, их или случайное число) просто чтобы сделать его сложнеепредсказать токен данного пользователя.

...