1 / 1 / 0
Регистрация: 24.04.2013
Сообщений: 4
1

Шифр Хилла, дешифрование

24.04.2013, 14:58. Показов 14629. Ответов 7
Метки нет (Все метки)

Помогите пожалуйста с шифром Хилла. Использую алфавит из 29 символов. Шифрует верно, я проверяла, а вот дешифрует... Вот код того, что я сделала:
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
        const int m = 29;
        char[] alf = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '!', '.', ' ' };
 
        private void button1_Click(object sender, EventArgs e)
        {
            Form2 it = new Form2();
            it.ShowDialog();
        }
 
        //зашифрование
        private void button2_Click(object sender, EventArgs e)
        {
            string text = textBox1.Text;
            int x = text.Length;
            int y = 0; //количество строк, Data.n - количество столбцов
            if (x % Data.n != 0)
                y = x / Data.n + 1;
            else y = x / Data.n;
            int xy = y*Data.n - x; //сколько символов нужно добавить
            if (xy != 0)
                for (int i = 0; i < xy; i++)
                    text += 'e';
            int[] mass = new int[text.Length];
            //преобразование о.т. в массив идентификаторов
            for (int i = 0; i < text.Length; i++)
                for (int j = 0; j < m; j++)
                    if (text[i] == alf[j])
                    {
                        mass[i] = j;
                        break;
                    }
            //преобразование массива идентификаторов в матрицу идентификаторов
            int[,] mid = new int[Data.n,y];
            int p = 0;
            for (int i = 0; i < Data.n; i++)
                for (int j = 0; j < y; j++)
                {
                    mid[i, j] = mass[p];
                    p++;
                }
            //перемножение матриц
            int[,] r = new int[Data.n, y];
            for (int i = 0; i < Data.n; i++)
            {
                for (int j = 0; j < y; j++)
                {
                    for (int k = 0; k < mid.GetLength(0); k++)
                    {
                        r[i, j] += Data.km[i, k] * mid[k, j];
                    }
                }
            }
            for (int i = 0; i < Data.n; i++)
                for (int j = 0; j < y; j++)
                    r[i, j] = Math.Abs(r[i,j]%m);
            //преобразование в строку символов
            string rez = "";
            for (int i = 0; i < Data.n; i++)
                for (int j = 0; j < y; j++)
                    for (int o = 0; o < m; o++)
                        if (r[i,j] == o)
                        {
                            rez += alf[o];
                            break;
                        }
            textBox2.Text = rez;
        }
 
        //расшифрование
        private void button3_Click(object sender, EventArgs e)
        {
            string text = textBox1.Text;
            int x = text.Length;
            int y = 0; //количество строк, Data.n - количество столбцов
            y = x / Data.n;
            int[] mass = new int[text.Length];
            //преобразование о.т. в массив идентификаторов
            for (int i = 0; i < text.Length; i++)
                for (int j = 0; j < m; j++)
                    if (text[i] == alf[j])
                    {
                        mass[i] = j;
                        break;
                    }
            //преобразование массива идентификаторов в матрицу идентификаторов
            int[,] mid = new int[Data.n, y];
            int p = 0;
            for (int i = 0; i < Data.n; i++)
                for (int j = 0; j < y; j++)
                {
                    mid[i, j] = mass[p];
                    p++;
                }
            //нахождение обратной ключевой матрицы по модулю 29
            int[,] a = new int[Data.n, Data.n];
            for (int i = 0; i < Data.n; i++)
                for (int j = 0; j < Data.n; j++)
                    a[i, j] = Data.km[i, j];
            int[,] bb = new int[Data.n, Data.n];
            int[] c = new int[Data.n];
            int[] cb = new int[Data.n];
            for (int i = 0; i < Data.n; i++)
            {
                c[i] = 0;
                for (int j = 0; j < Data.n; j++)
                {
                    if (i != j) bb[i, j] = 0;
                    else bb[i, j] = 1;
                }
            }
            for (int i = 0; i < Data.n; i++)
            {
                double r = Convert.ToDouble(a[i, i]);
                r = (Math.Pow(r, 27)) % m;//находим обратный элемент к элементу a[i,i]
                for (int j = 0; j < Data.n; j++)
                {
                    a[i, j] *= (int)r;//умножаем iю строку на обратный к a[i,i] элемент
                    a[i, j] = (Math.Abs(a[i, j]) % m);
                    bb[i, j] *= (int)r;
                    bb[i,j] = (Math.Abs(bb[i,j])%m);
                }
                for (int u=0; u<Data.n; u++)
                    for (int j=0; j<Data.n; j++)
                        if (u != i)
                        {
                            a[u, j] -= Math.Abs((a[i,j]*a[u,u])%m);//отнимаем от строки u!=i iю строку
                            if (a[u, j] < 0) a[u, j] += m;
                            bb[u, j] -= Math.Abs((cb[j]*a[u,u])%m);
                            if (bb[u, j] < 0) bb[u, j] += m;
                        }
            }
            //перемножение матриц
            int[,] ro = new int[Data.n, y];
            for (int i = 0; i < Data.n; i++)
                for (int j = 0; j < y; j++)
                {
                    for (int ko = 0; ko < Data.n; ko++)
                    {
                        ro[i, j] += bb[i, ko] * mid[ko, j];
                    }
                }
            for (int i = 0; i < Data.n; i++)
                for (int j = 0; j < y; j++)
                    ro[i, j] = (Math.Abs(ro[i, j]) % m);
            //преобразование в строку символов
            string rez = "";
            for (int i = 0; i < Data.n; i++)
                for (int j = 0; j < y; j++)
                    for (int o = 0; o < m; o++)
                        if (ro[i, j] == o)
                        {
                            rez += alf[o];
                            break;
                        }
            textBox2.Text = rez;
        }
Думаю, ввод ключевой матрицы вам не требуется (он выполняется в Form2), но на всякий случай вот:
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
        const int m = 29;
 
        private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (!Char.IsDigit(e.KeyChar) && e.KeyChar != Convert.ToChar(8))
                e.Handled = true;
        }
 
        private void textBox3_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (!Char.IsDigit(e.KeyChar) && e.KeyChar != Convert.ToChar(8) && e.KeyChar != Convert.ToChar(32))
                e.Handled = true;
        }
 
        private void button1_Click(object sender, EventArgs e)
        {
            Data.n = int.Parse(textBox1.Text);
            Data.km = new int[Data.n, Data.n];
            string[] mass = textBox3.Text.Replace("\r\n", " ").Split(' ');
            int p = 0;
            for (int i = 0; i < Data.n; i++)
                for (int j = 0; j < Data.n; j++)
                {
                    Data.km[i,j] = Convert.ToInt32(mass[p]);
                    p++;
                }
            //проверить ключевую матрицу на обратимость
            int[,] a = new int[Data.n, Data.n];
            double k;
            for (int i = 0; i < Data.n; i++)
                for (int j = 0; j < Data.n; j++)
                    a[i, j] = Data.km[i, j];
            //приведение матрицы к диагональному виду
            for (int i = 1; i < Data.n; i++)
            {
                double x = Convert.ToDouble(a[i-1,i-1]);
                k=(a[i-1,i-1]*a[i,i-1]*Math.Pow(x, 27))%m;
                int kint = Convert.ToInt32(k);
                for (int j = 0; j < Data.n; j++)
                {
                    a[i, j] -= kint;
                    if (a[i, j] < 0)
                        a[i, j] += m;
                }
            }
            Data.det = 0;
            for (int i=0; i<Data.n; i++)
                Data.det += a[i,i];
            Data.det = Data.det % m;
            if (Data.det == 0)
                MessageBox.Show("Детерминант равен нулю. Введите другую матрицу!", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
            else
                this.Close();
        }
__________________
Помощь в написании контрольных, курсовых и дипломных работ здесь
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
24.04.2013, 14:58
Ответы с готовыми решениями:

Шифр Хилла
Для тех кто не знает, его суть - есть слово и ключ из букв, допустим слово &quot;студент&quot; а ключ...

Аффинный шифр (шифрование и дешифрование)
Ребята, помогите мне в написании кода программы шифрования и дешифрования аффинного шифра, прошу. Я...

Шифр Хилла
Доброго времени суток, помогите, пожалуйста 1. Найти матрицу K, такую, чтобы у нее была...

Шифр Хилла
Господа, пишу курсовую, тема шифр Хилла. Все компилируется, запускается, но при выводе...

7
7 / 29 / 7
Регистрация: 04.04.2013
Сообщений: 282
24.04.2013, 18:44 2
C#
1
2
3
for (int i = 0; i < Data.n; i++)
* * * * * * * * for (int j = 0; j < y; j++)
* * * * * * * * * * r[i, j] = Math.Abs(r[i,j]%m);
Что за извращенство?

пишите нормально...
C#
1
2
3
for (int i=0; j=0; i<data.n, j<y; i++,j++)
{
}
Переделаете - выложите заного код... а то смотреть страшно на тройные циклы не в тему....

Добавлено через 8 минут
C#
1
i=0; j=0
опечатался - там между ними запятая должна быть
0
1 / 1 / 0
Регистрация: 24.04.2013
Сообщений: 4
24.04.2013, 19:16  [ТС] 3
Какие мы нежные Это ещё спорный вопрос, что читабельнее) Ну держите:
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
        const int m = 29;
        char[] alf = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '!', '.', ' ' };
 
        private void button1_Click(object sender, EventArgs e)
        {
            Form2 it = new Form2();
            it.ShowDialog();
        }
 
        //зашифрование
        private void button2_Click(object sender, EventArgs e)
        {
            string text = textBox1.Text;
            int x = text.Length;
            int y = 0; //количество строк, Data.n - количество столбцов
            if (x % Data.n != 0)
                y = x / Data.n + 1;
            else y = x / Data.n;
            int xy = y*Data.n - x; //сколько символов нужно добавить
            if (xy != 0)
                for (int i = 0; i < xy; i++)
                    text += 'e';
            int[] mass = new int[text.Length];
            //преобразование о.т. в массив идентификаторов
            for (int i = 0, j = 0; i < text.Length, j < m; i++, j++)
                if (text[i] == alf[j])
                {
                    mass[i] = j;
                    break;
                }
            //преобразование массива идентификаторов в матрицу идентификаторов
            int[,] mid = new int[Data.n,y];
            int p = 0;
            for (int i = 0, j = 0; i < Data.n, j < y; i++, j++)
            {
                mid[i, j] = mass[p];
                p++;
            }
            //перемножение матриц
            int[,] r = new int[Data.n, y];
            for (int i = 0, j = 0; i < Data.n, j < y; i++, j++)
                for (int k = 0; k < mid.GetLength(0); k++)
                {
                    r[i, j] += Data.km[i, k] * mid[k, j];
                }
            for (int i = 0, j = 0; i < Data.n, j < y; i++, j++)
                r[i, j] = Math.Abs(r[i,j]%m);
            //преобразование в строку символов
            string rez = "";
            for (int i = 0, j = 0; i < Data.n, j < y; i++, j++)
                for (int o = 0; o < m; o++)
                    if (r[i,j] == o)
                    {
                        rez += alf[o];
                        break;
                    }
            textBox2.Text = rez;
        }
 
        //расшифрование
        private void button3_Click(object sender, EventArgs e)
        {
            string text = textBox1.Text;
            int x = text.Length;
            int y = 0; //количество строк, Data.n - количество столбцов
            y = x / Data.n;
            int[] mass = new int[text.Length];
            //преобразование о.т. в массив идентификаторов
            for (int i = 0, j = 0; i < text.Length, j < m; i++, j++)
                if (text[i] == alf[j])
                {
                    mass[i] = j;
                    break;
                }
            //преобразование массива идентификаторов в матрицу идентификаторов
            int[,] mid = new int[Data.n, y];
            int p = 0;
            for (int i = 0, j = 0; i < Data.n, j < y; i++, j++)
            {
                mid[i, j] = mass[p];
                p++;
            }
            //нахождение обратной ключевой матрицы по модулю 29
            int[,] a = new int[Data.n, Data.n];
            for (int i = 0, j = 0; i < Data.n, j < Data.n; i++, j++)
                a[i, j] = Data.km[i, j];
            int[,] bb = new int[Data.n, Data.n];
            int[] c = new int[Data.n];
            int[] cb = new int[Data.n];
            for (int i = 0, j = 0; i < Data.n, j < Data.n; i++, j++)
            {
                if (i != j) bb[i, j] = 0;
                else bb[i, j] = 1;
            }
            for (int i = 0; i < Data.n; i++)
            {
                double r = Convert.ToDouble(a[i, i]);
                r = (Math.Pow(r, 27)) % m;//находим обратный элемент к элементу a[i,i]
                for (int j = 0; j < Data.n; j++)
                {
                    a[i, j] *= (int)r;//умножаем iю строку на обратный к a[i,i] элемент
                    a[i, j] = (Math.Abs(a[i, j]) % m);
                    bb[i, j] *= (int)r;
                    bb[i,j] = (Math.Abs(bb[i,j])%m);
                }
                for (int u = 0, j = 0; u < Data.n, j < Data.n; u++, j++)
                    if (u != i)
                    {
                        a[u, j] -= Math.Abs((a[i,j]*a[u,u])%m);//отнимаем от строки u!=i iю строку
                        if (a[u, j] < 0) a[u, j] += m;
                        bb[u, j] -= Math.Abs((cb[j]*a[u,u])%m);
                        if (bb[u, j] < 0) bb[u, j] += m;
                    }
            }
            //перемножение матриц
            int[,] ro = new int[Data.n, y];
            for (int i = 0, j = 0; i < Data.n, j < y; i++, j++)
            {
                for (int ko = 0; ko < Data.n; ko++)
                {
                    ro[i, j] += bb[i, ko] * mid[ko, j];
                }
            }
            for (int i = 0, j = 0; i < Data.n, j < y; i++, j++)
                ro[i, j] = (Math.Abs(ro[i, j]) % m);
            //преобразование в строку символов
            string rez = "";
            for (int i = 0, j = 0; i < Data.n, j < y; i++, j++)
                for (int o = 0; o < m; o++)
                    if (ro[i, j] == o)
                    {
                        rez += alf[o];
                        break;
                    }
            textBox2.Text = rez;
        }
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
        const int m = 29;
 
        private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (!Char.IsDigit(e.KeyChar) && e.KeyChar != Convert.ToChar(8))
                e.Handled = true;
        }
 
        private void textBox3_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (!Char.IsDigit(e.KeyChar) && e.KeyChar != Convert.ToChar(8) && e.KeyChar != Convert.ToChar(32))
                e.Handled = true;
        }
 
        private void button1_Click(object sender, EventArgs e)
        {
            Data.n = int.Parse(textBox1.Text);
            Data.km = new int[Data.n, Data.n];
            string[] mass = textBox3.Text.Replace("\r\n", " ").Split(' ');
            int p = 0;
            for (int i = 0, j = 0; i < Data.n, j < Data.n; i++, j++)
            {
                Data.km[i,j] = Convert.ToInt32(mass[p]);
                p++;
            }
            //проверить ключевую матрицу на обратимость
            int[,] a = new int[Data.n, Data.n];
            double k;
            for (int i = 0, j = 0; i < Data.n, j < Data.n; i++, j++)
                a[i, j] = Data.km[i, j];
            //приведение матрицы к диагональному виду
            for (int i = 1; i < Data.n; i++)
            {
                double x = Convert.ToDouble(a[i-1,i-1]);
                k=(a[i-1,i-1]*a[i,i-1]*Math.Pow(x, 27))%m;
                int kint = Convert.ToInt32(k);
                for (int j = 0; j < Data.n; j++)
                {
                    a[i, j] -= kint;
                    if (a[i, j] < 0)
                        a[i, j] += m;
                }
            }
            Data.det = 0;
            for (int i=0; i<Data.n; i++)
                Data.det += a[i,i];
            Data.det = Data.det % m;
            if (Data.det == 0)
                MessageBox.Show("Детерминант равен нулю. Введите другую матрицу!", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
            else
                this.Close();
        }
Я думаю, что ошибка в блоке нахождения обратной матрицы, потому что в остальном я в общем-то почти уверена...
1
1 / 1 / 0
Регистрация: 24.04.2013
Сообщений: 4
05.05.2013, 15:59  [ТС] 4
Цитата Сообщение от BeBrave Посмотреть сообщение
C#
1
2
3
for (int i = 0; i < Data.n; i++)
* * * * * * * * for (int j = 0; j < y; j++)
* * * * * * * * * * r[i, j] = Math.Abs(r[i,j]%m);
Что за извращенство?

пишите нормально...
C#
1
2
3
for (int i=0; j=0; i<data.n, j<y; i++,j++)
{
}
Переделаете - выложите заного код... а то смотреть страшно на тройные циклы не в тему....

Добавлено через 8 минут
C#
1
i=0; j=0
опечатался - там между ними запятая должна быть
Мда... Вот зря я тогда Вас послушала и переделала... Да ещё и в блокноте переделывала, поленилась открывать студию... Вас не смущает, что таких конструкций, как Вы описали, в C# нет?
А я ещё думаю, чо эт я такие штуки впервые вижу...
И, кстати, слово заново пишется через в.
0
MЫW
124 / 109 / 9
Регистрация: 15.02.2013
Сообщений: 538
05.05.2013, 17:47 5
C#
1
for (int i = 0, j = 0; i < 2 && j<2; i++, j++)
Студия сожрала.
0
1 / 1 / 0
Регистрация: 24.04.2013
Сообщений: 4
05.05.2013, 19:59  [ТС] 6
Цитата Сообщение от phantom96 Посмотреть сообщение
C#
1
for (int i = 0, j = 0; i < 2 && j<2; i++, j++)
Студия сожрала.
Правильно, Вы же вставили && в условие окончания цикла. А это уже совсем другое. К тому же эта конструкция подходит только для i=j. Если вы сделаете вот так
C#
1
for (int i = 0, j = 0; i < 8 && j < 4; i++, j++)
то Ваш цикл по i пройдёт не до конца. Не знаю уж, как будет в C++ работать предложенная BeBrave конструкция. Наверное, как положено.
И вообще лучше бы по теме подсказали Я тут не спор по поводу синтаксических конструкций устраивала. Таких тем полно в C# для начинающих.
0
MЫW
124 / 109 / 9
Регистрация: 15.02.2013
Сообщений: 538
05.05.2013, 20:38 7
Я если честно незнаю как этот шифр открыть. Посмотрел вики, оценил что не моё. Может вам стоит попробывать просто статичный ключ, точнее сразу ввести матрицу шифрования и обратную для расшифровки и проверить только это.

Добавлено через 6 минут
0
0 / 0 / 2
Регистрация: 14.06.2015
Сообщений: 60
22.11.2016, 14:15 8
выложите пож-та окончательный код , лучше с исходниками и файлом .sln и рабочим .exe

Спасибо
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
22.11.2016, 14:15

Шифр Хилла в делфи
Есть уже написанная программа &quot; Шифратор&quot; реализующая симметричный блочный алгоритм шифрования...

Лабораторная работа: Шифр Хилла
Составить программу с графическим интерфейсом, которая реализует Шифр Хилла

Шифр хилла - закомпилировать как?
Windows forms С++ помогите закомпилировать Следуя описанному выше алгоритму представлен код...

Аффинное матричное преобразование (Шифр Хилла),
Здравствуйте, господа форумчане! Столкнулся с такой задачи и прошу помощи. Если у кого есть...


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.