2008-10-23 96 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(); 
    } 
}