public bool TestSubstitutionEncode()
        {
            Substitution sub = new Substitution(plain: "the international collegiate programming contest is an annual competitive programming competition among the universities of the world");

            sub.Key         = sub.GenerateKey();
            (var cipher, _) = sub.Encode();
            Print(sub.Plain, sub.Key, cipher);
            return(cipher == "WNIIR wniir");
        }
Exemplo n.º 2
0
        public (string, double) Break(string cipher)
        {
            List <Individual> group = new List <Individual>();

            sub.Cipher = cipher;
            for (int i = 0; i < InitNum; i++)
            {
                group.Add(new Individual(sub.GenerateKey(), this));
            }

            int    cnt = 0, T = 0;
            double last = double.MinValue;

            while (cnt < 5 && T < 15)
            {
                T++;

                // 去重
                HashSet <Individual> set = new HashSet <Individual>();
                foreach (var id in group)
                {
                    set.Add(id);
                }
                group.Clear();
                foreach (var id in set)
                {
                    group.Add(id);
                }
                set.Clear();

                // 按照适应度降序排序
                group.Sort();
                group.Reverse();

                // 破解中间结果
                sub.ProcessLog.Enqueue(Decode(group[0].key));

                // 控制个体数量
                if (group.Count > Cap)
                {
                    group = group.GetRange(0, Cap);
                }

                minFitness = group.Last().fitness;

                // 最大适应度是否与上次相同,
                if (group[0].fitness != last)
                {
                    last = group[0].fitness;
                    cnt  = 1;
                }
                else
                {
                    cnt++;
                }

                // 计算浓度与基于适应度排名的线性概率
                var      concentrations = CalConcentration(group);
                double[] fitnessProbs   = new double[group.Count];
                for (int i = 0; i < fitnessProbs.Length; i++)
                {
                    fitnessProbs[i] = (double)(group.Count - i) / group.Count;
                }

                Random            rand     = new Random();
                List <Individual> newGroup = new List <Individual>();
                for (int i = 0; i < group.Count; i++)
                {
                    // 选择
                    if (rand.NextDouble() <= Alpha * fitnessProbs[i] + (1 - Alpha) * concentrations[i])
                    {
                        var kids = CalMutation(group[i]);
                        newGroup.AddRange(kids);
                    }
                }

                group.AddRange(newGroup);
            }

            group.Sort();
            group.Reverse();
            sub.ProcessLog.Enqueue(Decode(group[0].key));
            sub.ProcessLog.Enqueue("");

            return(Decode(group[0].key), group[0].fitness);
        }