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"); }
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); }