2008-10-23 69 views
3

我想用C#风格语言编写一个类似里程表的方法,但不是只使用0-9来表示字符,而是使用任何字符集。它会或多或少地像一个暴力应用程序。算法:里程表/蛮力

如果我在字符从一个炭数组传递给Ĵ,并设置长度为5,我要像00000,00001,00002 ... HJJJJ,IJJJJJ,JJJJJ结果。

这是基础,请帮我扩大:

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

密码破解,我们? – KristoferA 2008-10-23 07:14:35

+0

哈哈,我不认为我的笔记本电脑是现代密码的现实蛮力机器:)它更适用于大脑超常规和乐趣。 – 2008-10-23 07:33:49

回答

1

这是我找到的解决方案之一。我喜欢它的紧凑性和分离:我刚刚出版了一本重写我的一个老的(但大)蛮力例行我做早在20世纪90年代那样

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

谷歌的排列。

然而,如果你只是处理那些“十六进制”的范围,只是做到以下几点:

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

这不是相当"recursion instead of multi-loops"重复,但它是相当接近。如果这对你没有帮助,我会写一个解决方案。

编辑:这是一个非递归解决方案。递归一个是稍硬返回从IEnumerable<string>,但返回一个迭代器IMO给出了一个漂亮的界面:)

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

下面是我以前用过这个确切目的的一类...顾名思义,它基于所提供的字符集中的字符数来计算不同基础。希望它是有用的...

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

继承人在控制台应用程序中的几个使用场景。

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