Random string with no duplicates
Asked Answered
R

5

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);
Rhodos answered 3/3, 2013 at 11:54 Comment(0)
H
9

Consider implementing shuffle algorithm with which you will shuffle your string with unique characters and then just pick up first 16 characters.

You can do this in-place, by allocating single StringBuffer which will contain your initial data ("abc....") and just use Durstenfeld's version of the algorithm to mutate your buffer, than return first 16 chars.

Hemlock answered 3/3, 2013 at 11:59 Comment(1)
Thank You! So simple and elegant. Just what I wanted.Rhodos
J
8

There are many algorithms for this.

One easy one is:

  1. Fill an array of chars with the available chars.
  2. Shuffle the array.
  3. Take the first N items (where N is the number of characters you need).

Sample code:

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;
            }
        }
    }
}
Justiciary answered 3/3, 2013 at 12:0 Comment(0)
L
7
const string chars = 
               "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
var r = new Random();
var s = new string(chars.OrderBy(x => r.Next()).Take(16).ToArray());
Lauralauraceous answered 3/3, 2013 at 12:12 Comment(0)
S
0

I am using a GUID generation method it itself generates random strings and you can modify it if a number appears in the beginning, use the code given below:

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

Hope that helps.

Sofko answered 17/7, 2015 at 6:36 Comment(1)
Guids are not random. They may be unique, but they are not random. There is nothing in the .NET spec that says guids are anything but unique.Vinyl
C
0

See if this helps:

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

This returns alpha-numeric string.

Calebcaledonia answered 6/10, 2015 at 2:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.