2013-03-03 103 views
4

我试图产生一个没有重复的CHARS的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

谢谢!如此简单和优雅。正是我想要的。 – 2013-03-03 12:18:50

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

Guids不是随机的。它们可能是独一无二的,但它们不是随机的。 .NET规范中没有任何内容指出guid是唯一的东西。 – Enigmativity 2015-07-20 12:58:13

0

看看这有助于:

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

这将返回字母数字字符串。