如果您非常快速地生成两个密码,它们将在同一个刻度上生成。
如果您只想生成一个随机的人类可读密码,请看这里。如果您想知道为什么Random
不适合此目的以及如何做更合适的事情,请继续阅读。
最快的做法是使用 的默认构造函数Random()
,它会为你做种子。
检查文档后,默认构造函数使用基于时间的种子,因此您在使用它时会遇到同样的问题。无论如何,Random
该类太容易预测而无法用于安全密码生成。
如果你正在寻找更多的力量,你可以这样做,
using System.Security.Cryptography;
static string GetPassword(int length = 13)
{
var rng = new RNGCryptoServiceProvider();
var buffer = new byte[length * sizeof(char)];
rng.GetNonZeroBytes(buffer);
return new string(Encoding.Unicode.GetChars(buffer));
}
但是,如果您希望人类能够阅读、记住和键入您生成的密码,您应该在可能的字符范围内更加有限。
我已经更新了这部分,以给出一个详细、现代、公正的答案。
如果您想将输出限制为一组特定的字符,您可以执行以下操作。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
/// <summary>
/// Get a random password.
/// </summary>
/// <param name="valid">A list of valid password chars.</param>
/// <param name="length">The length of the password.</returns>
/// <returns>A random password.</returns>
public static string GetPassword(IList<char> valid, int length = 13)
{
return new string(GetRandomSelection(valid, length).ToArray());
}
/// <summary>
/// Gets a random selection from <paramref name="valid"/>.
/// </summary>
/// <typeparam name="T">The item type.</typeparam>
/// <param name="valid">List of valid possibilities.</param>
/// <param name="length">The length of the result sequence.</param>
/// <returns>A random sequence</returns>
private static IEnumerable<T> GetRandomSelection<T>(
IList<T> valid,
int length)
{
// The largest multiple of valid.Count less than ulong.MaxValue.
// This upper limit prevents bias in the results.
var max = ulong.MaxValue - (ulong.MaxValue % (ulong)valid.Count);
// A finite sequence of random ulongs.
var ulongs = RandomUInt64Sequence(max, length).Take(length);
// A sequence of indecies.
var indecies = ulongs.Select((u => (int)(u % (ulong)valid.Count)));
return indecies.Select(i => valid[i]);
}
/// <summary>
/// An infinite sequence of random <see cref="ulong"/>s.
/// </summary>
/// <param name="max">
/// The maximum inclusive <see cref="ulong"/> to return.
/// </param>
/// <param name="poolSize">
/// The size, in <see cref="ulong"/>s, of the pool used to
/// optimize <see cref="RNGCryptoServiceProvider"/> calls.
/// </param>
/// <returns>A random <see cref="ulong"/> sequence.</returns>
private static IEnumerable<ulong RandomUInt64Sequence(
ulong max = UInt64.MaxValue,
int poolSize = 100)
{
var rng = new RNGCryptoServiceProvider();
var pool = new byte[poolSize * sizeof(ulong)];
while (true)
{
rng.GetBytes(pool);
for (var i = 0; i < poolSize; i++)
{
var candidate = BitConvertor.ToUInt64(pool, i * sizeof(ulong));
if (candidate > max)
{
continue;
}
yield return candidate;
}
}
}
您可以像这样使用此代码,首先您需要一组有效char
的 a 可以在您的密码中,
var validChars = new[] { 'A', 'B', 'C' };
为了说明,我只包含了 3 个char
s,实际上您希望char
包含更多的 s。然后,要生成一个 8 秒长的随机密码char
,您可以进行此调用。
var randomPassword = GetPassword(validChars, 8);
在实践中,您可能希望您的密码至少为 13char
秒。