UNIX で使用される crypt(3) 暗号化を「クラック」するプログラムを C で開発しようとしています。それを行う最も単純な方法は、私が推測するブルートフォースです。パスワードに含めることができるすべての記号を含む配列を作成し、それらのすべての可能な順列を取得して、それらを 2 次元配列に格納する必要があると考えました (1 文字のパスワードはすべて最初の行などに保存されます)。ループします。これを行うより良い方法はありますか?それはループでかなり面倒です。
2 に答える
62の異なる文字しか使用できないと仮定すると、可能な8文字のパスワードをすべて保存するには、62 ^ 8=198テラバイトが必要です。
ループの質問に答えるために、特定のセットの文字を使用して、特定の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ループです。ほとんどの場合、このエントリはnbletterに達していないため、最初のエントリをインクリメントするだけで、そこで停止します。エントリがnbletterに達した場合、それはゼロに戻らなければならないことを意味し、それはインクリメントされる次のエントリの番です。これは確かに異常なループ状態です。オーバーフローがなくなるまでループが続きます。ループは最悪の場合、つまり最後の要素に複数のエントリがある場合にのみ発生します。
現在の単語が「zzzc」である場合を想像してみてください。次に、各エントリがインクリメントされ、そのオーバーフローが検出され、0にリセットされ、オーバーフローしない最後のエントリまで次のエントリが考慮されて、「000d」が与えられます。
質問のコメント者が指摘しているように、必要な 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))