0

I have this code which generates all the combination of characters possible for a given size of string:

public partial class Form1 : Form
{
    List<string> characters = new List<string>();

    string rip = "";

    int size   = 0;

    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        SetList();
    }
    public void SetList()
    {
        string[] numbers = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };

        string[] lowercase = { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" };

        string[] uppercase = { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" };

        characters.AddRange(numbers);

        characters.AddRange(lowercase);

        characters.AddRange(uppercase);
    }
  
    private void button1_Click(object sender, EventArgs e)
    {
        int x = 1;
       
       Random rand = new Random();
        while (x <= size)
        {
            int y = rand.Next(0, characters.Count - 1);

            string ch = characters[y];

            rip = rip + ch;

            x++;

        }

            listBoxPasswords.Items.Add(rip);

            rip = string.Empty;
        }

        private void numericUpDown1_ValueChanged(object sender, EventArgs e)
        {
            size = Convert.ToInt32(numericUpDown1.Value);
        }
    }
}

However in order to retrieve all the combinations of the characters i need to push the button1 many times. Is there a way I can loop this somehow? I need this in order to make my app practical .

I will let the programm running while I do other things. I want my loop to generate the combinations of characters and print them in the form of a string to the listbox.

  • 1
    Is there any reason you're using random numbers? You'll get duplicates this way and there's not really an easy way to know when you've created all the combinations. – the.Doc Jul 04 '20 at 21:29
  • It is impossible to do without it or at least I don't know how. Maybe someone smarter than me will tell me. one day. And I don't think there is another built in function which does this job. – Maddy Wells Jul 04 '20 at 21:46
  • 4
    Why don't you try with pen and paper first? Don't think of it as a programming problem. Once you know the required steps you can then do it in code. We could give you the answer, but you'll learn a lot more by trying it yourself. – the.Doc Jul 04 '20 at 22:03
  • Take a look at this: [Is there a good LINQ way to do a cartesian product?](https://stackoverflow.com/questions/4073713/is-there-a-good-linq-way-to-do-a-cartesian-product). Btw the number of all possible letter combinations is gonna be huge, for any non trivial password length. If you try to store all these combinations in memory, chances are that you'll run out of memory. – Theodor Zoulias Jul 05 '20 at 02:54
  • I don't know math. – Maddy Wells Jul 05 '20 at 07:51

2 Answers2

3

You may want to reconsider the way you are wanting to implement this. Just using a length of 4 generates 14,776,336 unique combinations. But to answer your question the below would generate the unique strings. With a length greater than that you will more than likely run out of memory. You could always write them to a file ahead of time and then pull a random sample of lines from the file.

Results = new List<string>();
var alphabet = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHILKLMNOPQRSTUVWXYZ";
var q = alphabet.Select(x => x.ToString());
int lengthOfPw = 4;
for (int i = 0; i < lengthOfPw - 1; i++)
    q = q.SelectMany(x => alphabet, (x, y) => x + y);

foreach (var item in q)
    Results.Add(item);
Edney Holder
  • 1,140
  • 8
  • 22
1

Using LINQ:

int lengthOfPasswords = 2;
IEnumerable<string> passwords = new List<string> { "" };
string characters = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHILKLMNOPQRSTUVWXYZ";

for (int i = 0; i < lengthOfPasswords; i++)
    passwords = passwords.SelectMany(x => characters.Select(y => x + y));

// Usage:
foreach (string k in passwords)
    Console.WriteLine(k);

// Output:
// 00
// 01
// 02
// ...
// ZX
// ZY
// ZZ

Description(built-in functions):

  • Enumerable.Select Method: Projects each element of a sequence into a new form. Example:
int[] test = { 1, 2, 3 };
var test2 = test.Select(num => num + 1);

foreach (int number in test2)
    Console.WriteLine(number);

// Output:
// 2
// 3
// 4
  • Enumerable.SelectMany Method: Projects each element of a sequence to an IEnumerable and flattens the resulting sequences into one sequence. Example:
int[][] test = { new int[] { 1, 2, 3 }, new int[] { 4, 5, 6 } };

var test2 = test.Select(intArr => intArr.Select(num => num + 1));
var test3 = test.SelectMany(intArr => intArr.Select(num => num + 1));

// test2 = { new int[] { 2, 3, 4 }, new int[] { 5, 6, 7 } };
// test3 = { 2, 3, 4, 5, 6, 7 };

foreach (var arr in test2)
    Console.WriteLine(arr);

foreach (var num in test3)
    Console.WriteLine(num);

// Output:
// System.Linq.Enumerable+SelectArrayIterator`2[System.Int32,System.Int32]
// System.Linq.Enumerable+SelectArrayIterator`2[System.Int32,System.Int32]
// 2
// 3
// 4
// 5
// 6
// 7

Description(line passwords = passwords.SelectMany(x => characters.Select(y => x + y));):

For each element in passwords, we define passwords equal to an IEnumerable<string> containing element + char, for each char in characters.