Использует ли GUID допустимый способ генерации случайной строки символов и чисел?

Возможный дубликат:
Как Random является System.Guid.NewGuid()?

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

Так, например, если бы я хотел случайную строку символов и чисел из 32 или менее символов, я мог бы использовать следующий код С#:

string s = Guid.NewGuid().ToString().Replace("-", "");

Если длина должна быть короче 32, я бы обрезал строку, и если бы она была длиннее, я бы добавил несколько GUID вместе.

Каковы недостатки этого подхода?

После того, как я написал это, я понял, что один из недостатков будет заключаться в том, что он будет иметь только буквы от a до f, поэтому я изменю вопрос:

Это действительно случайная последовательность из 6 символов и 10 цифр?

Ответы

Ответ 1

GUID не гарантирует гарантии случайности, он делает гарантии по уникальности. Если вы хотите случайность, используйте Random для генерации строки.

Ответ 2

Это не на самом деле предназначено быть случайным, а скорее быть (относительно) уникальным. Если вам действительно нужна случайность, я рекомендую использовать что-то вроде хэша значения из System.Random.

Вот ссылка на документацию MSDN для .NET "System.Random", а также то же самое для их Хеширующий пакет.

Ответ 3

Как объяснили другие ответы, a GUID гарантирует единственность, а не случайность.

Если уникальность - это все, что вам нужно, то код в вашем вопросе хорош, хотя вы можете просто использовать Guid.NewGuid().ToString("N"), а не явно заменять дефисы.

Если вам действительно нужна случайная строка, попробуйте что-то вроде этого:

// use RNGCryptoServiceProvider instead of Random if you need extra security
private readonly Random _rng = new Random();

public string GetRandomString(int length)
{
    const string allowedChars =
        "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";

    char[] buffer = new char[length];

    for (int i = 0; i < length; i++)
    {
        buffer[i] = allowedChars[_rng.Next(allowedChars.Length)];
    }

    return new string(buffer);
}

Ответ 4

Нет. Например, стандартные алгоритмы генерации GUID включают такие вещи, как текущее время и MAC-адрес компьютера, выполняющего генерацию.

Ответ 5

Как уже указывалось, GUID разработаны как уникальные, а не случайные. Лучшим и довольно простым способом генерации "random" string (т.е. Соответствия определенным статистическим требованиям для случайности) было бы использовать Random:

/// <summary>
/// Generates a random string with the given length
/// </summary>
/// <param name="size">Size of the string</param>
/// <param name="lowerCase">If true, generate lowercase string</param>
/// <returns>Random string</returns>
private string RandomString(int size, bool lowerCase)
{
    StringBuilder builder = new StringBuilder();
    Random random = new Random();
    char ch;
    for (int i = 0; i < size; i++)
    {
        ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65)));
        builder.Append(ch);
    }
    if (lowerCase)
        return builder.ToString().ToLower();
    return builder.ToString();
}

Если вам нужны "более безопасные" случайные числа, вы можете проверить RNGCryptoServiceProvider. Но как уже сказал Джон фон Нейман сказал:

Любой, кто рассматривает арифметические методы создания случайных цифр, конечно, находится в состоянии греха.

Ответ 6

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

Ответ 7

Из-за того, что Guid уникален, решение в порядке.