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


当前回答

在这个线程中只是一些不同答案的性能比较:

方法与设置

// what's available
public static string possibleChars = "abcdefghijklmnopqrstuvwxyz";
// optimized (?) what's available
public static char[] possibleCharsArray = possibleChars.ToCharArray();
// optimized (precalculated) count
public static int possibleCharsAvailable = possibleChars.Length;
// shared randomization thingy
public static Random random = new Random();


// http://stackoverflow.com/a/1344242/1037948
public string LinqIsTheNewBlack(int num) {
    return new string(
    Enumerable.Repeat(possibleCharsArray, num)
              .Select(s => s[random.Next(s.Length)])
              .ToArray());
}

// http://stackoverflow.com/a/1344258/1037948
public string ForLoop(int num) {
    var result = new char[num];
    while(num-- > 0) {
        result[num] = possibleCharsArray[random.Next(possibleCharsAvailable)];
    }
    return new string(result);
}

public string ForLoopNonOptimized(int num) {
    var result = new char[num];
    while(num-- > 0) {
        result[num] = possibleChars[random.Next(possibleChars.Length)];
    }
    return new string(result);
}

public string Repeat(int num) {
    return new string(new char[num].Select(o => possibleCharsArray[random.Next(possibleCharsAvailable)]).ToArray());
}

// http://stackoverflow.com/a/1518495/1037948
public string GenerateRandomString(int num) {
  var rBytes = new byte[num];
  random.NextBytes(rBytes);
  var rName = new char[num];
  while(num-- > 0)
    rName[num] = possibleCharsArray[rBytes[num] % possibleCharsAvailable];
  return new string(rName);
}

//SecureFastRandom - or SolidSwiftRandom
static string GenerateRandomString(int Length) //Configurable output string length
{
    byte[] rBytes = new byte[Length]; 
    char[] rName = new char[Length];
    SolidSwiftRandom.GetNextBytesWithMax(rBytes, biasZone);
    for (var i = 0; i < Length; i++)
    {
        rName[i] = charSet[rBytes[i] % charSet.Length];
    }
    return new string(rName);
}

结果

在LinqPad中测试。对于长度为10的字符串,生成:

from Linq = chdgmevhcy [10] from Loop = gtnoaryhxr [10] from Select = rsndbztyby [10] from GenerateRandomString = owyefjjakj [10] from securefastrrandom = VzougLYHYP [10] from securefastrrandom - nocache = oVQXNGmO1S [10]

性能数据会有细微的变化,偶尔NonOptimized会更快,有时ForLoop和GenerateRandomString会切换谁领先。

LinqIsTheNewBlack (10000x) = 96762 ticks elapsed (9.6762 ms) ForLoop (10000x) = 28970滴答流逝(2.897毫秒) ForLoopNonOptimized (10000x) = 33336滴答流逝(3.3336毫秒) 重复(10000x) = 78547滴答流逝(7.8547毫秒) GenerateRandomString (10000x) = 27416 tick elapsed (2.7416 ms) securefastrrandom (10000x) = 13176滴答流逝(5ms)最低[不同的机器] securefastrrandom - nocache (10000x) = 39541 ticks elapsed (17ms) low[不同的机器]

其他回答

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

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())
    }

最简单和最灵活的加密安全解决方案(。NET Core 3.0+):

如果你使用的是。net Core 3.0或更高版本,你可以在RandomNumberGenerator类上使用新的静态GetInt32方法(这是加密安全的)来为给定的字符集生成随机索引,并以这种方式很容易地填充结果。

这种方法比这个答案中提出的方法要简单得多;它还提供了完全的灵活性,因为你可以传入任何你想要的字符集。

public static string GenerateRandomString(int length, IEnumerable<char> charSet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")
{
    var charArray = charSet.Distinct().ToArray();
    char[] result = new char[length];
    for (int i = 0; i < length; i++)
        result[i] = charArray[RandomNumberGenerator.GetInt32(charArray.Length)];
    return new string(result);
}

用法:

string randomAlphanumericString = GenerateRandomString(length: 10);

现在是单行风格。

private string RandomName()
{
        return new string(
            Enumerable.Repeat("ABCDEFGHIJKLMNOPQRSTUVWXYZ", 13)
                .Select(s =>
                {
                    var cryptoResult = new byte[4];
                    using (var cryptoProvider = new RNGCryptoServiceProvider())
                        cryptoProvider.GetBytes(cryptoResult);

                    return s[new Random(BitConverter.ToInt32(cryptoResult, 0)).Next(s.Length)];
                })
                .ToArray());
}

DTB解决方案的一个稍微干净的版本。

    var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    var random = new Random();
    var list = Enumerable.Repeat(0, 8).Select(x=>chars[random.Next(chars.Length)]);
    return string.Join("", list);

您的风格偏好可能会有所不同。

不是100%确定,因为我没有测试这里的每个选项,但在我测试的选项中,这个是最快的。用秒表计时,它显示9-10滴答,所以如果速度比安全更重要,试试这个:

 private static Random random = new Random(); 
 public static string Random(int length)
     {   
          var stringChars = new char[length];

          for (int i = 0; i < length; i++)
              {
                  stringChars[i] = (char)random.Next(0x30, 0x7a);                  
                  return new string(stringChars);
              }
     }