Exemple #1
0
        private bool ReduceCandidates(Mapping set, bool[] solvedWords, SolveData data)
        {
            Mapping helper = new Mapping(this.calpha.GetAlphabetQuantity());

            int rounds = 0;

            bool dirty = true;

            while (dirty && rounds < DictionaryAttacker.maxReduceIterations)
            {
                dirty = false;

                for (int wordnum = 0; wordnum < words.Count; wordnum++)
                {
                    Word w = words[wordnum];
                    if (solvedWords[wordnum] || !w.Enabled)
                    {
                        continue;
                    }

                    helper.SetEmpty();

                    for (int c = data.firstcand[wordnum]; c < w.Candidates.Length; c++)
                    {
                        Candidate candidate = w.Candidates[c];

                        if (set.IsMappingOK(w.ByteValue, candidate.ByteValue))
                        {
                            helper.EnableMapping(w.ByteValue, candidate.ByteValue);
                        }
                        else
                        {
                            Candidate tmp = w.Candidates[data.firstcand[wordnum]];
                            w.Candidates[data.firstcand[wordnum]] = candidate;
                            w.Candidates[c] = tmp;
                            data.firstcand[wordnum]++;

                            dirty = true;
                        }
                    }

                    set.IntersectWith(helper);
                }

                long mappedTo = 0;
                for (int i = 0; i < this.calpha.GetAlphabetQuantity(); i++)
                {
                    if (!set.HasMapping((byte)i))
                    {
                        return(true);
                    }

                    int mi = set.GetMapping((byte)i);
                    if (mi >= 0)
                    {
                        if ((mappedTo & (1 << mi)) > 0)
                        {
                            return(true);
                        }
                        mappedTo |= (1 << mi);
                    }
                }

                rounds++;
            }

            return(false);
        }
Exemple #2
0
        private void Solve()
        {
            //First Mapping
            Mapping startMap = new Mapping(this.calpha.GetAlphabetQuantity());

            startMap.SetFull();

            // Prepare solution base data
            SolveData basis = new SolveData();

            basis.solvedWords    = new bool[this.words.Count];
            basis.numSolvedWords = 0;
            basis.mapping        = startMap;
            basis.firstcand      = new int[this.words.Count];
            for (int i = 0; i < this.words.Count; i++)
            {
                basis.firstcand[i] = 0;
            }
            Stack <SolveData> stack = new Stack <SolveData>();

            stack.Push(basis);

            // Reduce root node
            if (pruneRootNode)
            {
                bool inconsistent = ReduceCandidates(basis.mapping, basis.solvedWords, basis);
                if (inconsistent)
                {
                    basis.mapping = startMap.Copy();
                }
            }

            int rounds = 0;
            int action;
            int index;

            do
            {
                if (this.stopFlag == true)
                {
                    break;
                }

                rounds++;

                //// Store new data object to stack
                SolveData data = stack.Peek().Copy();

                //// Break if all words are solved
                if (data.numSolvedWords == words.Count)
                {
                    AddKeyToResult(data.mapping, true);
                    break;
                }

                // Define next action
                action = this.DetermineNextSubstitution(data.solvedWords, data.mapping, out index, data);
                if (action == -1)
                {
                    AddKeyToResult(data.mapping, true);
                    break;
                }
                else if (action == -2)
                {
                    AddKeyToResult(data.mapping, false);
                    break;
                }
                else if (action == 1)
                {
                    //// Implement action - Word
                    Word w = words[index];
                    data.solvedWords[index] = true;
                    data.numSolvedWords++;

                    if (!w.Enabled)
                    {
                        continue;
                    }

                    Mapping helper = data.mapping.Copy();
                    bool    leaf   = true;

                    if (scrambleWordOrder)
                    {
                        for (int c = data.firstcand[index]; c < w.Candidates.Length; c++)
                        {
                            int       d  = this.random.Next(w.Candidates.Length - data.firstcand[index]) + data.firstcand[index];
                            Candidate cc = w.Candidates[c];
                            Candidate cd = w.Candidates[d];
                            w.Candidates[d] = cc;
                            w.Candidates[c] = cd;
                        }
                    }

                    for (int c = data.firstcand[index]; c < w.Candidates.Length; c++)
                    {
                        Candidate candidate = w.Candidates[c];

                        if (!helper.IsMappingOK(w.ByteValue, candidate.ByteValue))
                        {
                            continue;
                        }

                        leaf = false;

                        helper.SetMapping(w.ByteValue, candidate.ByteValue);

                        bool inconsistent = false;
                        if (pruneEachNode)
                        {
                            inconsistent = ReduceCandidates(helper, data.solvedWords, data);
                        }

                        if (!inconsistent)
                        {
                            data.mapping          = helper;
                            data.firstcand[index] = c;
                            stack.Push(data);
                            leaf = false;
                            break;
                        }

                        helper.SetTo(data.mapping);
                    }

                    if (leaf)
                    {
                        AddKeyToResult(helper, false);
                        stack.Pop();
                    }
                }
                else if (action == 2)
                {
                    /// Implement action - letter
                    byte[] a = new byte[1];
                    byte[] b = new byte[1];
                    a[0] = (byte)(index);

                    Mapping helper = data.mapping.Copy();
                    bool    leaf   = true;

                    for (int c = 0; c < this.calpha.GetAlphabetQuantity(); c++)
                    {
                        b[0] = (byte)c;

                        if (helper.IsMappingOK(a, b))
                        {
                            helper.SetMapping(a, b);

                            bool inconsistent = ReduceCandidates(helper, data.solvedWords, data);

                            if (!inconsistent)
                            {
                                data.mapping = helper;
                                leaf         = false;
                                break;
                            }

                            helper.SetTo(data.mapping);
                        }
                    }

                    if (leaf)
                    {
                        AddKeyToResult(data.mapping, false);
                        stack.Pop();
                    }
                }
            } while (rounds < DictionaryAttacker.maxIterations);
        }