1

パスワードを生成できるパスワードジェネレータを作成しています。

 var listOfCharacters = "abcdefghijklmnopqrstuvwxyz" //the chars which are using
    chars = listOfCharacters.ToCharArray();

  string password = string.Empty;

            for (int i = 0; i < length; i++) 
            {
                int x = random.Next(0, chars.Length); //with random he is picking a random char from my list from position 0 - 26 (a - z)

                 password += chars.GetValue(x); // putting x (the char which is picked) in the new generated password

            }
            if (length < password.Length) password = password.Substring(0, length); // if the password contains the correct length he will be returns


            return password;

私のランダム:

random = new Random((int)DateTime.Now.Ticks);

Ticksを使用するよりも高速なパスワード生成方法を探しています。これは、私には十分な速度ではないためです。上記のコードに簡単に挿入できる簡単なコードを探しています。私はC#の初心者です。だから私はまだ使うことができます が、より速いものint x = random.Next(0, chars.Length);の代わりに。Random.next

編集:2つが短時間で2つのパスワードを生成したい場合。ダニは遅くなります

私のテストコード:

   [TestMethod]
    public void PasswordGeneratorShouldRenderUniqueNextPassword()
    {
        // Create an instance, and generate two passwords
        var generator = new PasswordGenerator();
        var firstPassword = generator.Generate(8); //8 is the length of the password
        var secondPassword = generator.Generate(8);

        // Verify that both passwords are unique
        Assert.AreNotEqual(firstPassword, secondPassword);
    }
4

4 に答える 4

0

Random起動時にインスタンスを1回作成するか、を使用しRNGCryptoServiceProviderます。

// Create the random instance only once.
private static Random _Random = new Random();

static void Main(string[] args)
{
    var listOfCharacters = "abcdefghijklmnopqrstuvwxyz".ToList();
    var result = new StringBuilder();

    for (int i = 0; i < 20; i++)
    {
        // Consider creating the provider only once!
        var provider = new RNGCryptoServiceProvider();
        // The same is true for the byte array.
        var bytes = new byte[4];

        provider.GetBytes(bytes);
        var number = BitConverter.ToInt32(bytes, 0);
        var index = Math.Abs(number % listOfCharacters.Count);

        result.Append(listOfCharacters[index]);
    }

    Console.WriteLine(result.ToString());
    Console.ReadKey();
}

バイアステスト

    static void Main(string[] args)
    {
        var listOfCharacters = "abcdefghijklmnopqrstuvwxyz".ToList();
        var occurences = new Dictionary<char, int>();

        foreach (var character in listOfCharacters)
        {
            occurences.Add(character, 0);
        }

        var provider = new RNGCryptoServiceProvider();
        var bytes = new byte[4];

        for (int i = 0; i < 1000000; i++)
        {
            provider.GetBytes(bytes);
            var number = BitConverter.ToInt32(bytes, 0);
            var index = Math.Abs(number % listOfCharacters.Count);

            occurences[listOfCharacters[index]]++;
        }

        var orderedOccurences = occurences.OrderBy(kvp => kvp.Value);
        var minKvp = orderedOccurences.First();
        var maxKvp = orderedOccurences.Last();

        Console.WriteLine("Min occurence: " + minKvp.Key + " Times: " + minKvp.Value);
        Console.WriteLine("Max occurence: " + maxKvp.Key + " Times: " + maxKvp.Value);
        Console.WriteLine("Difference: " + (maxKvp.Value - minKvp.Value));

        Console.ReadKey();
    }

その結果、最高の出現と最低の出現の間の値は700〜800のどこかになります。これは、バイアスが0.08%のどこかにあり、最大の差を持つ2つの文字が常に異なることを意味します。だから私は本当にバイアスを見ることができません。

于 2013-03-14T12:05:51.570 に答える
0

GuidのハッシュコードをRandomインスタンスのシード値として使用できます。それはあなたの場合には十分にランダムでなければなりません。

random = new Random(Guid.NewGuid().GetHashCode());
于 2013-03-14T12:17:44.437 に答える
0

次のプログラムは、私のコンピューターで1ミリ秒あたり最大500のパスワードを生成します。

class Program
{
    static void Main(string[] args)
    {
        var g = new Generator();
        IEnumerable<string> passwords = new List<string>();
        var startTime = DateTime.Now;
        passwords = g.GetPassword().ToList();
    }
}

class Generator
{
    Random r = new Random(Guid.NewGuid().GetHashCode());
    string randomCharsList;
    const int length = 8;
    const int randomLength = 8000;
    const string listOfCharacters = "abcdefghijklmnopqrstuvwxyz";
    public Generator()
    {
        CreateRandom();
    }

    private void CreateRandom()
    {
        var randomChars = new StringBuilder();
        string password = string.Empty;

        for (int i = 0; i < randomLength + length; i++)
        {
            var random = new Random(i * Guid.NewGuid().ToByteArray().First());
            int x = random.Next(0, listOfCharacters.Length);
            randomChars.Append(listOfCharacters[x]);
        }
        randomCharsList = randomChars.ToString();
    }

    public IEnumerable<string> GetPassword()
    {
        int pos;
        var startTime = DateTime.Now;
        while ((DateTime.Now - startTime).Milliseconds < 1)
        {
            pos = r.Next(randomLength);
            yield return randomCharsList.Substring(pos, length);
        }
    }
}
于 2013-03-14T12:48:19.430 に答える
0

乱数を生成する際のスレッドセーフの問題についてここにメモを追加したかっただけです(この問題に遭遇した大量のWebサーバーなど)。

基本的に、ランダムクラスはスレッドセーフではなく、衝突が発生した場合、0(私が期待したものではありません)を返します。これは言うまでもなく、ロジックに大混乱をもたらす可能性があります:)したがって、マルチスレッド環境で使用する場合は、必ず保護してください共有ランダムオブジェクトへのアクセス。

詳細については、 https://msdn.microsoft.com/en-us/library/system.random (v = vs.110).aspxの「System.Randomクラスとスレッドセーフ」のセクションを参照してください。

これが誰かを助けることを願っています。

于 2016-01-23T22:05:21.893 に答える