Отображение целого числа на имя пользователя - PullRequest
1 голос
/ 20 января 2010

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

Наиболее очевидным решением было бы просто установить имя пользователя равным идентификатору пользователя. Но важное требование заключается в том, что имена пользователей не являются «явно последовательными» - поэтому, хотя идентификаторы пользователей могут быть равны 4000 4001 4002 400, клиент не хочет, чтобы пользователи видели этот прогресс в имени пользователя, даже если они числа в конечном итоге будут использоваться.

Также было бы желательно, чтобы длина имени пользователя была компактной, то есть длина не увеличивалась до тех пор, пока идентификаторы пользователя не достигли точки, необходимой для увеличения длины.

Есть предложения?

Edit: Большинство ответов предполагали, что безопасность механизма важна - это не так. Клиент просто не хочет, чтобы было очевидно, кто является «старшим» участником от имени пользователя.

Основная цель имен пользователей состоит в том, чтобы их было легко запомнить, поэтому длинные хеши не так хороши.

Буквенно-цифровые символы в порядке, но клиент обеспокоен назначением потенциально «неправильных» имен пользователей. fpq321 было бы хорошо, ass123 не будет. Это будет публичный «дескриптор» пользователей.

Ответы [ 7 ]

4 голосов
/ 20 января 2010

Я склонен выбирать случайные слова из списка слов + случайное число. Промойте и повторите, если у вас нет уникального. Столкновения случаются редко, особенно если вы используете два списка значительных слов. Например:

Список слов A ( существительные, например )

  • Танго
  • Bravo
  • Альфа

Список слов B ( прилагательные или глаголы )

  • Массивная
  • Славный
  • Отвратительно

Итак, некоторыми примерами могут быть «DisgustingTango1208», «GloriousAlpha1912», «MassiveAlpha15» и т. Д. Преимущество этого метода в том, что пользователям гораздо легче запомнить слова. Пока вы сохраняете низкие цифры, они также не будут представлять проблему, гораздо меньше, чем 16+ буквенно-цифровых символов.

Я знаю, что это не удовлетворяет требованию длины / роста, но выполнение этого даст понимание линейности последовательности (в пределах 1000). Итак, кажется, что можно было бы получить ID # с 1000 попыток перебора.

1 голос
/ 20 января 2010

Если вы хотите, чтобы имена пользователей были такими же короткими, как и идентификатор пользователя, вы можете сделать что-то вроде этого: (он просто заменяет числа на [символы] [знаки] [другие числа])

<?php
// function generates (always the same) username from an ID
function get_username($id){
    $i=0;
    $return=null;
    // define some strings used to generate the usernames (must be 10 chars long)
    $string1=str_split('abcdefghij');
    $string2=str_split('KLMNOPQRST');
    $string3=str_split('3274190258');
    $string4=str_split('ANYSTRINGY');
    $string5=str_split('TENCHARSLO');
    if($splitted=str_split($id)){ // split username
        foreach($splitted as $i => $char){ // loop trough each number of uses_id
            if($i==0) $return .= $string1[(intval($char))]; // 1st char is picked from $sting1
            elseif($i==1) $return .= $string2[(intval($char))];
            elseif($i==2) $return .= $string3[(intval($char))];
            elseif($i==3) $return .= $string4[(intval($char))];
            else $return .= $string5[(intval($char))]; // from 5 chars, pick from sting 5
        }
    }
    return (!empty($return))?$return:false; // return username or false if argument is empty
}
get_username(45879);
?>
1 голос
/ 20 января 2010

Вы можете несколько преобразовать целое число - переставить его байты - поменять местами байт 1 на байт 3, байт 2 на байт 4 и т. Д. И использовать его в качестве имени пользователя. Хотя это не обязательно делает его компактным (поскольку он действительно делает большие числа из маленьких чисел).

например что-то вроде:

BYTE b1 = i&0xFF;
BYTE b2 = (i>>8)&0xFF;
BYTE b3 = (i>>16)&0xFF;
BYTE b4 = (i>>24)&0xFF;

int nTransformed = (b2<<24) | (b1<<16) | (b3<<8) | b4;

Он сохраняет их уникальными, но не обязательно последовательными.

1 голос
/ 20 января 2010

Возможный подход - запустить хеш-функцию для идентификатора пользователя. Вы можете использовать последовательное зондирование. Например, если идентификатор пользователя хешируется до 300, но он уже используется, вы затем проверяете 301, затем 302, затем 303.

1 голос
/ 20 января 2010

Если они не должны дружелюбно читать, вы можете использовать MD5 или аналогичный хеш. Это всегда выдает одинаковую длину, и «никогда» не имеет коллизий. Я, конечно, свободно использую слово «никогда».

Должно работать нормально для ваших нужд.

1 голос
/ 20 января 2010

Рассматривали ли вы использование GUID? Они довольно длинные, но вы не получите совпадения. Или как насчет хеша MD5?

0 голосов
/ 21 января 2010

Обычное решение этой проблемы - позволить пользователю выбрать собственное имя пользователя, а затем связать его с идентификатором пользователя, который используется в качестве первичного ключа.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...