コード例 #1
0
        public SolveData Copy()
        {
            SolveData res = new SolveData();

            res.mapping        = this.mapping.Copy();
            res.numSolvedWords = this.numSolvedWords;

            res.solvedWords = new bool[this.solvedWords.Length];
            this.solvedWords.CopyTo(res.solvedWords, 0);

            res.firstcand = new int[this.firstcand.Length];
            this.firstcand.CopyTo(res.firstcand, 0);

            return(res);
        }
コード例 #2
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);
        }
コード例 #3
0
        private int DetermineNextSubstituationRandomly(bool[] solvedWords, Mapping map, out int index, SolveData data)
        {
            int action = -1;

            int i = 0;

            while (i < solvedWords.Length * 10)
            {
                int cur_index = this.random.Next(solvedWords.Length);

                if (!(solvedWords[cur_index] || !this.words[cur_index].Enabled))
                {
                    index = cur_index;
                    return(1);
                }
                i++;
            }
            index = 0;
            return(action);
        }
コード例 #4
0
        private int DetermineNextSubstitutionDeterministic(bool[] solvedWords, Mapping map, out int index, SolveData data)
        {
            int score = Int32.MaxValue;
            int word  = -1;

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

                int cur_score = (w.Candidates.Length - data.firstcand[i]);

                if (cur_score == 0)
                {
                    index = 0;
                    return(-2);
                }

                if (cur_score < score)
                {
                    score = cur_score;
                    word  = i;
                }
            }

            if (score > this.calpha.GetAlphabetQuantity())
            {
                for (int i = 0; i < this.historder.Length; i++)
                {
                    if (map.IsUniquelyMapped(this.historder[i]))
                    {
                        continue;
                    }
                    byte letter = this.historder[i];

                    if (this.histogram[letter] == 0)
                    {
                        continue;
                    }

                    index = letter;
                    return(2);
                }
            }

            index = word;
            if (index == -1)
            {
                return(-2);
            }

            return(1);
        }
コード例 #5
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 (StopFlag)
                {
                    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);
        }