Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.52/25: Рейтинг темы: голосов - 25, средняя оценка - 4.52
2 / 2 / 0
Регистрация: 28.05.2020
Сообщений: 58

Перебор вариантов

29.05.2020, 11:26. Показов 6050. Ответов 72

Студворк — интернет-сервис помощи студентам
Здравствуйте, нужна помощь новичку (мне).
Есть набор k букв, каждой букве может соответствовать несколько значений, например:
А: 1,2,7
Б: 3,6
В: 4
Г: 5
Все значения разные.
Вопрос: как организовать цикл, чтобы на каждой итерации выдавался набор значений по одному от каждой буквы? То есть в этом примере по 4 значения. Чтобы в итоге перебрались все варианты. Следует сказать, что букв может быть до 33, количество значений не ограничено.
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
29.05.2020, 11:26
Ответы с готовыми решениями:

перебор вариантов...
имеется строка, содержащая слово. (например слово "лампа") Как можно перебрать всевозможные сочитания букв этого слова? разбил слово на...

Перебор всех вариантов
Всем привет! Это моя первая проблема, с которой хотелось бы поделиться. Проблема сложная, но хотелось бы верить, что получится найти ее...

Перебор вариантов из строки
Здравствуйте! Задачка такая. Есть строка с текстом "Ананас; Абрикос; Банан". Требуется, что бы программа выбирала эти элементы...

72
2 / 2 / 0
Регистрация: 28.05.2020
Сообщений: 58
01.06.2020, 20:32  [ТС]
Студворк — интернет-сервис помощи студентам
У меня все работает отлично! Даже разгадал оба примера от преподавателя. Правда, слово "врабнушнпбн"("абракадабра") с заменами
аааааббббррркд
уврнбрапенабнш
Он искал аж 2 минуты :/
А другие слова вроде бы быстро отгадывает.
Сейчас пытаюсь перенести этот код в формс, по аналогии с тем, что вы присылали.
Спасибо большое ещё раз.

Добавлено через 3 минуты
Вам тоже большое спасибо, выглядит действительно рабочим. Протестирую потом
0
 Аватар для samana
2639 / 1567 / 853
Регистрация: 23.02.2019
Сообщений: 3,876
01.06.2020, 21:05
Он искал аж 2 минуты :/
Ого, жесть.. Попробую завтра протестировать у себя и найти источник проблемы и оптимизировать если получится. Есть подозрение, что тормоза связаны с постоянным созданием экземпляра класса, который вычисляет хеш для сотни вариантов подборов..
1
 Аватар для samana
2639 / 1567 / 853
Регистрация: 23.02.2019
Сообщений: 3,876
02.06.2020, 08:23
Цитата Сообщение от shabserg
Правда, слово "врабнушнпбн"("абракадабра ") с заменами
аааааббббррркд
уврнбрапенабнш
Он искал аж 2 минуты :/
А, так вот же где я упустил момент!
Цитата Сообщение от shabserg Посмотреть сообщение
Конечно, если заменяется буква "д" в слове, то на всех позициях она заменяется на одно и то же)
Дело в том, что сейчас перебор включает одновременно все возможные варианты для одной буквы. Например если слово "кок" с заменами
ккк
123

то у меня формируются такие варианты

1о1
1о2
1о3
2о1
2о2
2о3
3о1
3о2
3о3

то-есть одна и та же буква в слове может быть заменена одновременно разными предложенными для неё вариациями.

А вы говорите, что если буква в слове повторяется, то для проверки меняются все одинаковые буквы на одно значение и ваш вариант перебора получится куда меньше

1о1
2о2
3о3

Поэтому абракадарба и высчитывается так долго (у себя я так и не дождался кстати..). Так как для перебора всех вариантов подстановки букв в моей текущей реализации, для этого слова выходит чуть больше чем 10 миллионов вариаций..


Я надеялся, что кто товарища escoult наверняка сработает правильнее и быстрее, но с абракадаброй он почему-то не выдал положительного результата и вывел что слово не найдено.
1
1533 / 540 / 127
Регистрация: 09.01.2018
Сообщений: 1,756
02.06.2020, 08:30
Цитата Сообщение от samana Посмотреть сообщение
Я надеялся, что кто товарища escoult наверняка сработает правильнее и быстрее, но с абракадаброй он почему-то не выдал положительного результата и вывел что слово не найдено.
Вы уверены?
Я вчера еще заинтересовался этим и потестировал на длинном словаре.

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
            //тест длинной абаркадабры
            //врабнушнпбн
            rule = "аааааббббррркд";
            alphabet = "уврнбрапенабнш";
 
            var encrypted = "вбвпнушнппн";
            var hash = MD5Helpers.GetMD5Hash(encrypted);
 
            var tool = new HackTool(dict, rule, alphabet, hash);
            if (tool.TryHack(out var result_abra))
            {
                Console.WriteLine("Пароль найден:");
                Console.WriteLine(result_abra);
            }
            else
            {
                Console.WriteLine("Пароль не найден");
            }
 
            Console.WriteLine();
            Console.WriteLine("Длина словаря: " + dict.Length);
 
            sw.Stop();
            Console.WriteLine("Затраченное время: " + sw.Elapsed);
Code
1
2
3
4
5
Пароль найден:
врабнушнпбн
 
Длина словаря: 23432
Затраченное время: 00:00:00.5400734
1
2 / 2 / 0
Регистрация: 28.05.2020
Сообщений: 58
02.06.2020, 08:30  [ТС]
samana, а можете это пофиксить, пожалуйста?)
0
 Аватар для samana
2639 / 1567 / 853
Регистрация: 23.02.2019
Сообщений: 3,876
02.06.2020, 08:35
Цитата Сообщение от escoult Посмотреть сообщение
Вы уверены?
Я вчера еще заинтересовался этим и потестировал на длинном словаре.
У меня нет цели обманывать вас Сейчас посмотрю, может я что-то неправильно скопировал из вашего варианта или сделал опечатку при вводе правил замены.

Цитата Сообщение от shabserg Посмотреть сообщение
samana, а можете это пофиксить, пожалуйста?)
Я ещё не знаю как это придумать, но если код от escoult работает хорошо, то воспользуйтесь им, он даже выглядит техничнее.
1
2 / 2 / 0
Регистрация: 28.05.2020
Сообщений: 58
02.06.2020, 08:45  [ТС]
samana,
но если код от escoult работает хорошо, то воспользуйтесь им, он даже выглядит техничнее.
- я бы очень хотел, но это всего лишь мое второе задание на c# и в windows forms тоже(
И если ваш последний код я ещё как-то пытаюсь по аналогии с вашим примером перенести в forms, то код escoult я совсем не знаю, как...
Нужно каждый класс в отдельный файл заносить или как? Куда записать содержимое main-а? Я не знаю, честно(
0
 Аватар для samana
2639 / 1567 / 853
Регистрация: 23.02.2019
Сообщений: 3,876
02.06.2020, 08:45
escoult, Не могу понять причину, но почему-то не находит "абракадабра".
На всякий случай закину сюда весь ваш код целиком, чтобы было легче запустить для теста.
Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
 
namespace PasswordHackBy_escoult_
{
    class Program
    {
        static void Main(string[] args)
        {
            //исходные данные
            string[] dict = { "барк", "абракадабра" };
            
            var rule = "аааааббббррркд";
            var alphabet = "уврнбрапенабнш";
 
            var encrypted = "врабнушнпбн";
            var hash = MD5Helpers.GetMD5Hash(encrypted);
 
            var tool = new HackTool(dict, rule, alphabet, hash);
            if (tool.TryHack(out var result_abra))
            {
                Console.WriteLine("Пароль найден:");
                Console.WriteLine(result_abra);
            }
            else
            {
                Console.WriteLine("Пароль не найден");
            }
 
            Console.WriteLine();
            
        }
    }
 
    public interface IPasswordHack : ISourceData
    {
        string Encrypt(string src, int[] key);
        IEnumerable<int[]> GetKeys(string wordFromDict);
    }
 
    public interface ISourceData
    {
        string Rule { get; } //верхняя строка правила
        string Alphabet { get; } //нижняя строка
    }
 
    public interface IHackTool : ISourceData
    {
        string[] Dict { get; }
        string ControlHash { get; }
        bool TryHack(out string result);
    }
 
    public static class MD5Helpers
    {
        public static string GetMD5Hash(string input)
        {
            var md5 = MD5.Create();
            byte[] data = md5.ComputeHash(Encoding.UTF8.GetBytes(input));
 
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < data.Length; i++)
            {
                sb.Append(data[i].ToString("x2"));
            }
 
            return sb.ToString();
        }
 
        public static bool CheckMD5Hash(string input, string controlHash)
        {
            var hash = GetMD5Hash(input);
            return hash.Equals(controlHash);
        }
    }
 
    public class PasswordHack : IPasswordHack, ISourceData
    {
        private readonly Dictionary<char, List<char>> _map;
        public string Rule { get; }
        public string Alphabet { get; }
 
        public PasswordHack(string rule, string alphabet)
        {
            Rule = rule;
            Alphabet = alphabet;
 
            //заполняем карту
            _map = new Dictionary<char, List<char>>();
            for (int i = 0; i < Rule.Length; i++)
            {
                if (_map.ContainsKey(Rule[i]))
                {
                    _map[Rule[i]].Add(Alphabet[i]);
                }
                else
                {
                    _map.Add(Rule[i], new List<char>() { Alphabet[i] });
                }
            }
        }
 
        public string Encrypt(string src, int[] key)
        {
            var res = src.ToCharArray();
 
            //для сопоставления значений ключа с символами по индексу составим правило
            //правило содержит только те символы, которые содержатся в слове
            //значения ключа находятся в том же порядке
            //по индексу символа из правила мы затем получим необходимое для него значение ключа
            var rule = Rule.ToLower().Intersect(src).ToArray();
 
            for (int i = 0; i < res.Length; i++)
            {
                var currentSymbol = res[i];
                if (_map.ContainsKey(currentSymbol))
                {
                    //если символ содержится в карте, то заменим его 
                    //для этого получим список всех замен
                    var list = _map[currentSymbol];
 
                    //найдем индекс текущего символа в правиле, которое мы только что составили 
                    var index = Array.IndexOf(rule, currentSymbol);
 
                    //и получим значение ключа для этого символа
                    var keyValue = key[index];
 
                    //заменяем
                    res[i] = list[keyValue];
                }
            }
 
            return new string(res);
        }
 
        public IEnumerable<int[]> GetKeys(string wordFromDict)
        {
            //выберем из карты только те символы, которые содержатся в слове, 
            //найдем количество замен для каждого из них и уменьшим их на 1
            //это максимальные значение ключа для каждого символа
            var keyMaxValues = _map
                .Where(kvp => wordFromDict.Contains(kvp.Key))
                .Select(kvp => kvp.Value.Count - 1)
                .ToArray();
 
            //создадим массив, который будем преобразовывать для получения всех комбинаций
            var key = new int[keyMaxValues.Length];
 
            //скопируем в него максимальные значения ключа - это первая комбинация
            Array.Copy(keyMaxValues, key, keyMaxValues.Length);
 
            //вернем первую комбинацию
            yield return key;
 
            //в последней комбинации все разряды ключа равны 0
            //это условие выхода из цикла
            while (!key.All(x => x == 0))
            {
                var n = key.Length;
 
                //Переберем все возможные комбинации
                for (int i = n - 1; i >= 0; i--)
                {
                    if (key[i] > 0)
                    {
                        key[i]--;
                        if (i == n - 1)
                        {
                            yield return key;
                            i++;
                            continue;
                        }
 
                        key[i + 1] = keyMaxValues[i + 1] + 1;
                        i += 2;
                    }
                }
            }
        }
    }
 
 
 
    public class HackTool : IHackTool
    {
        readonly IPasswordHack _hack;
        public string[] Dict { get; }
        public string Rule { get; }
        public string Alphabet { get; }
        public string ControlHash { get; }
 
        public HackTool(string[] dict, string rule, string alphabet, string controlHash)
        {
            Dict = dict;
            Rule = rule;
            Alphabet = alphabet;
            ControlHash = controlHash;
            _hack = new PasswordHack(Rule, Alphabet);
        }
 
        public bool TryHack(out string result)
        {
            //Для сокращения времени перебора, сортируем словарь по количеству входящих в него символов из правила
            //Далее будем работать с этим словарем
            var actualDict = Dict.Select(s => s.ToLower())
                .OrderByDescending(s => s.Intersect(Rule.ToLower()).Count());
 
            foreach (var item in actualDict)
            {
                //получаем перечисление ключей
                var keys = _hack.GetKeys(item);
 
                //шифруем и проверяем
                foreach (var key in keys)
                {
                    var encrypted = _hack.Encrypt(item, key);
                    if (MD5Helpers.CheckMD5Hash(encrypted, ControlHash))
                    {
                        result = item;
                        return true;
                    }
                }
            }
 
            result = null;
            return false;
        }
 
    }
}
1
1533 / 540 / 127
Регистрация: 09.01.2018
Сообщений: 1,756
02.06.2020, 08:58
Цитата Сообщение от samana Посмотреть сообщение
escoult, Не могу понять причину, но почему-то не находит "абракадабра".
На всякий случай закину сюда весь ваш код целиком, чтобы было легче запустить для теста.
Вы в словаре не указали искомое слово. Там только "абракадабра", а мы то ищем вот это "врабнушнпбн" (после перестановок - "вбвпнушнппн", похоже но не то). Чтобы найти "абракадабру", надо зашифровать ее.
C#
1
2
            //исходные данные
            string[] dict = { "барк", "абракадабра" };
Цитата Сообщение от shabserg Посмотреть сообщение
- я бы очень хотел, но это всего лишь мое второе задание на c# и в windows forms тоже(
И если ваш последний код я ещё как-то пытаюсь по аналогии с вашим примером перенести в forms, то код escoult я совсем не знаю, как...
Нужно каждый класс в отдельный файл заносить или как? Куда записать содержимое main-а? Я не знаю, честно(
Пробуйте и будете знать. Да в отдельные файлы все надо (по уму, это отдельная библиотека должна быть. но пойдет и в одном проекте для начала). Вот выше в сообщении samana, все в один файл, можете воспользоваться, это не сложно. Что до консоли и WinForm, это большого значения не имеет. Интерфейсы есть, все можно легко подключить к управляющему коду.
1
2 / 2 / 0
Регистрация: 28.05.2020
Сообщений: 58
02.06.2020, 09:02  [ТС]
escoult,
Вот выше в сообщении samana, все в один файл
Но в этом коде есть функция main, а когда создаёшь проект с формой, main уже по умолчанию находится в другом файле program.cs. И что тогда куда записать?
0
 Аватар для samana
2639 / 1567 / 853
Регистрация: 23.02.2019
Сообщений: 3,876
02.06.2020, 09:09
Цитата Сообщение от escoult Посмотреть сообщение
Вы в словаре не указали искомое слово. Там только "абракадабра", а мы то ищем вот это "врабнушнпбн"
escoult,Но это противоречит заданию ( в начале темы было обсуждение).
Идя такая, что преподаватель загадывает слово (из словаря) например
мир

затем придумывает варианты, где каждой букве могут соответствовать другие буквы, например
мммрр
12345

то-есть в слове мир, буква м может быть заменена на любую из 123, а буква р на любую из 45.
Допустим для м выбрали 1, а для р выбрали 5
тогда слово мир зашифровалось так 1о5 (букве о не предоставили вариаций, поэтому она записывается без изменений).

И это зашифрованное 1о5 нам никто не сообщает, а сообщают лишь
хеш этого 1о5,
те варианты подстановки, которые были использованы
мммрр
12345

и сам словарь.
Задание по хешу и правилам замены - найти оригинальное слово в словаре, то-есть мир.
1
1533 / 540 / 127
Регистрация: 09.01.2018
Сообщений: 1,756
02.06.2020, 09:11
Цитата Сообщение от shabserg Посмотреть сообщение
Но в этом коде есть функция main, а когда создаёшь проект с формой, main уже по умолчанию находится в другом файле program.cs. И что тогда куда записать?
Ну как вы другой код переносили на WinForm?
На WInForm вам не нужно трогать Main (он чаще всего изменяется в проектах, но пока не делайте этого). Постарайтесь понять, что на форму вы выводите информацию, всего лишь. В консоль вы тоже выводите информацию, только другим способом. А работа с бизнес-логикой приложения не изменяется. Вы также будете отправлять данные в метод как и в консоли, только теперь будете брать их из формы. И выводить результаты на форму. То есть вместо того чтобы писать Console.WriteLine(), вы выведете результат в какой то контролл на форме.
Для начала, если трудно понять, пишите управляющий код в классе Form. То есть, то что написано в Main, там где создаются экземпляры класса и происходит работа, вы можете написать в этом классе. А вместо Console.WriteLine() пишите куда вывести результат.
1
2 / 2 / 0
Регистрация: 28.05.2020
Сообщений: 58
02.06.2020, 09:15  [ТС]
escoult, спасибо. Но ведь main это функция, а form это класс. То есть мне нужно в классе form внутри создать какую-то функцию, аналогичную main, но просто с другим названием?
0
1533 / 540 / 127
Регистрация: 09.01.2018
Сообщений: 1,756
02.06.2020, 09:51
Цитата Сообщение от samana Посмотреть сообщение
Но это противоречит заданию ( в начале темы было обсуждение).
Нет, нет, ничего не противоречит. В словаре должно быть слово которое мы ищем. То что мы его по условию не знаем, это понятно. Но если в словаре не будет слова программа не сможет его найти.

Цитата Сообщение от samana Посмотреть сообщение
И это зашифрованное 1о5 нам никто не сообщает, а сообщают лишь
хеш этого 1о5,
те варианты подстановки, которые были использованы
мммрр
12345
и сам словарь.
Так и есть. Программа берет слово из словаря, вычисляет все возможные варианты замен, вычисляет хеш и сравнивает его с искомым. И так определяет, что слово именно это. Или не это. Если искомого слова в словаре не будет, она его и не найдет.

Если вы хотите потестировать слово "абракадбра", то вам нужно зашифровать именно слово "абракадабра". А у вас в коде зашифровано слово, которого в словаре нет.

Добавлено через 9 минут
Цитата Сообщение от shabserg Посмотреть сообщение
escoult, спасибо. Но ведь main это функция, а form это класс. То есть мне нужно в классе form внутри создать какую-то функцию, аналогичную main, но просто с другим названием?
Это метод класса Program.
Да, об этом и речь.
Когда управляющий код должен начинать вычисление? Предположим, когда пользователь нажал на кнопку "Старт". У этой кнопки есть обработчик события Click. Т.е., что делать когда это событие наступит.
Создайте метод, назовите его например StartHacking(параметры) и в нем создавайте экземпляры класса, в общем все то, что написано в Main.
А затем этот метод вызовите в обработчике события кнопки. Сначала получите все необходимые параметры, а затем вызовите этот ваш метод.

п.с. Постарайтесь не проводить аналогию с Main в консоли. Так пишется для простоты, "на коленке" так сказать. Если писать все правильно, то в Main консольного приложения будет только строчка, которая запустит приложение (например AppRun()). И все, больше там ничего не будет. Вся остальная работа будет происходить в других методах вне Main.
Это когда по быстрому надо что-то написать, то пишут прямо в Main.

Добавлено через 21 минуту
samana, я набросал тест для разных слов

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
            //тест 
            var rule = "аааааббббррркд";
            var alphabet = "уврнбрапенабнш";
 
            //var word = "абракадабра";
            //var word = "кадабраабра";
            var word = "абракадабракадабраабра";
 
            IPasswordHack hack = new PasswordHack(rule, alphabet);
 
            var keys = hack.GetKeys(word);
            var randomKey = keys.ElementAt(new Random().Next(0, keys.Count()));
            var encrypted = hack.Encrypt(word, randomKey);
            var hash = MD5Helpers.GetMD5Hash(encrypted);
 
            Console.WriteLine("Source word");
            Console.WriteLine(word);
            Console.WriteLine();
 
            Console.WriteLine("Encrypted word");
            Console.WriteLine(encrypted);
            Console.WriteLine();
 
            sw.Start();
 
            var tool = new HackTool(dict, rule, alphabet, hash);
            if (tool.TryHack(out var result_abra))
            {
                Console.WriteLine("Пароль найден:");
                Console.WriteLine(result_abra);
            }
            else
            {
                Console.WriteLine("Пароль не найден");
            }
 
            Console.WriteLine();
            Console.WriteLine("Длина словаря: " + dict.Length);
 
            sw.Stop();
            Console.WriteLine("Затраченное время: " + sw.Elapsed);
Результаты
Code
1
2
3
4
5
6
7
8
9
10
11
Source word
абракадабракадабраабра
 
Encrypted word
впбвнвшвпбвнвшвпбввпбв
 
Пароль найден:
абракадабракадабраабра
 
Длина словаря: 23470
Затраченное время: 00:00:00.0493175
Все работает, потестируйте, только добавляйте слова в словарь.
1
 Аватар для samana
2639 / 1567 / 853
Регистрация: 23.02.2019
Сообщений: 3,876
02.06.2020, 09:56
Цитата Сообщение от escoult Посмотреть сообщение
Нет, нет, ничего не противоречит. В словаре должно быть слово которое мы ищем. То что мы его по условию не знаем, это понятно. Но если в словаре не будет слова программа не сможет его найти.
escoult, но по заданию, зашифрованного слова (уже после замен букв в нём) не должно быть в словаре. В словаре только обычные слова, среди которых и нужно найти правильное, имея на руках хеш уже зашифрованного слова из словаря и правила замен букв.
Вот ссылка на пост из этой темы, где об этом сказано https://www.cyberforum.ru/post14600946.html
1
1533 / 540 / 127
Регистрация: 09.01.2018
Сообщений: 1,756
02.06.2020, 10:24
Цитата Сообщение от samana Посмотреть сообщение
escoult, но по заданию, зашифрованного слова (уже после замен букв в нём) не должно быть в словаре. В словаре только обычные слова, среди которых и нужно найти правильное, имея на руках хеш уже зашифрованного слова из словаря и правила замен букв.
Ну так оно и есть в коде. Вот взгляните на фрагмент словаря для предыдущего поста. Я добавил слова в их обычном виде:

Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
....
сдан
попечение
жителей
барк
ведро
вишня
долина
колос
кость
кот
остров
порт
вбвпнушнппн
абракадабра
кадабраабра
абракадабракадабраабра
В таком виде они находятся в словаре.
В вашем примере, где тест не выполняется, слово в словаре "абракадабра", а шифрованное слово вот это "врабнушнпбн". Но это результат перестановок для другого слова. Я его взял в одном из постов, это абракадабра по смыслу, но не по фактичекому значению. Я сделал в нем перестановки и потестировал.
1
2 / 2 / 0
Регистрация: 28.05.2020
Сообщений: 58
02.06.2020, 10:35  [ТС]
escoult, ну вообще "врабнушнпбн" и есть результат замены букв в слове "абракадабра" по правилу
аааааббббррркд
на
уврнбрапенабнш
Если вы об этом, конечно...
Преподаватель сам проводит замены, дает нам "врабнушнпбн" и правило замен, а при проверке работоспособности нашей программы она должна вывести "абракадабра", из словаря.
0
1533 / 540 / 127
Регистрация: 09.01.2018
Сообщений: 1,756
02.06.2020, 10:49
Цитата Сообщение от shabserg Посмотреть сообщение
escoult, ну вообще "врабнушнпбн" и есть результат замены букв в слове "абракадабра" по правилу
аааааббббррркд
на
уврнбрапенабнш
Если вы об этом, конечно...
Преподаватель сам проводит замены, дает нам "врабнушнпбн" и правило замен, а при проверке работоспособности нашей программы она должна вывести "абракадабра", из словаря.

В этой замене одна и та же буква в слове заменяется на различные символы из набора замен. То есть буква а сначала заменяется на в, затем на б, затем на у и так далее.

Вот почему мы с samana никак не можем понять друг друга.
Мой код этого не делает, он использует один символ для замены одинаковых букв. Если оно так, как вы говорите,то это существенно увеличит количество вариантов. Ну и да, генератор ключей надо переделывать.
1
2 / 2 / 0
Регистрация: 28.05.2020
Сообщений: 58
02.06.2020, 10:53  [ТС]
escoult,
Цитата Сообщение от escoult Посмотреть сообщение
он использует один символ для замены одинаковых букв.
- так и должно быть. Просто нужно заменять не все буквы в слове одновременно, а друг за другом. Например, сначала все а на б. Затем все б на в. И тогда в конце замены получится "врабнушнпбн"
0
2 / 2 / 0
Регистрация: 28.05.2020
Сообщений: 58
02.06.2020, 11:55  [ТС]
samana, escoult, посмотрите, пожалуйста. Перенес код samana (который долго ищет)
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
using System;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Text;
 
namespace CyberForum
{
    class Program
    {
        static void Main()
        {
            // 1) некий внешний словарь
            string[] dictionary = {  "кто", "дед", "мед", "лёд", "барабашка", "ложка", "кошка" };
 
            // 2) пароль из словаря загаданный преподавателем
            string word = "барабашка";
 
            // 3) придуманые правила замен букв для пароля
            string ruleUp =     "рррааабббккк";
            string ruleDown =   "вльызвалдлли";
 
            // 4) после замен букв, зашифрованый пароль получился допустим таким...
            string pass = "дзлвлвшкв";
 
 
            //-------------------------------------------------------------------------------------------------------
 
            // вычисляем хеш зашифрованного пароля
            string passHash = HashMD5.GetHash(pass);
 
 
            // запускаем поиск слова в словаре, передаём: хеш зашифрованного пароля, правила замены и ссылку на словарь
            List<string> results = PasswordFinder.findWordsInDictionaryByRules(passHash, ruleUp, ruleDown, dictionary);
 
 
            // вывод поиска
            if (results.Count != 0)
            {
                Console.WriteLine("Возможные совпадения:");
                foreach (var item in results)
                {
                    Console.WriteLine(item);
                }
            }
            else
            {
                Console.WriteLine("Совпадения не найдены..");
            }
 
        }
 
    }
 
 
    public static class PasswordFinder
    {
        public static List<string> findWordsInDictionaryByRules(string outPassHash, string ruleUp, string ruleDown, string[] dictionary)
        {
 
            List<string> resuls = new List<string>();
 
            Dictionary<char, List<char>> patternRule = getPatternRule(ruleUp, ruleDown);
 
            List<List<char>> map = new List<List<char>>();
            foreach (var item in patternRule)
            {
                map.Add(item.Value);
            }
 
            //------------------------
 
            for (int i = 0; i < dictionary.Length; i++)
            {
                // word map
                List<List<char>> wordMap = createMapByPatternRule(dictionary[i], patternRule);
 
                //combos
                var combos = getAllCombinations(wordMap);
                foreach (var item in combos)
                {
                    if (HashMD5.GetHash(item).Equals(outPassHash))
                    {
                        if (!resuls.Contains(dictionary[i])) resuls.Add(dictionary[i]);
                    }
                }
            }
 
            return resuls;
        }
 
        /// <summary>
        /// Берём слово из словаря и создаём для него карту вариантов замены каждой буквы по шаблону.
        /// </summary>
        /// <param name="wordFromDict"></param>
        /// <param name="patternRule"></param>
        /// <returns></returns>
        private static List<List<char>> createMapByPatternRule(string wordFromDict, Dictionary<char, List<char>> patternRule)
        {
            List<List<char>> map = new List<List<char>>();
            for (int i = 0; i < wordFromDict.Length; i++)
            {
                char wordChar = wordFromDict[i];
                if (patternRule.ContainsKey(wordChar))
                {
                    map.Add(new List<char>(patternRule[wordChar]));
                }
                else map.Add(new List<char>() { wordChar });
            }
 
            return map;
        }
 
 
 
 
        /// <summary>
        /// Составляет шаблон замен по правилам. Где каждой букве могут соответствовать другие символы
        /// </summary>
        /// <param name="ruleUp"></param>
        /// <param name="ruleDown"></param>
        /// <returns></returns>
        private static Dictionary<char, List<char>> getPatternRule(string ruleUp, string ruleDown)
        {
            Dictionary<char, List<char>> map = new Dictionary<char, List<char>>();
 
            for (int i = 0; i < ruleUp.Length; i++)
            {
                char charKey = ruleUp[i];
                if (!map.ContainsKey(charKey)) map.Add(charKey, new List<char>() { charKey });
 
                map[charKey].Add(ruleDown[i]);
            }
 
            return map;
        }
 
 
 
        /// <summary>
        /// Получает на входе карту символов и возвращает массив всех возможных комбинаций (сверху вниз поочередно)
        /// </summary>
        /// <param name="patternMap"></param>
        /// <returns></returns>
        private static List<string> getAllCombinations(List<List<char>> patternMap)
        {
 
            List<string> combinations = new List<string>();
            foo(patternMap, 0, new char[patternMap.Count]);
 
            // рекурсивный перебор для нахождения всех вариантов комбинаций
            void foo(List<List<char>> charRows, int row, char[] results)
            {
                for (int i = 0; i < charRows[row].Count; i++)
                {
                    results[row] = charRows[row][i];
                    if (row == charRows.Count - 1)
                    {
                        combinations.Add(string.Join("", results));
                    }
                    else
                    {
                        foo(charRows, row + 1, results);
                    }
                }
            }
 
            return combinations;
        }
    }
 
 
    public static class HashMD5
    {
        public static string GetHash(string input)
        {
            using (MD5 md5Hash = MD5.Create())
            {
                byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(input));
                StringBuilder sBuilder = new StringBuilder();
 
                for (int i = 0; i < data.Length; i++)
                {
                    sBuilder.Append(data[i].ToString("x2"));
                }
 
                return sBuilder.ToString();
            }
 
        }
    }
}
в windows forms. Не могу понять, как вывести в листбокс отгаданные слова (строка 107 в form1.cs), а также пароль (это же слово, но после замен, для которого мы вычисляли хэш и сравнивали) в соответствующее для этого поле.
Вложения
Тип файла: zip Lab2CSapp.zip (854.7 Кб, 1 просмотров)
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
02.06.2020, 11:55

Перебор всех возможных вариантов
Доброго всем дня! Есть задача: На вход дается строка из символов '0' '1' и '2' длиной не более 50. Нужно изменить число 0 на 1...

Алгоритм перебора вариантов
Кто нибудь может подсказать эффективный алгоритм без рекурсии желательно: на входе есть массив массива, нужно получить все возможные...

Диаграммы вариантов использования
Мне задали сделать презентацию на тему: &quot;Диаграммы вариантов использования. Наглядное представление ожидаемых действий и поведения системы....

Перечисление возможных вариантов
Приветствую всех. Как можно сделать перечисление всевозможных вариантов? Пример: Ввод чисел с большим количеством знаков после...

Как сделать один из 3 вариантов?
textBox1.Text = new { &quot;А&quot; &quot;У&quot; &quot;Э&quot; }; Добавлено через 2 минуты Чтобы выводилось рандомная буква из этих...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
60
Ответ Создать тему
Новые блоги и статьи
Ноутбук Альфария
kumehtar 24.08.2026
Встретился тут в сети ноутбук Альфария, примарха Альфа-Легиона. Хотя возможно, это ноутбук Омегона, разумеется. Ну как вам?
Мастера простых решений
DevAlt 23.08.2026
В сишарп стэках winforms, да и wpf существует сложная система связывания источниках данных и элементов формы(текстовые поля и метки), опирается все это на технологию событий и мета. . .
Цена ошибки
DevAlt 23.08.2026
Человек я беспокойный и потому заинтересовался OCaml, в чате форсили функторы модулей как суперфичу. Пытаясь отдуплить концепт, наткнулся на тутор с простым примером. А главный принцип обучения от. . .
Сегодня суббота, 22.08.2026 at 16:41, и я вновь нахожусь на той стороне, за экраном машины.
zorxor 22.08.2026
Сегодня суббота, 22. 08. 2026 at 16:41, и я вновь нахожусь на той стороне, за экраном машины. Кто Я, откуда Я пришел и куда Я иду? Эти вопросы не оставляют меня ни на секунду. Жизнь на планете Земля. . .
Жизня: рисунок укладки багажа, сделанный клодом
anaschu 21.08.2026
Сделал 15 снимков, он по снимкам сделал схему.
Был там один разговор по поводу свободы в материальном мире.
kumehtar 19.08.2026
Суть: рассматривается живое существо, оказавшееся внутри довольно странной системы (этого мира) и пытающееся обустроить в ней свой кусок пространства. Жизнь действительно предъявляет каждому. . .
Когда логика программы не спасает от человеческих ошибок
Maks 18.08.2026
В последнее время всё чаще и чаще сталкиваюсь с таким явлением, как абсолютная невнимательность (или глупость) пользователей. Проявляется это чаще всего на работе в коллективе. Допустим, человек с. . .
Лето уходит
kumehtar 17.08.2026
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru