是否存在一种迭代所有符合特定正则表达式的字符串的算法

本文关键字:正则表达式 算法 字符串 存在 迭代 一种 是否 | 更新日期: 2023-09-27 17:57:30

我正在制作一个脚本,试图破解一个登录密码至少为8个字符长、至少包含1个数字、1个特殊字符和1个大写字母的帐户。我会用蛮力。有没有一种紧凑、优雅、高效的方法来遍历与给定正则表达式匹配的每一个可能的字符串?有没有C#类已经做到了这一点,或者我必须发明轮子?

所需:

CoolClass pswExpIter = CoolClass(pswExp);
for ( string thisExp = pswdExpIter.first(); thisExp != pswdExpIter.offend(); thisExp = pswdExpIter.next()) 
{
      if (login("John Doe", thisExp)
      {
           // do something
           break;
      }          
}

是否存在一种迭代所有符合特定正则表达式的字符串的算法

枚举字符串并不困难,如下所示:

  1. 使用任何常用算法构造DFA。

  2. DFA实际上是一个图形。对图进行广度优先遍历,如果已经访问了工作队列的目的地,则无需执行从工作队列中删除边的常规步骤。在标记为接受的每个节点上,打印指向该节点的转换。

由于有必要维护队列上每个节点的转换历史,因此该算法将迅速耗尽内存。对于您所考虑的特定用例,另一种选择是深度优先遍历,当达到所需的字符串长度时停止。这不会占用太多内存,但仍然需要花费大量时间,除非你有办法进一步限制这种可能性。

以下是您正在寻找的东西:

    char[] availableChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_=+*".ToArray();
    IEnumerable<string> CreatePassword(int size)
    {
        if (size == 1 )
        {
            foreach (var c in availableChars)
            {
                yield return c.ToString();
            }
            yield break;
        }
        foreach (var password in CreatePassword(size - 1))
        {
            foreach (var c in availableChars)
            {
                yield return password + c;
            }
        }
    }

祝你好运:)

假设域如下

String domain[] = { a, b, .., z, A, B, .. Z, 0, 1, 2, .. 9 };

假设密码大小为8

ArrayList allCombinations = getAllPossibleStrings2(domain,8);

这将生成SIZE(domain) * LENGTH数量的组合,在本例中为(26+26+10)^8 = 62^8 = 218,340,105,584,896组合

然后,您可以枚举所有可能的字符串,直到指定的大小,如

// get all possible combinations up to a given size
static ArrayList getAllPossibleStrings1(ArrayList domain, int maxSize)
{
    ArrayList list = new ArrayList();
    int i = 1;
    list.AddRange(domain);
    while(++i <= maxSize)
        for(String a in list)
            for(String b in domain)
                list.Add(String.Concat(a,b));
    return list;
}
// get all possible combinations at a given size
static ArrayList getAllPossibleStrings2(ArrayList domain, int size)
{
    ArrayList list = new ArrayList();
    ArrayList temp = new ArrayList();
    int i = 1;
    list.AddRange(domain);
    while(++i <= maxSize)
    {
        for(String a in list)
            for(String b in domain)
                temp.Add(String.Concat(a,b));
        list.Clear();
        list.AddRange(temp);
        temp.Clear();
    }
    return list;
}