我如何在c#中生成一个随机的8个字符的字母数字字符串?
当前回答
问:为什么我要浪费时间使用Enumerable ?范围,而不是输入“ABCDEFGHJKLMNOPQRSTUVWXYZ0123456789”?
using System;
using System.Collections.Generic;
using System.Linq;
public class Test
{
public static void Main()
{
var randomCharacters = GetRandomCharacters(8, true);
Console.WriteLine(new string(randomCharacters.ToArray()));
}
private static List<char> getAvailableRandomCharacters(bool includeLowerCase)
{
var integers = Enumerable.Empty<int>();
integers = integers.Concat(Enumerable.Range('A', 26));
integers = integers.Concat(Enumerable.Range('0', 10));
if ( includeLowerCase )
integers = integers.Concat(Enumerable.Range('a', 26));
return integers.Select(i => (char)i).ToList();
}
public static IEnumerable<char> GetRandomCharacters(int count, bool includeLowerCase)
{
var characters = getAvailableRandomCharacters(includeLowerCase);
var random = new Random();
var result = Enumerable.Range(0, count)
.Select(_ => characters[random.Next(characters.Count)]);
return result;
}
}
答案:魔术弦不好。有没有人注意到在我的字符串顶部没有“I”?我妈妈教我不要用魔法弦就是因为这个原因……
注意事项1:正如许多像@dtb这样的人所说,不要使用系统。随机的,如果你需要密码安全…
注2:这个答案不是最有效或最短的,但我想用空间把答案和问题分开。我回答这个问题的目的,更多的是为了警告人们不要使用神奇的字符串,而不是提供一个花哨的创新答案。
其他回答
如果你的值不是完全随机的,但实际上可能依赖于某些东西——你可以计算出“某个东西”的md5或sha1哈希,然后将其截断为你想要的任何长度。
你也可以生成和截断一个guid。
另一种选择是使用Linq并将随机字符聚合到stringbuilder中。
var chars = "abcdefghijklmnopqrstuvwxyz123456789".ToArray();
string pw = Enumerable.Range(0, passwordLength)
.Aggregate(
new StringBuilder(),
(sb, n) => sb.Append((chars[random.Next(chars.Length)])),
sb => sb.ToString());
我不知道这在密码学上听起来如何,但它比迄今为止(在我看来)更复杂的解决方案更具可读性和简练性,而且它应该比系统更“随机”。Random-based解决方案。
return alphabet
.OrderBy(c => Guid.NewGuid())
.Take(strLength)
.Aggregate(
new StringBuilder(),
(builder, c) => builder.Append(c))
.ToString();
我不知道我认为这个版本还是下一个版本“更漂亮”,但它们给出了完全相同的结果:
return new string(alphabet
.OrderBy(o => Guid.NewGuid())
.Take(strLength)
.ToArray());
当然,它并没有针对速度进行优化,所以如果每秒生成数百万个随机字符串是关键任务,请尝试另一个!
注意:此解决方案不允许字母中符号的重复,并且字母必须等于或大于输出字符串的大小,使得这种方法在某些情况下不太可取,这完全取决于您的用例。
尝试将两部分结合起来:独特(序列、计数器或日期)和随机
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())
}
您只需使用程序集SRVTextToImage。并编写下面的代码生成随机字符串。
CaptchaRandomImage c1 = new CaptchaRandomImage();
string text = c1.GetRandomString(8);
它主要用于实现验证码。但对你来说也一样。希望能有所帮助。
推荐文章
- 实体框架核心:在上一个操作完成之前,在此上下文中开始的第二个操作
- 如何为构造函数定制Visual Studio的私有字段生成快捷方式?
- 为什么Visual Studio 2015/2017/2019测试运行器没有发现我的xUnit v2测试
- 如何使用JSON确保字符串是有效的JSON。网
- AppSettings从.config文件中获取值
- 通过HttpClient向REST API发布一个空体
- 如何检查IEnumerable是否为空或空?
- 如何在Ruby中生成a和b之间的随机数?
- 自动化invokerrequired代码模式
- 没有ListBox。SelectionMode="None",是否有其他方法禁用列表框中的选择?
- 在c#代码中设置WPF文本框的背景颜色
- 在c#中,什么是单子?
- c#和Java中的泛型有什么不同?和模板在c++ ?
- c#线程安全快速(est)计数器
- 如何将此foreach代码转换为Parallel.ForEach?