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


当前回答

如果你的值不是完全随机的,但实际上可能依赖于某些东西——你可以计算出“某个东西”的md5或sha1哈希,然后将其截断为你想要的任何长度。

你也可以生成和截断一个guid。

其他回答

尝试将两部分结合起来:独特(序列、计数器或日期)和随机

public class RandomStringGenerator
{
    public static string Gen()
    {
        return ConvertToBase(DateTime.UtcNow.ToFileTimeUtc()) + GenRandomStrings(5); //keep length fixed at least of one part
    }

    private static string GenRandomStrings(int strLen)
    {
        var result = string.Empty;

        using (var gen = new RNGCryptoServiceProvider())
        {
            var data = new byte[1];

            while (result.Length < strLen)
            {
                gen.GetNonZeroBytes(data);
                int code = data[0];
                if (code > 48 && code < 57 || // 0-9
                    code > 65 && code < 90 || // A-Z
                    code > 97 && code < 122   // a-z
                )
                {
                    result += Convert.ToChar(code);
                }
            }

            return result;
        }
    }

    private static string ConvertToBase(long num, int nbase = 36)
    {
        const string chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; //if you wish to make the algorithm more secure - change order of letter here

        // check if we can convert to another base
        if (nbase < 2 || nbase > chars.Length)
            return null;

        int r;
        var newNumber = string.Empty;

        // in r we have the offset of the char that was converted to the new base
        while (num >= nbase)
        {
            r = (int)(num % nbase);
            newNumber = chars[r] + newNumber;
            num = num / nbase;
        }
        // the last number to convert
        newNumber = chars[(int)num] + newNumber;

        return newNumber;
    }
}

测试:

    [Test]
    public void Generator_Should_BeUnigue1()
    {
        //Given
        var loop = Enumerable.Range(0, 1000);
        //When
        var str = loop.Select(x=> RandomStringGenerator.Gen());
        //Then
        var distinct = str.Distinct();
        Assert.AreEqual(loop.Count(),distinct.Count()); // Or Assert.IsTrue(distinct.Count() < 0.95 * loop.Count())
    }

我们也使用自定义字符串随机,但我们实现的是字符串的帮助器,所以它提供了一些灵活性…

public static string Random(this string chars, int length = 8)
{
    var randomString = new StringBuilder();
    var random = new Random();

    for (int i = 0; i < length; i++)
        randomString.Append(chars[random.Next(chars.Length)]);

    return randomString.ToString();
}

使用

var random = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".Random();

or

var random = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".Random(16);

这是我从Dot Net Perls的Sam Allen那里偷来的一个例子

如果你只需要8个字符,那么在系统中使用Path.GetRandomFileName()。IO命名空间。Sam说使用“Path.”这里的GetRandomFileName方法有时更优越,因为它使用RNGCryptoServiceProvider来获得更好的随机性。然而,它被限制为11个随机字符。”

GetRandomFileName总是返回一个12个字符的字符串,第9个字符是句点。所以你需要去掉句点(因为这不是随机的),然后从字符串中取出8个字符。实际上,你可以只取前8个字符而不用考虑句点。

public string Get8CharacterRandomString()
{
    string path = Path.GetRandomFileName();
    path = path.Replace(".", ""); // Remove period.
    return path.Substring(0, 8);  // Return 8 character string
}

PS:谢谢,Sam

如果你的值不是完全随机的,但实际上可能依赖于某些东西——你可以计算出“某个东西”的md5或sha1哈希,然后将其截断为你想要的任何长度。

你也可以生成和截断一个guid。

I was looking for a more specific answer, where I want to control the format of the random string and came across this post. For example: license plates (of cars) have a specific format (per country) and I wanted to created random license plates. I decided to write my own extension method of Random for this. (this is in order to reuse the same Random object, as you could have doubles in multi-threading scenarios). I created a gist (https://gist.github.com/SamVanhoutte/808845ca78b9c041e928), but will also copy the extension class here:

void Main()
{
    Random rnd = new Random();
    rnd.GetString("1-###-000").Dump();
}

public static class RandomExtensions
{
    public static string GetString(this Random random, string format)
    {
        // Based on http://stackoverflow.com/questions/1344221/how-can-i-generate-random-alphanumeric-strings-in-c
        // Added logic to specify the format of the random string (# will be random string, 0 will be random numeric, other characters remain)
        StringBuilder result = new StringBuilder();
        for(int formatIndex = 0; formatIndex < format.Length ; formatIndex++)
        {
            switch(format.ToUpper()[formatIndex])
            {
                case '0': result.Append(getRandomNumeric(random)); break;
                case '#': result.Append(getRandomCharacter(random)); break;
                default : result.Append(format[formatIndex]); break;
            }
        }
        return result.ToString();
    }

    private static char getRandomCharacter(Random random)
    {
        string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        return chars[random.Next(chars.Length)];
    }

    private static char getRandomNumeric(Random random)
    {
        string nums = "0123456789";
        return nums[random.Next(nums.Length)];
    }
}