5

I'm trying to generate a 16 chars random string with NO DUPLICATE CHARS. I thoght that it shouldn't be to hard but I'm stuck.

I'm using 2 methods, one to generate key and another to remove duplicate chars. In main I've created a while loop to make sure that generated string is 16 chars long.

There is something wrong with my logic because it just shoots up 16-char string with duplicates. Just can't get it right.

The code:

public string RemoveDuplicates(string s)
{
    string newString = string.Empty;
    List<char> found = new List<char>();
    foreach (char c in s)
    {
        if (found.Contains(c))
            continue;

        newString += c.ToString();
        found.Add(c);
    }
    return newString;
}

public static string GetUniqueKey(int maxSize)
{
    char[] chars = new char[62];
    chars =
    "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890".ToCharArray();
    byte[] data = new byte[1];
    RNGCryptoServiceProvider crypto = new RNGCryptoServiceProvider();
    crypto.GetNonZeroBytes(data);
    data = new byte[maxSize];
    crypto.GetNonZeroBytes(data);
    StringBuilder result = new StringBuilder(maxSize);
    foreach (byte b in data)
    {
        result.Append(chars[b % (chars.Length)]);

    }
    return result.ToString();
}

string builder = "";

do
{                       

    builder = GetUniqueKey(16);
    RemoveDuplicates(builder);

    lblDir.Text = builder;
    Application.DoEvents();


} while (builder.Length != 16);
4

5 に答える 5

9

文字列を一意の文字でシャッフルし、最初の 16 文字だけを取得するシャッフル アルゴリズムの実装を検討してください。

StringBuffer最初の 16 文字を返すよりも、最初のデータ ("abc....") を含む single を割り当て、Durstenfeld のバージョンのアルゴリズムを使用してバッファーを変更するだけで、これをインプレースで行うことができます。

于 2013-03-03T11:59:31.773 に答える
8

これには多くのアルゴリズムがあります。

簡単なものは次のとおりです。

  1. 使用可能な文字で文字の配列を埋めます。
  2. 配列をシャッフルします。
  3. 最初の N 個の項目を取得します (N は必要な文字数です)。

サンプルコード:

using System;

namespace ConsoleApplication2
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            var chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890".ToCharArray();
            Random rng = new Random();

            for (int i = 0; i < 10; ++i)
            {
                string randomString = RandomString(16, chars, rng);
                Console.WriteLine(randomString);
            }
        }

        public static string RandomString(int n, char[] chars, Random rng)
        {
            Shuffle(chars, rng);
            return new string(chars, 0, n);
        }

        public static void Shuffle(char[] array, Random rng)
        {
            for (int n = array.Length; n > 1; )
            {
                int k = rng.Next(n);
                --n;
                char temp = array[n];
                array[n] = array[k];
                array[k] = temp;
            }
        }
    }
}
于 2013-03-03T12:00:43.177 に答える
6
const string chars = 
               "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
var r = new Random();
var s = new string(chars.OrderBy(x => r.Next()).Take(16).ToArray());
于 2013-03-03T12:12:37.323 に答える
0

これが役立つかどうかを確認してください:

    RandomString()
    {
        string randomStr = Guid.NewGuid().ToString();
        randomStr = randomStr.Replace("-", "").Substring(0, 16);   
        Console.WriteLine(randomStr);
    }

これは英数字の文字列を返します。

于 2015-10-06T02:45:23.777 に答える