如何在不每次按下按钮的情况下使用给定字符生成所有可能的 WiFi 密码?

How to generate all possible WiFi passwords with given characters without pushing a buttun each time?

我有这段代码可以为给定大小的字符串生成所有可能的字符组合:

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

然而,为了检索所有字符组合,我需要多次按下按钮 1。有没有办法让我以某种方式循环播放?我需要这个来使我的应用实用。

我会在做其他事情的时候让程序运行。我希望我的循环生成字符组合并将它们以字符串的形式打印到列表框。

您可能需要重新考虑您想要实现它的方式。仅仅使用 4 的长度就产生了 14,776,336 个独特的组合。但要回答你的问题,下面会生成唯一的字符串。如果长度大于该长度,您很可能 运行 内存不足。您总是可以提前将它们写入文件,然后从文件中随机提取行样本。

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

使用 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

描述(内置函数):

  • Enumerable.Select 方法:将序列中的每个元素投影到一个新的形式中。示例:
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 方法:将序列的每个元素投影到 IEnumerable 并将生成的序列展平为一个序列。示例:
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

描述(第 passwords = passwords.SelectMany(x => characters.Select(y => x + y)); 行):

对于 passwords 中的每个元素,我们定义 passwords 等于包含 element + charIEnumerable<string>,对于 characters 中的每个字符。