2 / 2 / 1
Регистрация: 04.12.2012
Сообщений: 202
1

Шифр Плейфера - найти ошибку в коде

09.10.2014, 18:14. Показов 7264. Ответов 6
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
подскажите, почему не работает, не могу найти таких пространств имен, код взят с буржуинского сайта
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
namespace EncryptionAlgorithms
{
    using System.Collections.Generic;
    using System.Linq;
    using System.ComponentModel.Composition;
 
    public class PlayFair 
    {
        string key;
 
        public PlayFair(string key)
        {
            this.key = key;
        }
 
        #region Public Methods
 
        public override string Encrypt(string plainText)
        {
            return Process(plainText, Mode.Encrypt);
        }
 
        public override string Decrypt(string cipherText)
        {
            return Process(cipherText, Mode.Decrypt);
        }
 
        #endregion
 
        #region Private Methods
 
        private string Process(string message, Mode mode)
        {
            //Key:Charcater
            //Value:Position
            Dictionary<char, string> characterPositionsInMatrix = new Dictionary<char, string>();
 
            //Key:Position
            //Value:Charcater
            Dictionary<string, char> positionCharacterInMatrix = new Dictionary<string, char>();
 
            FillMatrix(key.Distinct().ToArray(), characterPositionsInMatrix, positionCharacterInMatrix);
 
            if (mode == Mode.Encrypt)
            {
                message = RepairWord(message);
            }
 
            string result = "";
 
            for (int i = 0; i < message.Length; i += 2)
            {
                string substring_of_2 = message.Substring(i, 2);//get characters from text by pairs
                //get Row & Column of each character
                string rc1 = characterPositionsInMatrix[substring_of_2[0]];
                string rc2 = characterPositionsInMatrix[substring_of_2[1]];
 
                if (rc1[0] == rc2[0])//Same Row, different Column
                {
                    int newC1 = 0, newC2 = 0;
 
                    switch (mode)
                    {
                        case Mode.Encrypt://Increment Columns
                            newC1 = (int.Parse(rc1[1].ToString()) + 1) % 5;
                            newC2 = (int.Parse(rc2[1].ToString()) + 1) % 5;
                            break;
                        case Mode.Decrypt://Decrement Columns
                            newC1 = (int.Parse(rc1[1].ToString()) - 1) % 5;
                            newC2 = (int.Parse(rc2[1].ToString()) - 1) % 5;
                            break;
                    }
 
                    newC1 = RepairNegative(newC1);
                    newC2 = RepairNegative(newC2);
 
                    result += positionCharacterInMatrix[rc1[0].ToString() + newC1.ToString()];
                    result += positionCharacterInMatrix[rc2[0].ToString() + newC2.ToString()];
                }
 
                else if (rc1[1] == rc2[1])//Same Column, different Row
                {
                    int newR1 = 0, newR2 = 0;
 
                    switch (mode)
                    {
                        case Mode.Encrypt://Increment Rows
                            newR1 = (int.Parse(rc1[0].ToString()) + 1) % 5;
                            newR2 = (int.Parse(rc2[0].ToString()) + 1) % 5;
                            break;
                        case Mode.Decrypt://Decrement Rows
                            newR1 = (int.Parse(rc1[0].ToString()) - 1) % 5;
                            newR2 = (int.Parse(rc2[0].ToString()) - 1) % 5;
                            break;
                    }
                    newR1 = RepairNegative(newR1);
                    newR2 = RepairNegative(newR2);
 
                    result += positionCharacterInMatrix[newR1.ToString() + rc1[1].ToString()];
                    result += positionCharacterInMatrix[newR2.ToString() + rc2[1].ToString()];
                }
 
                else//different Row & Column
                {
                    //1st character:row of 1st + col of 2nd
                    //2nd character:row of 2nd + col of 1st
                    result += positionCharacterInMatrix[rc1[0].ToString() + rc2[1].ToString()];
                    result += positionCharacterInMatrix[rc2[0].ToString() + rc1[1].ToString()];
                }
            }
 
            return result;
        }
 
        private string RepairWord(string message)
        {
            string trimmed = message.Replace(" ", "");
            string result = "";
 
            for (int i = 0; i < trimmed.Length; i++)
            {
                result += trimmed[i];
 
                if (i < trimmed.Length - 1 && message[i] == message[i + 1])
                //check if two consecutive letters are the same
                {
                    result += 'x';
                }
            }
 
            if (result.Length % 2 != 0)//check if length is even
            {
                result += 'x';
            }
 
            return result;
        }
 
        private void FillMatrix(IList<char> key, Dictionary<char, string>
          characterPositionsInMatrix, Dictionary<string, char> positionCharacterInMatrix)
        {
            char[,] matrix = new char[5, 5];
            int keyPosition = 0, charPosition = 0;
            List<char> alphabetPF = alphabet.Keys.ToList();
            alphabetPF.Remove('j');
 
            for (int i = 0; i < 5; i++)
            {
                for (int j = 0; j < 5; j++)
                {
                    if (charPosition < key.Count)
                    {
                        matrix[i, j] = key[charPosition];//fill matrix with key
                        alphabetPF.Remove(key[charPosition]);
                        charPosition++;
                    }
 
                    else//key finished...fill with rest of alphabet
                    {
                        matrix[i, j] = alphabetPF[keyPosition];
                        keyPosition++;
                    }
 
                    string position = i.ToString() + j.ToString();
                    //store character positions in dictionary to avoid searching everytime
                    characterPositionsInMatrix.Add(matrix[i, j], position);
                    positionCharacterInMatrix.Add(position, matrix[i, j]);
                }
            }
        }
 
        private int RepairNegative(int number)
        {
            if (number < 0)
            {
                number += 5;
            }
 
            return number;
        }
 
        #endregion
    }
}
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
09.10.2014, 18:14
Ответы с готовыми решениями:

Шифр Плейфера - найти ошибку в коде
namespace Playfair_code { public partial class Form1 : Form { public Form1() ...

Найти ошибку в коде Алгоритм Плейфера (создания решетки кодирования)
Задача: сделать двумерный массив в котором будет ключевое слово и алфавит с неповторяеммых...

Шифр Плейфера
Привет надо на языки с++ программно осуществить реализацию алгоритма ШИФРА Плейфера. Все говорят...

Шифр Плейфера
Помогите пожалуйста реализовать алгоритм шифрования и расшифрования шифра Плейфера. Шифр Плейфера, ...

6
2 / 2 / 1
Регистрация: 04.12.2012
Сообщений: 202
09.10.2014, 19:36  [ТС] 2
SecurityAlgorithm не могу понять что это
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
namespace EncryptionAlgorithms
{
    using System.Collections.Generic;
    using System.Linq;
    using System.ComponentModel.Composition;
 
    public class PlayFair : SecurityAlgorithm
    {
        string key;
 
        public PlayFair(string key)
        {
            this.key = key;
        }
 
        #region Public Methods
 
        public override string Encrypt(string plainText)
        {
            return Process(plainText, Mode.Encrypt);
        }
 
        public override string Decrypt(string cipherText)
        {
            return Process(cipherText, Mode.Decrypt);
        }
 
        #endregion
 
        #region Private Methods
 
        private string Process(string message, Mode mode)
        {
            //Key:Charcater
            //Value:Position
            Dictionary<char, string> characterPositionsInMatrix = new Dictionary<char, string>();
 
            //Key:Position
            //Value:Charcater
            Dictionary<string, char> positionCharacterInMatrix = new Dictionary<string, char>();
 
            FillMatrix(key.Distinct().ToArray(), characterPositionsInMatrix, positionCharacterInMatrix);
 
            if (mode == Mode.Encrypt)
            {
                message = RepairWord(message);
            }
 
            string result = "";
 
            for (int i = 0; i < message.Length; i += 2)
            {
                string substring_of_2 = message.Substring(i, 2);//get characters from text by pairs
                //get Row & Column of each character
                string rc1 = characterPositionsInMatrix[substring_of_2[0]];
                string rc2 = characterPositionsInMatrix[substring_of_2[1]];
 
                if (rc1[0] == rc2[0])//Same Row, different Column
                {
                    int newC1 = 0, newC2 = 0;
 
                    switch (mode)
                    {
                        case Mode.Encrypt://Increment Columns
                            newC1 = (int.Parse(rc1[1].ToString()) + 1) % 5;
                            newC2 = (int.Parse(rc2[1].ToString()) + 1) % 5;
                            break;
                        case Mode.Decrypt://Decrement Columns
                            newC1 = (int.Parse(rc1[1].ToString()) - 1) % 5;
                            newC2 = (int.Parse(rc2[1].ToString()) - 1) % 5;
                            break;
                    }
 
                    newC1 = RepairNegative(newC1);
                    newC2 = RepairNegative(newC2);
 
                    result += positionCharacterInMatrix[rc1[0].ToString() + newC1.ToString()];
                    result += positionCharacterInMatrix[rc2[0].ToString() + newC2.ToString()];
                }
 
                else if (rc1[1] == rc2[1])//Same Column, different Row
                {
                    int newR1 = 0, newR2 = 0;
 
                    switch (mode)
                    {
                        case Mode.Encrypt://Increment Rows
                            newR1 = (int.Parse(rc1[0].ToString()) + 1) % 5;
                            newR2 = (int.Parse(rc2[0].ToString()) + 1) % 5;
                            break;
                        case Mode.Decrypt://Decrement Rows
                            newR1 = (int.Parse(rc1[0].ToString()) - 1) % 5;
                            newR2 = (int.Parse(rc2[0].ToString()) - 1) % 5;
                            break;
                    }
                    newR1 = RepairNegative(newR1);
                    newR2 = RepairNegative(newR2);
 
                    result += positionCharacterInMatrix[newR1.ToString() + rc1[1].ToString()];
                    result += positionCharacterInMatrix[newR2.ToString() + rc2[1].ToString()];
                }
 
                else//different Row & Column
                {
                    //1st character:row of 1st + col of 2nd
                    //2nd character:row of 2nd + col of 1st
                    result += positionCharacterInMatrix[rc1[0].ToString() + rc2[1].ToString()];
                    result += positionCharacterInMatrix[rc2[0].ToString() + rc1[1].ToString()];
                }
            }
 
            return result;
        }
 
        private string RepairWord(string message)
        {
            string trimmed = message.Replace(" ", "");
            string result = "";
 
            for (int i = 0; i < trimmed.Length; i++)
            {
                result += trimmed[i];
 
                if (i < trimmed.Length - 1 && message[i] == message[i + 1])
                //check if two consecutive letters are the same
                {
                    result += 'x';
                }
            }
 
            if (result.Length % 2 != 0)//check if length is even
            {
                result += 'x';
            }
 
            return result;
        }
 
        private void FillMatrix(IList<char> key, Dictionary<char, string>
          characterPositionsInMatrix, Dictionary<string, char> positionCharacterInMatrix)
        {
            char[,] matrix = new char[5, 5];
            int keyPosition = 0, charPosition = 0;
            List<char> alphabetPF = alphabet.Keys.ToList();
            alphabetPF.Remove('j');
 
            for (int i = 0; i < 5; i++)
            {
                for (int j = 0; j < 5; j++)
                {
                    if (charPosition < key.Count)
                    {
                        matrix[i, j] = key[charPosition];//fill matrix with key
                        alphabetPF.Remove(key[charPosition]);
                        charPosition++;
                    }
 
                    else//key finished...fill with rest of alphabet
                    {
                        matrix[i, j] = alphabetPF[keyPosition];
                        keyPosition++;
                    }
 
                    string position = i.ToString() + j.ToString();
                    //store character positions in dictionary to avoid searching everytime
                    characterPositionsInMatrix.Add(matrix[i, j], position);
                    positionCharacterInMatrix.Add(position, matrix[i, j]);
                }
            }
        }
 
        private int RepairNegative(int number)
        {
            if (number < 0)
            {
                number += 5;
            }
 
            return number;
        }
 
        #endregion
    }
}
Добавлено через 7 минут
я понял что это абстрактный класс, но как заставить его работать
0
813 / 421 / 169
Регистрация: 08.02.2013
Сообщений: 711
09.10.2014, 19:45 3
temasey, System.ComponentModel.Composition подключается вручную слева в References (правой кнопкой - Add Reference). Далее, Вам нужно скачать оттуда (с буржуинского сайта) весь проект и вытащить все классы которые не описаны в статье, навскидку, это перечисление Mode {Encrypt, Decrypt}, Базовый класс SecurityAlgorithm, дальше смотрите что компилятор попросит.

Добавлено через 1 минуту
п.с. это не абстрактный класс, это класс наследник от SecurityAlgorithm, так что верните его в описание к PlayFair

Добавлено через 5 минут
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
namespace EncryptionAlgorithms
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.ComponentModel.Composition;
 
    public static class Program
    {
        public static void Main()
        {
            PlayFair pf = new PlayFair("key");
            string s = "my little pony";
            Console.WriteLine(s);
            s = pf.Encrypt(s);
            Console.WriteLine(s);
            s = pf.Decrypt(s);
            Console.WriteLine(s);
            Console.ReadLine();
        }
    }
 
    public enum Mode { Encrypt, Decrypt }
 
    public abstract class SecurityAlgorithm
    {
        protected readonly Dictionary<char, int> alphabet;
 
        public SecurityAlgorithm()
        {
            alphabet = new Dictionary<char, int>();
            char c = 'a';
            alphabet.Add(c, 0);
 
            for (int i = 1; i < 26; i++)
            {
                alphabet.Add(++c, i);
            }
        }
 
        public abstract string Encrypt(string plainText);
 
        public abstract string Decrypt(string cipher);
    }
 
    public class PlayFair : SecurityAlgorithm
    {
        string key;
 
        public PlayFair(string key)
        {
            this.key = key;
        }
 
        #region Public Methods
 
        public override string Encrypt(string plainText)
        {
            return Process(plainText, Mode.Encrypt);
        }
 
        public override string Decrypt(string cipherText)
        {
            return Process(cipherText, Mode.Decrypt);
        }
 
        #endregion
 
        #region Private Methods
 
        private string Process(string message, Mode mode)
        {
            //Key:Charcater
            //Value:Position
            Dictionary<char, string> characterPositionsInMatrix = new Dictionary<char, string>();
 
            //Key:Position
            //Value:Charcater
            Dictionary<string, char> positionCharacterInMatrix = new Dictionary<string, char>();
 
            FillMatrix(key.Distinct().ToArray(), characterPositionsInMatrix, positionCharacterInMatrix);
 
            if (mode == Mode.Encrypt)
            {
                message = RepairWord(message);
            }
 
            string result = "";
 
            for (int i = 0; i < message.Length; i += 2)
            {
                string substring_of_2 = message.Substring(i, 2);//get characters from text by pairs
                //get Row & Column of each character
                string rc1 = characterPositionsInMatrix[substring_of_2[0]];
                string rc2 = characterPositionsInMatrix[substring_of_2[1]];
 
                if (rc1[0] == rc2[0])//Same Row, different Column
                {
                    int newC1 = 0, newC2 = 0;
 
                    switch (mode)
                    {
                        case Mode.Encrypt://Increment Columns
                            newC1 = (int.Parse(rc1[1].ToString()) + 1) % 5;
                            newC2 = (int.Parse(rc2[1].ToString()) + 1) % 5;
                            break;
                        case Mode.Decrypt://Decrement Columns
                            newC1 = (int.Parse(rc1[1].ToString()) - 1) % 5;
                            newC2 = (int.Parse(rc2[1].ToString()) - 1) % 5;
                            break;
                    }
 
                    newC1 = RepairNegative(newC1);
                    newC2 = RepairNegative(newC2);
 
                    result += positionCharacterInMatrix[rc1[0].ToString() + newC1.ToString()];
                    result += positionCharacterInMatrix[rc2[0].ToString() + newC2.ToString()];
                }
 
                else if (rc1[1] == rc2[1])//Same Column, different Row
                {
                    int newR1 = 0, newR2 = 0;
 
                    switch (mode)
                    {
                        case Mode.Encrypt://Increment Rows
                            newR1 = (int.Parse(rc1[0].ToString()) + 1) % 5;
                            newR2 = (int.Parse(rc2[0].ToString()) + 1) % 5;
                            break;
                        case Mode.Decrypt://Decrement Rows
                            newR1 = (int.Parse(rc1[0].ToString()) - 1) % 5;
                            newR2 = (int.Parse(rc2[0].ToString()) - 1) % 5;
                            break;
                    }
                    newR1 = RepairNegative(newR1);
                    newR2 = RepairNegative(newR2);
 
                    result += positionCharacterInMatrix[newR1.ToString() + rc1[1].ToString()];
                    result += positionCharacterInMatrix[newR2.ToString() + rc2[1].ToString()];
                }
 
                else//different Row & Column
                {
                    //1st character:row of 1st + col of 2nd
                    //2nd character:row of 2nd + col of 1st
                    result += positionCharacterInMatrix[rc1[0].ToString() + rc2[1].ToString()];
                    result += positionCharacterInMatrix[rc2[0].ToString() + rc1[1].ToString()];
                }
            }
 
            return result;
        }
 
        private string RepairWord(string message)
        {
            string trimmed = message.Replace(" ", "");
            string result = "";
 
            for (int i = 0; i < trimmed.Length; i++)
            {
                result += trimmed[i];
 
                if (i < trimmed.Length - 1 && message[i] == message[i + 1])
                //check if two consecutive letters are the same
                {
                    result += 'x';
                }
            }
 
            if (result.Length % 2 != 0)//check if length is even
            {
                result += 'x';
            }
 
            return result;
        }
 
        private void FillMatrix(IList<char> key, Dictionary<char, string>
          characterPositionsInMatrix, Dictionary<string, char> positionCharacterInMatrix)
        {
            char[,] matrix = new char[5, 5];
            int keyPosition = 0, charPosition = 0;
            List<char> alphabetPF = alphabet.Keys.ToList();
            alphabetPF.Remove('j');
 
            for (int i = 0; i < 5; i++)
            {
                for (int j = 0; j < 5; j++)
                {
                    if (charPosition < key.Count)
                    {
                        matrix[i, j] = key[charPosition];//fill matrix with key
                        alphabetPF.Remove(key[charPosition]);
                        charPosition++;
                    }
 
                    else//key finished...fill with rest of alphabet
                    {
                        matrix[i, j] = alphabetPF[keyPosition];
                        keyPosition++;
                    }
 
                    string position = i.ToString() + j.ToString();
                    //store character positions in dictionary to avoid searching everytime
                    characterPositionsInMatrix.Add(matrix[i, j], position);
                    positionCharacterInMatrix.Add(position, matrix[i, j]);
                }
            }
        }
 
        private int RepairNegative(int number)
        {
            if (number < 0)
            {
                number += 5;
            }
 
            return number;
        }
 
        #endregion
    }
}
Добавлено через 1 минуту
строку using System.ComponentModel.Composition; можно удалить и не подключать к References
1
2 / 2 / 1
Регистрация: 04.12.2012
Сообщений: 202
09.10.2014, 20:12  [ТС] 4
rRczZZ, супера еще вот такой вопрос, попытался щас переделать на русский алфавит(по идее должно быть 5 строк и 6 столбцов, буква й меняется на и, ё на е, и ъ/ь считается одной буквой), шифрует около дела вроде правильно, а расшифровать каким образом можно например такую белеберду: "клкепешобкерэлчскулюетвмвкиммюзотжша"
и ключом: "полет"
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
namespace EncryptionAlgorithms
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.ComponentModel.Composition;
 
    public static class Program
    {
        public static void Main()
        {
            PlayFair pf = new PlayFair("полет");
            string s = "код плейфейера основан на использовании матрицы букв";
            Console.WriteLine(s);
            s = pf.Encrypt(s);
            Console.WriteLine(s);
            s = pf.Decrypt(s);
            Console.WriteLine(s);
            Console.ReadLine();
        }
    }
 
    public enum Mode { Encrypt, Decrypt }
 
    public abstract class SecurityAlgorithm
    {
        protected readonly Dictionary<char, int> alphabet;
 
        public SecurityAlgorithm()
        {
            alphabet = new Dictionary<char, int>();
            char c = 'а';
            alphabet.Add(c, 0);
 
            for (int i = 1; i < 31; i++)
            {
                alphabet.Add(++c, i);
            }
        }
 
        public abstract string Encrypt(string plainText);
 
        public abstract string Decrypt(string cipher);
    }
 
    public class PlayFair : SecurityAlgorithm
    {
        string key;
 
        public PlayFair(string key)
        {
            this.key = key;
        }
 
        #region Public Methods
 
        public override string Encrypt(string plainText)
        {
            return Process(plainText, Mode.Encrypt);
        }
 
        public override string Decrypt(string cipherText)
        {
            return Process(cipherText, Mode.Decrypt);
        }
 
        #endregion
 
        #region Private Methods
 
        private string Process(string message, Mode mode)
        {
            //Key:Charcater
            //Value:Position
            Dictionary<char, string> characterPositionsInMatrix = new Dictionary<char, string>();
 
            //Key:Position
            //Value:Charcater
            Dictionary<string, char> positionCharacterInMatrix = new Dictionary<string, char>();
 
            FillMatrix(key.Distinct().ToArray(), characterPositionsInMatrix, positionCharacterInMatrix);
 
            if (mode == Mode.Encrypt)
            {
                message = RepairWord(message);
            }
 
            string result = "";
 
            for (int i = 0; i < message.Length; i += 2)
            {
                string substring_of_2 = message.Substring(i, 2);//get characters from text by pairs
                //get Row & Column of each character
                string rc1 = characterPositionsInMatrix[substring_of_2[0]];
                string rc2 = characterPositionsInMatrix[substring_of_2[1]];
 
                if (rc1[0] == rc2[0])//Same Row, different Column
                {
                    int newC1 = 0, newC2 = 0;
 
                    switch (mode)
                    {
                        case Mode.Encrypt://Increment Columns
                            newC1 = (int.Parse(rc1[1].ToString()) + 1) % 6;
                            newC2 = (int.Parse(rc2[1].ToString()) + 1) % 6;
                            break;
                        case Mode.Decrypt://Decrement Columns
                            newC1 = (int.Parse(rc1[1].ToString()) - 1) % 6;
                            newC2 = (int.Parse(rc2[1].ToString()) - 1) % 6;
                            break;
                    }
 
                    newC1 = RepairNegative(newC1);
                    newC2 = RepairNegative(newC2);
 
                    result += positionCharacterInMatrix[rc1[0].ToString() + newC1.ToString()];
                    result += positionCharacterInMatrix[rc2[0].ToString() + newC2.ToString()];
                }
 
                else if (rc1[1] == rc2[1])//Same Column, different Row
                {
                    int newR1 = 0, newR2 = 0;
 
                    switch (mode)
                    {
                        case Mode.Encrypt://Increment Rows
                            newR1 = (int.Parse(rc1[0].ToString()) + 1) % 5;
                            newR2 = (int.Parse(rc2[0].ToString()) + 1) % 5;
                            break;
                        case Mode.Decrypt://Decrement Rows
                            newR1 = (int.Parse(rc1[0].ToString()) - 1) % 5;
                            newR2 = (int.Parse(rc2[0].ToString()) - 1) % 5;
                            break;
                    }
                    newR1 = RepairNegative(newR1);
                    newR2 = RepairNegative(newR2);
 
                    result += positionCharacterInMatrix[newR1.ToString() + rc1[1].ToString()];
                    result += positionCharacterInMatrix[newR2.ToString() + rc2[1].ToString()];
                }
 
                else//different Row & Column
                {
                    //1st character:row of 1st + col of 2nd
                    //2nd character:row of 2nd + col of 1st
                    result += positionCharacterInMatrix[rc1[0].ToString() + rc2[1].ToString()];
                    result += positionCharacterInMatrix[rc2[0].ToString() + rc1[1].ToString()];
                }
            }
 
            return result;
        }
 
        private string RepairWord(string message)
        {
            string trimmed = message.Replace(" ", "");
            string result = "";
 
            for (int i = 0; i < trimmed.Length; i++)
            {
                result += trimmed[i];
 
                if (i < trimmed.Length - 1 && message[i] == message[i + 1])
                //check if two consecutive letters are the same
                {
                    result += 'х';
                }
            }
 
            if (result.Length % 2 != 0)//check if length is even
            {
                result += 'х';
            }
 
            return result;
        }
 
        private void FillMatrix(IList<char> key, Dictionary<char, string>
          characterPositionsInMatrix, Dictionary<string, char> positionCharacterInMatrix)
        {
            char[,] matrix = new char[5, 6];
            int keyPosition = 0, charPosition = 0;
            List<char> alphabetPF = alphabet.Keys.ToList();
            alphabetPF.Remove('j');
 
            for (int i = 0; i < 5; i++)
            {
                for (int j = 0; j < 6; j++)
                {
                    if (charPosition < key.Count)
                    {
                        matrix[i, j] = key[charPosition];//fill matrix with key
                        alphabetPF.Remove(key[charPosition]);
                        charPosition++;
                    }
 
                    else//key finished...fill with rest of alphabet
                    {
                        matrix[i, j] = alphabetPF[keyPosition];
                        keyPosition++;
                    }
 
                    string position = i.ToString() + j.ToString();
                    //store character positions in dictionary to avoid searching everytime
                    characterPositionsInMatrix.Add(matrix[i, j], position);
                    positionCharacterInMatrix.Add(position, matrix[i, j]);
                }
            }
        }
 
        private int RepairNegative(int number)
        {
            if (number < 0)
            {
                number += 6;
            }
 
            return number;
        }
 
        #endregion
    }
}
между повторяющимися буквами ставится Х или если какой то букве не хватает пары приписывается тоже Х
1
813 / 421 / 169
Регистрация: 08.02.2013
Сообщений: 711
10.10.2014, 11:58 5
Лучший ответ Сообщение было отмечено temasey как решение

Решение

temasey, даже не представляю как этот алгоритм работает =) Могу исправить, но это ближе к ночи.

Добавлено через 15 часов 42 минуты
temasey, код получился довольно большим. Комментарии все портят как всегда. Разделил само шифрование Плейфером и настройки алфавита, чтобы можно было делать русский, английский итд, разные размеры матриц. Отдельно вынес формирование биграмм, чтобы можно было их напечатать.

как я понял, немного не так сделал преобразование, а именно: на вики символы строки, которые не принадлежат алфавиту, а также 'Х' - выкидываются, у меня - заменяются символом 'X', например, пробелы, знаки препинания итд.. Отсюда возникает беда если биграмма начинается с 'X', а строка закончилась или остались одни 'Х' (последний символ у меня пропускается в таких случаях).

Также реализация раздута неиспользованием linq, кучей проверок на валидность данных и единственным проходом вдоль шифруемой/дешифруемой строки
абстрактный класс алфавита
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
public abstract class PlayFairSettings
{
    protected HashSet<char> HsAlphabet { get; private set; }
    protected Dictionary<char, char> Replaces { get; private set; }
 
    protected abstract char[] AlphabetChars { get; }
 
    /// <summary>Число столбцов в матрице</summary>
    public abstract int Columns { get; }
 
    /// <summary>Число строк в матрице</summary>
    public abstract int Rows { get; }
 
    /// <summary>Символ-заменитель</summary>
    public abstract char Replacer { get; }
 
    /// <summary>Алфавит</summary>
    public IEnumerable<char> Alphabet
    {
        get
        {
            char[] chars = AlphabetChars;
            foreach (var c in chars)
                yield return c;
        }
    }
 
    public PlayFairSettings()
    {
        HsAlphabet = new HashSet<char>();
        Replaces = new Dictionary<char, char>();
 
        // Переносим символы алфавита в хэштаблицу, чтобы 
        // убрать повторяющиеся значения и быстро определять
        // принадлежит символ алфавиту или нет
        foreach (var c in AlphabetChars)
            HsAlphabet.Add(c);
    }
 
    /// <summary>Возвращает символ после всех преобразований</summary>
    /// <remarks>Если символ не принадлежит алфавиту, будет поставлен Replacer.</remarks>
    public char GetChar(char Char)
    {
        Char = System.Char.ToLower(Char);
        Char = Replaces.ContainsKey(Char) ? Replaces[Char] : Char;
        return HsAlphabet.Contains(Char) ? Char : Replacer;
    }
}

Пример настройки с русским алфавитом
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class PlayFairRu56 : PlayFairSettings
{
    public PlayFairRu56()
        : base()
    {
        Replaces.Add('ё', 'е');
        Replaces.Add('й', 'и');
        Replaces.Add('ъ', 'ь');
    }
 
    protected override char[] AlphabetChars { get { return "абвгдежзиклмнопрстуфхцчшщьыэюя".ToCharArray(); } }
    public override char Replacer { get { return 'х'; } }
    public override int Columns { get { return 5; } }
    public override int Rows { get { return 6; } }
}

Собственно Плейфер
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
public sealed class PlayFair
{
    struct TablePosition
    {
        public int Row;
        public int Column;
 
        public TablePosition(int Row, int Column)
        {
            this.Row = Row;
            this.Column = Column;
        }
    }
 
    char[,] Matrix;
    Dictionary<char, TablePosition> Positions; // Позиции символов в матрице
 
    public PlayFairSettings Settings { get; private set; }
    public string Key { get; private set; }
 
    public PlayFair(PlayFairSettings Settings, string Key)
    {
        this.Settings = Settings;
        this.Key = Key;
 
        // Формирование матрицы
        Positions = new Dictionary<char, TablePosition>();
        var items = MatrixItems().GetEnumerator();
        Matrix = new char[Settings.Rows, Settings.Columns];
        for (int r = 0; r < Settings.Rows; r++)
        {
            for (int c = 0; c < Settings.Columns; c++)
            {
                if (items.MoveNext())
                {
                    Matrix[r, c] = items.Current;
                    Positions.Add(items.Current, new TablePosition(r, c));
                }
                else throw new ArgumentException("Алфавит слишком маленький");
            }
        }
    }
 
    /// <summary> Перечисление элементов матрицы </summary>
    IEnumerable<char> MatrixItems()
    {
        HashSet<char> used = new HashSet<char>();
 
        // Сначала пишем символы ключа
        foreach (char c in Key)
        {
            char rc = Settings.GetChar(c);
            if (!used.Contains(rc))
            {
                used.Add(rc);
                yield return rc;
            }
        }
 
        // Теперь оставшиеся символы алфавита
        foreach (char c in Settings.Alphabet)
        {
            if (!used.Contains(c))
            {
                used.Add(c);
                yield return c;
            }
        }
    }
 
    /// <summary>
    ///     Разбиаение текста на символы по биграммам.
    ///     Replacer выкидывается
    /// </summary>
    public IEnumerable<char> Bigrams(string Text)
    {
        char prev = '\0';  // Храним перывй символ биграммы
        bool even = false; // если второй символ биграммы
        foreach (char c in Text)
        {
            // Преобразуем символ из текста
            // он может стать Replacer'ом, если, например, это пробел
            char rc = Settings.GetChar(c);
 
            if (!even) // Если это первый символ биграммы
            {
                // запоминаем и ищем второй
                prev = rc;
                even = true;
            }
            else
            {
                // Это второй символ биграммы
                if (prev == rc) // и он такойже как и первый
                {
                    if (prev != Settings.Replacer) // а первый не Replacer
                    {
                        // то вернем биграмму с Replacer в конце
                        yield return prev;
                        yield return Settings.Replacer;
 
                        // и будем считать, что уже нашли первый символ в следующей биграмме
                        prev = rc;
                    }
                }
                else
                {
                    // Ну, а если они разные, то вернем оба и будем искать дальше
                    yield return prev;
                    yield return rc;
                    even = false;
                }
 
            }
        }
 
        // Если мы ищем второй символ, а строка закончилась, 
        // при этом первый символ не Replacer
        if (even && prev != Settings.Replacer)
        {
            yield return prev;
            yield return Settings.Replacer;
        }
    }
 
    /// <summary>
    /// Шифр Плейфера
    /// </summary>
    /// <param name="Text">Исходный текст</param>
    /// <param name="ModeCrypt">True если нужно зашифровать. False - расшифровать</param>
    public string Crypt(string Text, bool ModeCrypt = true)
    {
        int shift = ModeCrypt ? 1 : -1;
        StringBuilder sb = new StringBuilder();
        // Разбиваем на биграммы
        var chars = Bigrams(Text).GetEnumerator();
        while (chars.MoveNext())
        {
            // Получаем координаты символов биграммы в таблице
            // При расшифровке, если шифротекст неверен 
            // т.е. имеет нечетную длину или неизвестные алфавиту символы
            // вылетит исключение (поэтому лучше раздить на два метода: шифровки и дешифровки
            // и перебрасывать исключение). Для шифровки такого не будет
            var p1 = Positions[chars.Current];
            chars.MoveNext();
            var p2 = Positions[chars.Current];
 
            // Если они на одной строке - переводим вправо
            // Если в одной колнке - вниз
            int error = 0;
            if (p1.Column == p2.Column)
            {
                p1.Column = Mod(p1.Column + shift, Settings.Columns);
                p2.Column = Mod(p2.Column + shift, Settings.Columns);
                error++;
            }
            else if (p1.Row == p2.Row)
            {
                p1.Row = Mod(p1.Row + shift, Settings.Rows);
                p2.Row = Mod(p2.Row + shift, Settings.Rows);
                error++;
            }
 
            if (error == 2)
                throw new ArgumentException("Неверные биграммы");
 
            sb.Append(Matrix[p1.Row, p2.Column]);
            sb.Append(Matrix[p2.Row, p1.Column]);
        }
        return sb.ToString();
    }
 
    private int Mod(int x, int m)
    {
        // остаток от деления для отрицательных чисел
        // для -1 вернет (m-1)
        return (x % m + m) % m;
    }
 
    public override string ToString()
    {
        StringBuilder sb = new StringBuilder();
        sb.Append("Ключ: ");
        sb.AppendLine(Key);
        for (int r = 0; r < Settings.Rows; r++)
        {
            for (int c = 0; c < Settings.Columns; c++)
            {
                sb.Append(Matrix[r, c]);
                sb.Append(' ');
            }
            sb.AppendLine();
        }
        return sb.ToString();
    }
}
В последнем три больших метода - формирование матрицы (в конструкторе), разбиение на биграммы и шифр.
2
813 / 421 / 169
Регистрация: 08.02.2013
Сообщений: 711
10.10.2014, 11:59 6
Пример работы
Шифр Плейфера - найти ошибку в коде

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
class Program
{
    static void Main(string[] args)
    {
        try
        {
            PlayFairSettings ps = new PlayFairRu56();
            PlayFair pf = new PlayFair(ps, "Шифр Плейфера");
            Console.WriteLine(pf);
 
            string Text = "Текст который нужно зашифровать шифром Плейферах";
            Console.WriteLine("Исходный текст\r\n" + Text);
 
            int i = 0;
            foreach (char c in pf.Bigrams(Text))
            {
                Console.Write(c); 
 
                i++;
                if (i % 2 == 0) Console.Write(' ');
                if (i % 10 == 0) Console.WriteLine();
            }
 
            Text = pf.Crypt(Text, true);
            Console.WriteLine("\r\nЗашифрованный текст\r\n" + Text);
 
            Text = pf.Crypt(Text, false);
            Console.WriteLine("\r\nРасшифрованный текст\r\n" + Text);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
        Console.ReadLine();
    }
}
Проект в аттаче, в настройках .Net 4.5, студия 2013
Вложения
Тип файла: zip Playfair.zip (10.9 Кб, 367 просмотров)
1
-22 / 4 / 2
Регистрация: 17.09.2021
Сообщений: 186
22.10.2022, 11:07 7
rRczZZ, Как поменять таблицу не на 5*6, а 6*5
0
22.10.2022, 11:07
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
22.10.2022, 11:07
Помогаю со студенческими работами здесь

Шифр Плейфера
Напишите, пожалуйста, программу, которая шифрует текст по методу Плейфера. Заранее огромное спасибо!

Шифр Плейфера
Здравствуйте, для начала расскажу что за шифр такой: Для начала берется матрица и в первую очередь...

Шифр Плейфера
Доброго времени суток. Проблема в том, что я почти доделала шифр Плейфера. Но сама замена букв...

Шифр Плейфера
https://www.youtube.com/watch?v=mvGgpHMpWzc Здравствуйте помогите мне пожалуйста написать Шифр...

Укажите на ошибку в коде и алгоритме (Шифр Цезаря)
#include &lt;iostream&gt; using namespace std; //Функция подсчета символов int count_symbols() {...

Биграммный шифр Плейфера
Кто может реализовать данный шифр в Haskell.помогите чем можете плиз


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

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2023, CyberForum.ru