2013-03-03 5 views
4

Я пытаюсь создать случайную строку из 16 символов с НЕТ ДУБЛИРОВАННЫХ СИМВОЛОВ. Я хочу сказать, что это не должно быть трудно, но я застрял.Случайная строка без дубликатов

Я использую 2 метода, один для генерации ключа и другой для удаления повторяющихся символов. В основном я создал цикл while, чтобы убедиться, что сгенерированная строка имеет длину 16 символов.

С моей логикой что-то не так, потому что она просто стреляет по 16-символьной строке с дубликатами. Просто не получится.

Код:

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); 

ответ

8

shuffle algorithm Рассмотрим реализацию, с которой вы будете перетасовать вашу строку с уникальными персонажами, а затем просто подобрать первые 16 символов.

Вы можете сделать это на месте, выделив один StringBuffer, который будет содержать ваши исходные данные («abc ....»), и просто используйте версию алгоритма Durstenfeld для изменения вашего буфера, чем возврат первых 16 символов.

+0

Спасибо! Так просто и элегантно. Только то, что я хотел. –

7

Существует много алгоритмов для этого.

Простые одно:

  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; 
      } 
     } 
    } 
} 
5
const string chars = 
       "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"; 
var r = new Random(); 
var s = new string(chars.OrderBy(x => r.Next()).Take(16).ToArray()); 
0

Я использую метод генерации GUID он сам генерирует случайные строки и вы можете изменить его, если число появляется в начале, использовать код, указанный ниже :

string guid = System.Guid.NewGuid().ToString("N"); 
      while (char.IsDigit(guid[0])) 
       guid = System.Guid.NewGuid().ToString("N"); 

Надеюсь, что это поможет.

+0

Гиды не случайны. Они могут быть уникальными, но они не случайны. В спецификации .NET нет ничего, что говорит о невидимых ошибках. – Enigmativity

0

Смотрите, если это помогает:

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

Это возвращает буквенно-цифровую строку.

Смежные вопросы