2008-10-23 10 views
3

Je veux écrire une méthode de type odomètre dans un langage C#, mais pas seulement en utilisant 0-9 pour les caractères, mais n'importe quel ensemble de caractères. Il agira comme une application de force brute, plus ou moins.Algorithme: Odomètre/force brute

Si je passe dans un char-tableau de caractères de à J, et la longueur fixée à 5, je veux des résultats comme 00000, 00001, 00002 ... HJJJJ, IJJJJJ, JJJJJ.

est la base Ici, s'il vous plaît me aider à développer:

protected void Main() 
{ 
    char[] chars = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 
     'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J' }; 

    BruteForce(chars, 5); 
} 

private void BruteForce(char[] chars, int length) 
{ 
    // for-loop (?) console-writing all possible combinations from 00000 to JJJJJ 
    // (when passed in length is 5) 
    // TODO: Implement code... 
} 
+1

craquage de mot de passe, sommes-nous? – KristoferA

+0

Haha, je ne pense pas que mon ordinateur portable est une machine de force brute réaliste pour les mots de passe modernes :) C'est plus pour cerveau-excersize et amusant. –

Répondre

1

Ceci est l'une des solutions que j'ai trouvé. J'aime la compacité et la séparation de celui-ci:

private static char[] characters = 
    new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J' }; 

// length: The length of the string created by bruteforce 
public static void PerformBruteForce(int length) { 
    int charactersLength = characters.Length; 
    int[] odometer = new int[length]; 
    long size = (long)Math.Pow(charactersLength, length); 

    for (int i = 0; i < size; i++) { 
     WriteBruteForce(odometer, characters); 
     int position = 0; 
     do { 
      odometer[position] += 1; 
      odometer[position] %= charactersLength; 
     } while (odometer[position++] == 0 && position < length); 
    } 
} 

private static void WriteBruteForce(int[] odometer, char[] characters) { 
    // Print backwards 
    for (int i = odometer.Length - 1; i >= 0; i--) { 
     Console.Write(characters[odometer[i]]); 
    } 
    Console.WriteLine(); 
} 
0

Google pour les permutations.

Si toutefois vous êtes juste affaire avec cette gamme « hexagonale », il suffit de ce qui suit:

for (int i = 0; i < (1 << 24); i++) 
    string s = i.ToString("X6"); 
+0

Ce n'est pas strictement permutations que nous sommes après ici - cela ne permet pas le genre de répétition que nous recherchons. Malheureusement je ne peux pas penser au mot juste, c'est pourquoi je suis parti pour le nom de méthode "GetAllMatches" dans ma réponse. –

+0

Désolé d'avoir confondu avec 0-F, c'était juste pour référence à quelque chose que nous reconnaissons tous. –

+0

Vous pouvez utiliser votre propre numéro de base n à la place. – leppie

7

Ce n'est pas tout à fait un double de "recursion instead of multi-loops" mais il est assez proche. Je vais écrire une solution si cela ne vous aide pas.

EDIT: Voici une solution non récursive. L'récursive est légèrement plus difficile de retourner un IEnumerable<string> de, mais le retour d'un itérateur donne une belle interface OMI :)

private static IEnumerable<string> GetAllMatches(char[] chars, int length) 
{ 
    int[] indexes = new int[length]; 
    char[] current = new char[length]; 
    for (int i=0; i < length; i++) 
    { 
     current[i] = chars[0]; 
    } 
    do 
     { 
      yield return new string(current); 
     } 
     while (Increment(indexes, current, chars)); 
} 

private static bool Increment(int[] indexes, char[] current, char[] chars) 
{ 
    int position = indexes.Length-1; 

    while (position >= 0) 
    { 
     indexes[position]++; 
     if (indexes[position] < chars.Length) 
     { 
      current[position] = chars[indexes[position]]; 
      return true; 
     } 
     indexes[position] = 0; 
     current[position] = chars[0]; 
     position--; 
    } 
    return false; 
} 
0

Voici une classe que je l'ai utilisé avant à cet effet exact ... comme son nom l'indique , il compte essentiel dans différentes bases en fonction du nombre de caractères dans le jeu de caractères fourni. J'espère que c'est utile ...

public class BaseNCounter 
{ 
    public char[] CharSet { get; set; } 
    public int Power { get; set; } 

    public BaseNCounter() { } 

    public IEnumerable<string> Count() { 
     long max = (long)Math.Pow((double)this.CharSet.Length, (double)this.Power); 
     long[] counts = new long[this.Power]; 
     for(long i = 0; i < max; i++) 
      yield return IncrementArray(ref counts, i); 
    } 

    public string IncrementArray(ref long[] counts, long count) { 
     long temp = count; 
     for (int i = this.Power - 1; i >= 0 ; i--) { 
      long pow = (long)Math.Pow(this.CharSet.Length, i); 
      counts[i] = temp/pow; 
      temp = temp % pow; 
     } 

     StringBuilder sb = new StringBuilder(); 
     foreach (int c in counts) sb.Insert(0, this.CharSet[c]); 
     return sb.ToString(); 
    } 
} 

Voici quelques scénarios d'utilisation dans une application de console.

class Program 
{ 
    static void Main(string[] args) 
    { 
     BaseNCounter c = new BaseNCounter() { 
      CharSet = new char [] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }, 
      Power = 2}; 

     foreach(string cc in c.Count()) 
      Console.Write("{0} ,", cc); 
     Console.WriteLine(""); 

     BaseNCounter c2 = new BaseNCounter() 
     { 
      CharSet = new char[] { 'x', 'q', 'r', '9'}, 
      Power = 3 
     }; 
     foreach (string cc in c2.Count()) 
      Console.Write("{0} ,", cc); 
     Console.Read(); 
    } 
} 
0

Je viens de publier une ré-écriture, je l'ai fait sur un vieux (mais grande) routine de force brute, je l'ai fait dans les années 90, il est disponible à partir de mon Gist et fera exactement ce que vous vous demandez:

https://gist.github.com/johanssonrobotics/11249060

Bonne chance!