//Обчислення матриці подібності public void calcResultMatrix(TextBox[][] valueEl, int sizeMatrix, NumericUpDown[] numUpDnArray) { mas = new List<HashSet<string>>();//Копіюю елементи з TextBox[][] в List for (int i = 0; i < sizeMatrix; i++) { mas.Add(new HashSet<string>()); for (int j = 0; j < (int)numUpDnArray[i].Value; j++) { if (valueEl[i][j].Text == "") continue; mas[i].Add(valueEl[i][j].Text); } } for (int i = 0; i < mas.Count; i++)//Видалення пустих рядків { if (mas.ElementAt(i).Count == 0) mas.RemoveAt(i); } //////////////////////////////////////////////////////////////////////////////////////// resultMatrix = new List<List<int>>(); for (int i = 0; i < mas.Count; i++) { resultMatrix.Add(new List<int>()); for (int j = 0; j < mas.Count; j++) { resultMatrix[i].Add(0); } } List<String> list; //List для злиття 2 рядків елементів for (int i = 0; i < mas.Count - 1; i++) { list = new List<String>(); for (int j = 1; j < mas.Count; j++) { if (i == j) continue; list.AddRange(mas[i]);//Копіюю 1 рядок list.AddRange(mas[j]);//Копіюю 2 рядок /* list.Distinct() видаляє елементи, які повторюються, залишаючи перший з них. * (list.Count - list.Distinct().Count()))*2 - дізнаюсь скільки спільних елементів * (list.Count - (list.Count - list.Distinct().Count()) * 2) - дізнаюсь скільки унікальних елементів * countUEl - (list.Count - (list.Count - list.Distinct().Count()) * 2) - від загальної кількості віднімаю унікальні в 2 рядках */ resultMatrix[i][j] = countUEl - (list.Count - (list.Count - list.Distinct().Count()) * 2); resultMatrix[j][i] = countUEl - (list.Count - (list.Count - list.Distinct().Count()) * 2); list.Clear();//Очищаю для наступної пари рядків } } }
//Уточнення модулів ////////////////5 Лаба public void createVerificationModuls() { totalGraph = allGraphs.Last(); //Зливаю назви вершин і модулі в один словник nameVertexAndM = new Dictionary<string, List<string>>(); for (int i = 0; i < nameVertexAndModuls.Count; i++) { for (int j = 0; j < nameVertexAndModuls[i].Count; j++) { try//Ключ, який вже є в словнику не додаємо { nameVertexAndM.Add(nameVertexAndModuls[i].ElementAt(j).Key, nameVertexAndModuls[i].ElementAt(j).Value); } catch (Exception) { } } } nameVertexAndM = nameVertexAndM.OrderBy(a => a.Value.Count).ToDictionary(pair => pair.Key, pair => pair.Value); //Зливаю модулі для кожної групи в один List for (int i = 0; i < calc.moduls.Count; i++) { foreach (List<string> list in calc.moduls[i]) { calc.modulsAfterVerification.Add(list); } } calc.modulsAfterVerification.Sort((a, b) => a.Count - b.Count);//Сортую за кількістю елементів //Формую такі самі множини для перевірки підмножин List<HashSet<string>> setModuls = new List<HashSet<string>>(); for (int i = 0; i < calc.modulsAfterVerification.Count; i++) { setModuls.Add(new HashSet<string>()); for (int j = 0; j < calc.modulsAfterVerification[i].Count; j++) { setModuls[i].Add(calc.modulsAfterVerification[i][j]); } } //Видаляю модулі, які є підмножиною інших модулів for (int i = 0; i < calc.modulsAfterVerification.Count - 1; i++) { for (int j = i + 1; j < calc.modulsAfterVerification.Count; j++) { if (setModuls[i].IsSubsetOf(setModuls[j]))//Являється підмножиною? { calc.modulsAfterVerification.RemoveAt(i); setModuls.RemoveAt(i); ////// string temp = ""; foreach(string str in setModuls[i]) { temp += str; } ///// totalGraph.RemoveVertex(totalGraph.Vertices.First(x => x.Text == temp)); nameVertexAndM.Remove(temp); i--; break; } } } //Видаляю елементи, які є в інших модулях(з більшого) for (int i = 0; i < calc.modulsAfterVerification.Count - 1; i++) { for (int j = 0; j < calc.modulsAfterVerification[i].Count; j++) { for (int k = 1; k < calc.modulsAfterVerification.Count; k++) { if (calc.modulsAfterVerification[k].Contains(calc.modulsAfterVerification[i][j])) { if (k == i) continue; /////////////////// if (calc.modulsAfterVerification[k].Count >= calc.modulsAfterVerification[i].Count) calc.modulsAfterVerification[k].Remove(calc.modulsAfterVerification[i][j]); else { calc.modulsAfterVerification[i].Remove(calc.modulsAfterVerification[i][j]); j--; } /////////////////// if (calc.modulsAfterVerification[i].Count == 0) calc.modulsAfterVerification.RemoveAt(i); ////// string namev = ""; foreach (string s in calc.modulsAfterVerification[k]) { namev += s; } totalGraph.Vertices.ElementAt(k).Text = namev; } } } } //Перезаписую назви вершин і відповідні їм модулі nameVertexAndM.Clear(); foreach(List<string> list in calc.modulsAfterVerification) { string key = ""; foreach(string name in list) { key += name; } nameVertexAndM.Add(key, list); } ///////////////////////////////////////////// totalGraph.RemoveEdgeIf(x => x.Text != "");//Видаляю всі зв'язки //Розтавляю нові вершини totalGraph.RemoveVertexIf(x => x.Text != ""); foreach(string name in nameVertexAndM.Keys) { totalGraph.AddVertex(new DataVertex(name)); } }
//Групування з знаходженням підмножин public void groupsAfterVerification() { groupsAfterV = new List<HashSet<int>>(); setElAfterV= new List<HashSet<string>>(); groupsAfterV.AddRange(groups); setElAfterV.AddRange(createSet(groups)); sortV(groupsAfterV, setElAfterV);//Сортування груп за кількістю елементів sortWithEqualL(setElAfterV);//Сортування груп з однаковою кількістю елементів за перекриванням найбільшої кількості об'єктів for (int i = 0; i < setElAfterV.Count() - 1; i++)//Йду по найбільших групах { for (int k = i+1; k < groupsAfterV.Count(); k++)//Йду по підгрупах { for (int j = 0; j < groupsAfterV[k].Count; j++)//Йду по елементах в групі { if (setElAfterV[i].IsSupersetOf(mas[groupsAfterV[k].ElementAt(j)]))//Являється підмножиною? { groupsAfterV[i].Add(groupsAfterV[k].ElementAt(j));//Додаю елемент групи в групу надмножину groupsAfterV[k].Remove(groupsAfterV[k].ElementAt(j));//Видаляю елемент з підмножини j--; } } } for (int ind = 0; ind < groupsAfterV.Count; ind++)//Видалення пустих рядків { if (groupsAfterV.ElementAt(ind).Count == 0) groupsAfterV.RemoveAt(ind); } setElAfterV.Clear();//Видалив всі групи setElAfterV.AddRange(createSet(groupsAfterV));//Переукомплектовую групи після уточнення sortWithEqualL(setElAfterV);//Сортування груп з однаковою кількістю елементів за перекриванням найбільшої кількості об'єктів } }
//Сортую групи і множини елементів за кількістю елементів(разом щоб співпадали) private void sortV(List<HashSet<int>> groupsAfterV, List<HashSet<string>> setElAfterV) { List<HashSet<int>> temp = new List<HashSet<int>>(); List<HashSet<string>> temp2 = new List<HashSet<string>>(); for (int i = 0; i < groupsAfterV.Count; i++) { for (int j = 0; j < groupsAfterV.Count - 1; j++) { if (setElAfterV.ElementAt(j).Count < setElAfterV.ElementAt(j + 1).Count) { temp.Add(groupsAfterV.ElementAt(j)); groupsAfterV.Insert(j, groupsAfterV.ElementAt(j + 1)); groupsAfterV.RemoveAt(j + 1); groupsAfterV.Insert(j + 1, temp.ElementAt(0)); groupsAfterV.RemoveAt(j + 2); temp.Clear(); temp2.Add(setElAfterV.ElementAt(j)); setElAfterV.Insert(j, setElAfterV.ElementAt(j + 1)); setElAfterV.RemoveAt(j + 1); setElAfterV.Insert(j + 1, temp2.ElementAt(0)); setElAfterV.RemoveAt(j + 2); temp2.Clear(); } } } }
private void buttonCrypto_Click(object sender, EventArgs e) { string cipher,substring,tempstring=""; int indexfirst,indexlast,i,j,k,a,b; List<int> distList = new List<int>(); List<Nod> NodList = new List<Nod>(); Nod currentnod=new Nod(); bool check; if (textBox_Cipher.Lines.Count() == 0) { MessageBox.Show("Не введен шифротекст!"); return; } textBox_Source.Clear(); cipher = textBox_Cipher.Text.ToString(); for (indexfirst = 0; indexfirst < cipher.Length; indexfirst++) { if (Array.IndexOf(Alphabet, cipher[indexfirst]) == -1) { cipher = cipher.Remove(indexfirst, 1); indexfirst--; } } for (int length = 10; length >= 3; length--) { for (indexfirst = 0; indexfirst < cipher.Length-length; indexfirst++) { substring = cipher.Substring(indexfirst,length); if ((textBox_Source.Text.IndexOf(substring) == -1) && (textBox_Source.Text.IndexOf(substring.Substring(0,3)) == -1)) { tempstring = ""; indexlast = indexfirst + length - 1; while (indexlast > -1) { indexlast = cipher.IndexOf(substring, indexlast + 1); if (indexlast > -1) { tempstring = tempstring + "pos=" + indexlast + " dist=" + (indexlast - indexfirst) + "; "; distList.Add(indexlast - indexfirst); } } if (tempstring != "") textBox_Source.AppendText("\"" + substring + "\" " + "starting pos=" + indexfirst + " " + tempstring + "\r\n"); } } } distList.Sort(); for (i = 1; i < distList.Count; i++) { if (distList[i] == distList[i - 1]) { distList.RemoveAt(i); i--; } } for (i = 0; i < distList.Count; i++) { for (j = i+1; j < distList.Count; j++) { check = true; a = distList[i]; b = distList[j]; while ((a!=0) && (b!=0)) { if (a > b) a = a % b; else b = b % a; } currentnod.value=a+b; currentnod.chance=1; if (currentnod.value == 1) continue; for (k = 0; k < NodList.Count; k++) { if (NodList[k].value == currentnod.value) { check = false; currentnod = NodList[k]; currentnod.chance++; NodList[k] = currentnod; break; } } if (check) NodList.Add(currentnod); } } indexfirst = 0; currentnod = NodList[0]; for (i = 0; i < NodList.Count; i++) { indexfirst+=NodList[i].chance; if (NodList[i].chance>currentnod.chance) currentnod = NodList[i]; } textBox_Source.AppendText("Криптоанализ завершен!\r\n"); textBox_Source.AppendText("Вероятная длинна ключа: "+currentnod.value+". Вероятность: "+(currentnod.chance*100/indexfirst)+"%\r\n"); }