Как я могу создать уникальную случайную последовательность символов в C#?

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

, Какое событие Вы являетесь переопределяющими, когда Вы хотите получить доступ к сессии? Сессия не доступна, пока AcquireRequestState не был запущен.

Для получения дополнительной информации, см.: http://msdn.microsoft.com/en-us/library/9ysfzy8h.aspx

6
задан holiveira 14 August 2009 в 01:09
поделиться

10 ответов

Вам действительно нужно «случайное», или «уникального» будет достаточно?

Unique чрезвычайно прост - просто вставьте URL-адрес в базу данных и преобразуйте последовательный идентификатор для этой записи в число base-n, которое представлено выбранным вами набором символов.

Например, если вы хотите использовать только [AZ] в вашей последовательности вы конвертируете идентификатор записи в число с основанием 26, где A = 1, B = 2, ... Z = 26. Алгоритм представляет собой рекурсивный div26 / mod26, где частное - это требуемый символ, а остаток используется для вычисления следующего символа.

Затем при получении URL-адреса вы выполняете обратную функцию, которая должна преобразовать число с основанием 26 обратно в десятичное. Выполните SELECT URL WHERE ID = decimal, и готово!

EDIT:

private string alphabet = "abcdefghijklmnopqrstuvwxyz"; 
   // or whatever you want.  Include more characters 
   // for more combinations and shorter URLs

public string Encode(int databaseId)
{
    string encodedValue = String.Empty;

    while (databaseId > encodingBase)
    {
        int remainder;
        encodedValue += alphabet[Math.DivRem(databaseId, alphabet.Length, 
            out remainder)-1].ToString();
        databaseId = remainder;
    }
    return encodedValue;
}

public int Decode(string code)
{
    int returnValue;

    for (int thisPosition = 0; thisPosition < code.Length; thisPosition++)
    {
        char thisCharacter = code[thisPosition];

        returnValue += alphabet.IndexOf(thisCharacter) * 
            Math.Pow(alphabet.Length, code.Length - thisPosition - 1);
    }
    return returnValue;
}
3
ответ дан 10 December 2019 в 00:42
поделиться

Я бы использовал систему автонумерации и создал алгоритм для генерации ключей. т.е. 1 = a, 2 = b, 27 = aa и т. д.

Вы можете использовать автономный номер базы данных, чтобы гарантировать, что ваш URL-адрес уникален, и вы можете вычислить URL-адрес, возможно, в sproc в базе данных или на вашем бизнес-уровне?

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

2
ответ дан 10 December 2019 в 00:42
поделиться

Самый простой способ создать уникальные последовательности - сделать это последовательно, например: aaaaaa aaaaab aaaaac ... Они не обязательно самые красивые, но гарантируют уникальность для первых 12230590463 последовательностей (при условии вы использовали az и AZ как уникальные символы). Если вам нужно больше URL-адресов, вам нужно добавить седьмой символ.

Однако это не случайные последовательности. Если вы делаете случайные, просто выберите случайный символ из 48, 6 раз. Однако вам нужно будет проверить существующую БД на наличие "использованных" последовательностей, так как вы с большей вероятностью столкнетесь с конфликтами.

3
ответ дан 10 December 2019 в 00:42
поделиться

Полезность случайного генератора ограничена тем, что он не позволяет пользователям вставлять случайные URL-адреса для поиска вещей, на которые у них не должно быть ссылок. Если это не ваша цель, то последовательные идентификаторы должны работать нормально. Если вы просто не хотите, чтобы у пользователей сложилось впечатление, что они используют «младенческую» технологию (когда они видят, что их объявление о вакансии - № 000001), почему бы не начать последовательность с произвольного значения?

1
ответ дан 10 December 2019 в 00:42
поделиться

Когда вы укажете « общее количество уникальных 6 комбинаций символов будет более чем достаточно в течение длительного времени "для вашего случайного поколения учли ли вы парадокс дня рождения в своих расчетах? Как правило, это проклятие любой попытки создать случайные идентификаторы в диапазоне, который составляет всего 1 порядок или меньше, чем ожидаемый диапазон, который потребуется.

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

Я бы посоветовал вам пойти с идеей кодирования последовательных идентификаторов. Чтобы избежать проблемы, связанной с тем, что пользователи могут просто увеличивать / уменьшать значение в URL-адресе для «исследования», вы можете использовать комбинированный сдвиг битов и альтернативный упорядоченный список букв (вместо 1 = a, 2 = b используйте 1 = t, 2 = j и т. д.)

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

Я бы посоветовал вам пойти с идеей кодирования последовательных идентификаторов. Чтобы избежать проблемы, связанной с тем, что пользователи могут просто увеличивать / уменьшать значение в URL-адресе для «исследования», вы можете использовать комбинированный сдвиг битов и альтернативный упорядоченный список букв (вместо 1 = a, 2 = b используйте 1 = t, 2 = j и т. д.)

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

Я бы посоветовал вам пойти с идеей кодирования последовательных идентификаторов. Чтобы избежать проблемы, связанной с тем, что пользователи могут просто увеличивать / уменьшать значение в URL-адресе для «исследования», вы можете использовать комбинированный сдвиг битов и альтернативный упорядоченный список букв (вместо 1 = a, 2 = b используйте 1 = t, 2 = j и т. д.)

1
ответ дан 10 December 2019 в 00:42
поделиться

Если подумать об этом подробнее, вот идея.

Вы можете начать с таблицы ключей, увеличивая символы AAAAAA - ZZZZZZ.

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

Мысли?

] Для случайного выбора попробуйте эту ссылку

Select a random row with MySQL:

SELECT column FROM table
ORDER BY RAND()
LIMIT 1
Select a random row with PostgreSQL:

SELECT column FROM table
ORDER BY RANDOM()
LIMIT 1
Select a random row with Microsoft SQL Server:

SELECT TOP 1 column FROM table
ORDER BY NEWID()
Select a random row with IBM DB2

SELECT column, RAND() as IDX 
FROM table 
ORDER BY IDX FETCH FIRST 1 ROWS ONLY
Thanks Tim

Select a random record with Oracle:

SELECT column FROM
( SELECT column FROM table
ORDER BY dbms_random.value )
WHERE rownum = 1
0
ответ дан 10 December 2019 в 00:42
поделиться
0
ответ дан 10 December 2019 в 00:42
поделиться

Вместо того, чтобы вести таблицу всех возможных значений, просто ведите таблицу значений, которые вы использовали. Используйте функцию random, чтобы сгенерировать 6 случайных значений, от 1 до 26, составить из них строку и сохранить ее в массиве или таблице. Если он уже существует, вы можете (а) создать другую строку или (б) перейти по таблице к следующей доступной (отсутствующей) 6-буквенной строке и использовать это значение. (б) будет более эффективным по мере заполнения таблицы.

0
ответ дан 10 December 2019 в 00:42
поделиться

Следуя идее ответа Рида Копси, я представляю следующий код:

class IDGetter
{
    private StringID ID = new StringID();
    public string GetCurrentID()
    {
        string retStr = "";
        if (ID.char1 > 51)
            id.char1 = 0;
        if (ID.char2 > 51)
            id.char2 = 0;
        if (ID.char3 > 51)
            id.char3 = 0;
        if (ID.char4 > 51)
            id.char4 = 0;
        if (ID.char5 > 51)
            id.char5 = 0;
        if (ID.char6 > 51)
            throw new Exception("the maximum number of id's has been reached");
        return ToIDChar(ID.char1) + ToIDChar(ID.char2) + ToIDChar(ID.char3) + ToIDChar(ID.char4) + ToIDChar(ID.char5) + ToIDChar(ID.char6)
        id.char1++;
    }
    public void SetCurrentID(StringID id) //for setting the current ID from storage or resetting it or something
    {
        this.ID = id;
    }
    private const string alphabet = "abcdefghijklmopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
    private static string ToIDChar(int number)
    {
        if (number > 51 || number < 0)
        {
            throw new InvalidArgumentException("the number passed in (" + number + ") must be between the range 0-51");
        }
        return alphabet[number];
    }
}
public struct StringID 
{
    public int char1 = 0;
    public int char2 = 0;
    public int char3 = 0;
    public int char4 = 0;
    public int char5 = 0;
    public int char6 = 0;
}

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

0
ответ дан 10 December 2019 в 00:42
поделиться

Я использовал это для чего-то очень похожего. Я не беспокоился о скорости, так как это будет редко используемое событие и стол. Но затем можно увеличить строку по мере необходимости.

/// Generates a string and checks for existance
/// <returns>Non-existant string as ID</returns>
public static string GetRandomNumbers(int numChars, string Type)
{
    string result = string.Empty;
    bool isUnique = false;
    while (!isUnique)
    {
        //Build the string
        result = MakeID(numChars);
        //Check if unsued
        isUnique = GetValueExists(result, Type);
    }
    return result;
}
/// Builds the string
 public static string MakeID(int numChars)
{
    string random = string.Empty;
    string[] chars = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" };
    Random rnd = new Random();
    for (int i = 0; i < numChars; i++)
    {
        random += chars[rnd.Next(0, 35)];
    }
    return random;
}
/// Checks database tables based on type for existance, if exists then retry
/// <returns>true or false</returns>
private static bool GetValueExists(string value, string Type)
{
    bool result = false;
    string sql = "";
    if (Type == "URL")
    {
        sql = string.Format(@"IF EXISTS (SELECT COUNT(1) FROM myTable WHERE uniqueString = '{0}')
         BEGIN
             SELECT 1
         END
          ELSE
          BEGIN
             SELECT 0
         END ", value);
    }
    //query the DB to see if it's in use
    result = //ExecuteSQL
    return result;
}
0
ответ дан 10 December 2019 в 00:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: