我如何在c#中生成一个随机的8个字符的字母数字字符串?


当前回答

您只需使用程序集SRVTextToImage。并编写下面的代码生成随机字符串。

CaptchaRandomImage c1 = new CaptchaRandomImage();
            string text = c1.GetRandomString(8);

它主要用于实现验证码。但对你来说也一样。希望能有所帮助。

其他回答

不使用Random的解决方案:

var chars = Enumerable.Repeat("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 8);

var randomStr = new string(chars.SelectMany(str => str)
                                .OrderBy(c => Guid.NewGuid())
                                .Take(8).ToArray());

Eric J.写的代码很潦草(很明显这是6年前写的……他今天可能不会写那个代码),甚至还有一些问题。

与目前提出的一些替代方案不同,这个方案在密码学上是合理的。

不真实的…在密码中有一个偏差(正如在注释中所写的那样),bcdefgh比其他的更有可能(a不是,因为通过GetNonZeroBytes,它不会生成值为0的字节,因此a的偏差由它平衡),所以它在密码学上并不可靠。

这应该可以纠正所有的问题。

public static string GetUniqueKey(int size = 6, string chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890")
{
    using (var crypto = new RNGCryptoServiceProvider())
    {
        var data = new byte[size];

        // If chars.Length isn't a power of 2 then there is a bias if
        // we simply use the modulus operator. The first characters of
        // chars will be more probable than the last ones.

        // buffer used if we encounter an unusable random byte. We will
        // regenerate it in this buffer
        byte[] smallBuffer = null;

        // Maximum random number that can be used without introducing a
        // bias
        int maxRandom = byte.MaxValue - ((byte.MaxValue + 1) % chars.Length);

        crypto.GetBytes(data);

        var result = new char[size];

        for (int i = 0; i < size; i++)
        {
            byte v = data[i];

            while (v > maxRandom)
            {
                if (smallBuffer == null)
                {
                    smallBuffer = new byte[1];
                }

                crypto.GetBytes(smallBuffer);
                v = smallBuffer[0];
            }

            result[i] = chars[v % chars.Length];
        }

        return new string(result);
    }
}

一种简单且高度安全的方法可能是生成加密Aes密钥。

public static string GenerateRandomString()
{
    using Aes crypto = Aes.Create();
    crypto.GenerateKey();
    return Convert.ToBase64String(crypto.Key);
}

最简单的:

public static string GetRandomAlphaNumeric()
{
    return Path.GetRandomFileName().Replace(".", "").Substring(0, 8);
}

如果硬编码char数组并依赖于System,则可以获得更好的性能。随机:

public static string GetRandomAlphaNumeric()
{
    var chars = "abcdefghijklmnopqrstuvwxyz0123456789";
    return new string(chars.Select(c => chars[random.Next(chars.Length)]).Take(8).ToArray());
}

如果你担心英文字母可能会改变,你可能会失去业务,那么你可以避免硬编码,但应该表现得稍差(与Path相比)。GetRandomFileName方法)

public static string GetRandomAlphaNumeric()
{
    var chars = 'a'.To('z').Concat('0'.To('9')).ToList();
    return new string(chars.Select(c => chars[random.Next(chars.Length)]).Take(8).ToArray());
}

public static IEnumerable<char> To(this char start, char end)
{
    if (end < start)
        throw new ArgumentOutOfRangeException("the end char should not be less than start char", innerException: null);
    return Enumerable.Range(start, end - start + 1).Select(i => (char)i);
}

如果您可以将后两种方法作为System上的扩展方法,那么它们看起来会更好。随机的实例。

解决方案1 -最大的“范围”与最灵活的长度

string get_unique_string(int string_length) {
    using(var rng = new RNGCryptoServiceProvider()) {
        var bit_count = (string_length * 6);
        var byte_count = ((bit_count + 7) / 8); // rounded up
        var bytes = new byte[byte_count];
        rng.GetBytes(bytes);
        return Convert.ToBase64String(bytes);
    }
}

这个解决方案比使用GUID有更大的范围,因为GUID有几个固定的位,它们总是相同的,因此不是随机的,例如十六进制中的13个字符总是“4”——至少在版本6的GUID中是这样。

这个解决方案还允许您生成任意长度的字符串。

解决方案2 -一行代码-最多22个字符

Convert.ToBase64String(Guid.NewGuid().ToByteArray()).Substring(0, 8);

你不能生成字符串,只要解决方案1和字符串没有相同的范围,由于GUID的固定位,但在很多情况下,这将完成工作。

解决方案3——代码略少

Guid.NewGuid().ToString("n").Substring(0, 8);

主要是为了历史目的。它使用更少的代码,尽管代价是范围更小——因为它使用十六进制而不是base64,所以与其他解决方案相比,它需要更多的字符来表示相同的范围。

这意味着碰撞的可能性更大——用10万次迭代测试8个字符串,生成一个副本。