【发布时间】:2014-07-02 09:36:55
【问题描述】:
如果我们将下面我的方法与this answer 中的RCIX 方法进行比较,以提出一个问题,哪个更有效,为什么?
private string RandomString(int length = 25)
{
const string chars = "aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ0123456789#@%&";
StringBuilder sbSalt = new StringBuilder();
for (int i = 0; i < length; i++)
{
int inx = 0;
inx = rnd.Next(0, chars.Length);
sbSalt.Append(chars[inx]);
}
return sbSalt.ToString();
}
private Random rnd = new Random();
我使用“aAbBcC...”而不是“abc...ABC...”的原因是为了增加每个字母的小写和大写之间随机化的机会,因为它们彼此相邻。
另外,对于密码盐,最好保留重复字符还是我应该确保每个盐只遇到一次每个字符?话又说回来,如果我允许重复字符,则可以生成的盐组合量更大。
提前致谢!
更新 #1:
我意识到,如果我再次调用 RandomString 函数,它会返回完全相同的随机字符串,所以为了解决这个问题,我将 rnd 仅声明为一次新的随机字符串,方法是将它移到函数之外。
【问题讨论】:
-
至于您的更新:Random 在其构造函数中使用种子。当提供相同的种子时,
.Next()函数返回相同的数字集。如果种子没有插入到Random构造函数中,它将使用基于 DateTime.Now 的值。 -
这是另一件需要记住的有用的事情。我使用的解决方法是一个好的解决方法吗?
-
嗯,实际上,最好在函数
RandomString函数中创建一个新的Random对象。它的可读性会更好,性能开销也会很小。此外,虽然这是一个技术细节,但Random对象的寿命越长,真实随机性的下降幅度就越大。有关它的更多信息:stackoverflow.com/a/4440760/2416958 这会将您重定向到相应的文献。 -
@Stefan:我不同意在函数中创建
Random对象。这将始终根据当前时间创建一个新实例。如果您要多次实例化该类,它很可能会创建相同的种子。最好是为特定目的创建一个Random对象,并在应用程序的整个生命周期中使用它,以确保正确分发(当然,在重复周期内)。 -
@Caramiriel:让我重新检查一下;我的信息基于伪随机算法的非真实随机性。我会坚定地承认(可能)只有当你真的很频繁地调用
.Next函数时(比如 10 ^ 10 次)才是一个问题。如果我错了,我会尝试获取一些信息并重述。谢谢。
标签: c# string random passwords salt