1

我正在尝试用 C 语言开发一个程序,该程序将“破解”UNIX 使用的 crypt(3) 加密。我猜最天真的方法是暴力破解。我想我应该创建一个包含密码可以具有的所有符号的数组,然后获取它们的所有可能排列并将它们存储在一个二维数组中(其中所有 1 个字符的密码都保存在第一行等)通过 for循环。有没有更好的方法来做到这一点?循环非常混乱。

4

2 回答 2

3

假设只能使用 62 个不同的字符,存储所有可能的 8 个字符的密码需要 62^8=198 TB。

要回答您循环问题,这里有一些代码可以使用给定集合的字符循环遍历给定 len 的所有可能密码:

int len = 3;
char letters[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
int nbletters = sizeof(letters)-1;

int main() {
    int i, entry[len];
    for(i=0 ; i<len ; i++) entry[i] = 0;
    do {
        for(i=0 ; i<len ; i++) putchar(letters[entry[i]]);
        putchar('\n');
        for(i=0 ; i<len && ++entry[i] == nbletters; i++) entry[i] = 0;
    } while(i<len);
}

主要部分是最后一个for循环。在大多数情况下,它只会增加第一个条目,并停在那里,因为这个条目还没有达到 nbletters。如果条目达到 nbletter,则意味着它必须返回零,并且轮到下一个条目递增。这确实是一个不寻常的循环条件:循环一直持续到没有溢出为止。循环只发生在最坏的情况下:当最后一个元素上有多个条目时。

想象一下当前单词是“zzzc”的情况。依次递增每个条目,检测其溢出,将其重置为 0,并考虑下一个条目,直到最后一个没有溢出的条目,给出“000d”。

于 2009-11-17T16:11:44.487 回答
0

正如该问题的评论者所指出的那样-您没有必要的RAM,也不需要全部存储。

覆盖排序顺序中的排列并不是破解密码的最有效方法,尽管它最终会有效。

实现完全覆盖的一种方法是通过排列数迭代 0,并以字符集的大小为基础对值进行编码。这可以很容易地缩放到您的字符集的大小。

(伪代码,但你明白了)


passChars = '[all characters used in this attempt]'

permutationCount = 8^len(passChars) #crypt(3) only uses 8 chars

output = ''

for looper = 0 to permutationCount - 1
    localTemp = looper
    while localTemp > 0
        output += passchars[localTemp%len(passchars)] # % being modulus
        localTemp = floor(localTemp/len(passChars))


于 2009-11-17T16:00:26.853 回答