简体   繁体   中英

C# word permutations with special characters

I'm trying to create permutations of the Word "password", I have managed to create all permutations of the word with the code below. Currently this does Upper cases and lower cases. I need to Include permutations that have special characters for example where I will have "p@ssword". Where I'm replacing "a" with "@" and "o" "0".

Any idea how I can expand my implementation?

 public static void WritePermutations(string pwd)
    {
        pwd = pwd.ToLower();
        var myDict = new Dictionary<int, string>();
        int Count = 0;

        var results =
            from e in Enumerable.Range(0, 1 << pwd.Length)
            let p =
            from b in Enumerable.Range(0, pwd.Length)
            select (e & (1 << b)) == 0 ? (char?)null : pwd[b]
            select string.Join(string.Empty, p);

        foreach (string s in results)
        {
            string newValue = pwd;
            s.ToLower();
            foreach (char c in s)
            {
                var Old = c.ToString().ToLower();
                var New = c.ToString().ToUpper();
                newValue = ReplaceFirstOccurrence(newValue, Old, New);
                Count++;
            }

            myDict.Add(Count, newValue);
        }

            foreach (var cred in myDict)
            {

                Console.WriteLine(cred.Value);
            }
    }

  public static string ReplaceFirstOccurrence(string Source, string Find, string Replace)
    {
        int Place = Source.IndexOf(Find);
        string result = Source.Remove(Place, Find.Length).Insert(Place, Replace);
        return result;
    }

How about starting off with these declarations and functions:

    List<HashSet<char>> _charCombinations = new List<HashSet<char>> {
        new HashSet<char> {'a','@'},
        new HashSet<char> {'o', '0'},
    };

    HashSet<char> GetAlternatives(char c)
    {
        var result = new HashSet<char>();
        foreach (var hashSet in _charCombinations)
        {
            if (hashSet.Contains(c))
            {
                foreach (char c2 in hashSet)
                    result.Add(c2);
            }
        }

        if (char.IsLetter(c))
        {
            result.Add((String.Empty + c).ToUpper()[0]);
            result.Add((String.Empty + c).ToLower()[0]);
        }
        else if (false) // any other char.Is-based logic
        {

        }
        result.Add(c);
        return result;
    }

    IEnumerable<string> GetTransformations(string s, int start)
    {
        char c = s[start - 1];
        foreach (var c2 in GetAlternatives(c))
        {
            if (start == s.Length)
                yield return String.Empty + c2;
            else
            {
                var e = GetTransformations(s, start + 1).GetEnumerator();
                while (e.MoveNext())
                    yield return  c2 + e.Current;

            }
        }
    }

You can then use them like this:

        var e = GetTransformations("password", 1).GetEnumerator();
        var result = new List<string>();
        while (e.MoveNext())
            result.Add(e.Current);
        result.Sort((a,b) => string.CompareOrdinal(a, b));

This produces 576 strings (too long to list here), which is exactly what you'd expect for an 8-letter word where 6 of the chars have 2 possibilities, and the other 2 have 3 possibilities, ie 2x2x2x2x2x2x3x3

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM