Чат с шифрованием по Плейферу. Как передать ключ для формирования матрицы? - C#
Формулировка задачи:
Добрый вечер!
Вот код чата
сообщения между собеседниками должны передаваться зашифрованными
причем ключ у каждого собеседника свой (ник = ключ)
на основании ключа формируется матрица для шифровки по Плейферу
сообщение шифруется и передается другому собеседнику
моя проблема в том, что я не знаю как получить ключ от собеседника чтобы дешифровать его сообщение
вот код:
кто может помогите пожалста моему горю
голова кругом уже
а завтра сдаваться (
Листинг программы
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Data;
- using System.Drawing;
- using System.Linq;
- using System.Text;
- using System.Text.RegularExpressions;
- using System.Windows.Forms;
- using System.Net;
- using System.Net.Sockets;
- using System.Threading;
- using System.IO;
- namespace Chat_APP
- {
- public partial class Form1 : Form
- {
- Socket socket;
- EndPoint epLocal, epRemote;
- // все символы алфавитов английские русские + знаки, вся длина строки = 160
- String ABC = "ABCDEFGHIJKLMNOPQRSTUVWXYZАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯabcdefghijklmnopqrstuvwxyzабвгдеёжзийклмнопрстуфхцчшщъыьэюя !@\"#№$;%^:&?*()-_+={}[]\\/<>.,~`0123456789";
- // матрица для шифровки расшифровки
- // формируется динамически на основании переданного Ключа и строки ABC
- // строку из 160 символов будем разбивать на двумерный массив размером 10x16
- char[,] Matrix = new char[10, 16];
- static public string Ключ;
- //
- public Form1()
- {
- InitializeComponent();
- socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
- socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
- // IP = 127.0.0.1 для локальной сети
- textLocalIP.Text = "127.0.0.1"; //ПолучитьЛокальныйАдресIP();
- textFriendIP.Text = "127.0.0.1"; //ПолучитьЛокальныйАдресIP();
- //// если связь НЕ по локальной сети то нужно получать IP
- //textLocalIP.Text = ПолучитьЛокальныйАдресIP();
- //textFriendIP.Text = ПолучитьЛокальныйАдресIP();
- // Номер порта = 15000 можно любой другой
- textLocalPort.Text = "15000"; // мой порт - локальный
- textFriendPort.Text = "15001"; // порт собеседника - удаленный
- // во 2-ом окне нужно ввести порты наоборот:
- // мой порт = "15001"
- // порт собеседника = "15000"
- }
- // Подключение к сети
- private void buttonStart_Click(object sender, EventArgs e)
- {
- try
- {
- epLocal = new IPEndPoint(IPAddress.Parse(textLocalIP.Text), Convert.ToInt32(textLocalPort.Text));
- socket.Bind(epLocal);
- epRemote = new IPEndPoint(IPAddress.Parse(textFriendIP.Text), Convert.ToInt32(textFriendPort.Text));
- socket.Connect(epRemote);
- byte[] buffer = new byte[1500];
- socket.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref epRemote, new AsyncCallback(ПолучитьСообщение), buffer);
- buttonStart.Text = "Подключён";
- buttonStart.Enabled = false;
- // разрешаем поле и кнопку отправки сообщений
- textMessage.Enabled = true;
- buttonSend.Enabled = true;
- // переводим фокус на ввод сообщения
- textMessage.Focus();
- }
- catch (Exception ex)
- {
- MessageBox.Show(ex.ToString());
- }
- }
- private void buttonSend_Click(object sender, EventArgs e)
- {
- ОтправитьСообщение();
- }
- private void textMessage_KeyDown(object sender, KeyEventArgs e)
- {
- // если нажата Enter в поле сообщения то отправляем сообщение
- if (e.KeyCode == Keys.Enter)
- {
- ОтправитьСообщение();
- }
- }
- // Отправка сообщения
- private void ОтправитьСообщение()
- {
- try
- {
- Ключ = textBoxNick.Text; // глобальный
- // конвертация текста в байты для передачи
- byte[] byteMsg = new byte[1500];
- ///
- string Key = textBoxNick.Text; // ключ = Ник
- //string SendMessage = textMessage.Text;
- string Сообщение = textMessage.Text;
- string ТекстДляОтправки = Key + "Ё" + textMessage.Text; // отправляемая строка
- //// шифровка текста
- //СоздатьМатрицу(Key);
- string ЗашифрованноеСообщение = ЗашифроватьТекст(Сообщение, Key);
- textBoxEncodedMsg.Text = ЗашифрованноеСообщение;
- string sKey = ПолучитьКлючИзСообщения(ТекстДляОтправки);
- string sMsg = ПолучитьТекстИзСообщения(ТекстДляОтправки);
- textBoxDecodedMsg.Text = РасшифроватьТекст(ЗашифрованноеСообщение, Key);
- string ЗашифрованныйТекстДляОтправки = ЗашифроватьТекст(ТекстДляОтправки, Key);
- // перевод строки в набор битов
- //byteMsg = Encoding.Default.GetBytes(ЗашифрованныйТекстДляОтправки);
- //byteMsg = Encoding.Unicode.GetBytes(Сообщение);
- byteMsg = Encoding.Unicode.GetBytes(ЗашифрованныйТекстДляОтправки);
- socket.Send(byteMsg); // отправка сообщения
- listMessage.Items.Add("Я: " + Сообщение);
- //listMessage.Items.Add(textBoxNick.Text + ": " + textMessage.Text);
- textMessage.Clear();
- }
- catch (Exception ex)
- {
- MessageBox.Show(ex.ToString());
- }
- }
- // получение сообщения
- private void ПолучитьСообщение(IAsyncResult aresut)
- {
- try
- {
- int size = socket.EndReceiveFrom(aresut, ref epRemote);
- if (size > 0)
- {
- byte[] byteПолученныеДанные = new byte[1464];
- byteПолученныеДанные = (byte[])aresut.AsyncState;
- //string ПолученныйТекст = Encoding.Default.GetString(byteПолученныеДанные);
- string ПолученныйТекст = Encoding.Unicode.GetString(byteПолученныеДанные);
- ПолученныйТекст = ПолученныйТекст.TrimEnd();
- // Дешифровка
- string РасшифрованныйТекст = РасшифроватьТекст(ПолученныйТекст, Ключ);
- // выделить ключ и текст сообщения из полученных данных
- string Кеу = ПолучитьКлючИзСообщения(ПолученныйТекст);
- string РасшифрованноеСообщение = ПолучитьТекстИзСообщения(ПолученныйТекст);
- // вывести в список сообщений
- //listMessage.Items.Add("Друг: " + receivedMessage);
- ////listMessage.Items.Add(textBoxNick.Text + ": " + receivedMessage);
- //listMessage.Items.Add(strReceivedMessage);
- listMessage.Items.Add(Кеу + ": " + РасшифрованноеСообщение);
- }
- byte[] buffer = new byte[1500];
- socket.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref epRemote, new AsyncCallback(ПолучитьСообщение), buffer);
- }
- catch (Exception exp)
- {
- MessageBox.Show(exp.ToString());
- }
- }
- // Получить IP адрес компьютера
- private string ПолучитьЛокальныйАдресIP()
- {
- IPHostEntry host;
- host = Dns.GetHostEntry(Dns.GetHostName());
- foreach (IPAddress ip in host.AddressList)
- {
- if (ip.AddressFamily == AddressFamily.InterNetwork)
- return ip.ToString(); // возвращаем сетевой IP
- }
- return "127.0.0.1"; // возвращаем локальный IP
- }
- // Выход
- private void buttonExit_Click(object sender, EventArgs e)
- {
- Close();
- }
- // -----------------------------------------------------------------
- #region Шифрование-Дешифрование
- // Получить ключ из полученной строки
- // Ключ в полученном сообщении отделен символом Ё от текста
- string ПолучитьКлючИзСообщения(string strMsg)
- {
- // разбиваем сообщение на массив строк по символу Ё
- string[] arrMsg = strMsg.Split('Ё');
- string key = arrMsg[0]; // ключ
- string msg = arrMsg[1]; // сообщение
- return key;
- }
- // Получить только текст сообщения из полученной строки без ключа
- // Ключ в полученном сообщении отделен символом Ё от текста
- string ПолучитьТекстИзСообщения(string strMsg)
- {
- // разбиваем сообщение на массив строк по символу Ё
- string[] arrMsg = strMsg.Split('Ё');
- string key = arrMsg[0]; // ключ
- string msg = arrMsg[1]; // сообщение
- return msg;
- }
- // Проверка Шифрования
- private void buttonEncode_Click(object sender, EventArgs e)
- {
- string Key = textBoxNick.Text; // ключ = Ник
- //СоздатьМатрицу(Key);
- if (textBoxDecodedMsg.Text != "")
- {
- string msg = textBoxDecodedMsg.Text.TrimEnd();
- textBoxEncodedMsg.Text = ЗашифроватьТекст(msg, Key);
- }
- }
- // Проверка ДеШифрования
- private void buttonDecode_Click(object sender, EventArgs e)
- {
- string Key = textBoxNick.Text; // ключ = Ник
- //СоздатьМатрицу(Key);
- if (textBoxEncodedMsg.Text != "")
- {
- string msg = textBoxEncodedMsg.Text;
- textBoxDecodedMsg.Text = РасшифроватьТекст(msg, Key);
- }
- }
- // Функция создания матрицы
- void СоздатьМатрицу(string Key)
- {
- String Alphabet = "";
- // добавляем ключ
- for (int i = 0; i < Key.Length; i++)
- {
- if (Alphabet.IndexOf(Key[i]) == -1)
- Alphabet += Key[i];
- }
- // добавляем остальные символы из ABC
- for (int i = 0; i < ABC.Length; i++)
- {
- if (Alphabet.IndexOf(ABC[i]) == -1)
- Alphabet += ABC[i];
- }
- // заполняем массив букв решетки
- int num = 0;
- for (int i = 0; i < 10; i++)
- for (int j = 0; j < 16; j++)
- {
- Matrix[i, j] = Alphabet[num];
- num++;
- }
- }
- // ------------------------
- // Шифрование текста
- string ЗашифроватьТекст(string Text, string Key)
- {
- СоздатьМатрицу(Key);
- if (Text.Length % 2 != 0)
- Text = Text + " ";
- string Результат = "";
- // индексы букв в столбцах
- int ind_x1 = 0;
- int ind_y1 = 0;
- int ind_x2 = 0;
- int ind_y2 = 0;
- int k = 0;
- while (k < Text.Length)
- {
- for (int i = 0; i < 10; i++)
- for (int j = 0; j < 16; j++)
- {
- if (Text[k] == Matrix[i, j])
- {
- ind_x1 = i;
- ind_y1 = j;
- }
- if (Text[k + 1] == Matrix[i, j])
- {
- ind_x2 = i;
- ind_y2 = j;
- }
- }
- // Если буквы находятся в одной строке
- if (ind_x1 == ind_x2)
- {
- if (ind_y1 == 15)
- {
- Результат += Matrix[ind_x1, 0];
- Результат += Matrix[ind_x2, ind_y2 + 1];
- }
- else
- if (ind_y2 == 15)
- {
- Результат += Matrix[ind_x1, ind_y1 + 1];
- Результат += Matrix[ind_x2, 0];
- }
- else
- {
- Результат += Matrix[ind_x1, ind_y1 + 1];
- Результат += Matrix[ind_x2, ind_y2 + 1];
- }
- }
- // Если буквы находятся в одном столбце
- if (ind_y1 == ind_y2)
- {
- if (ind_x1 == 9)
- {
- Результат += Matrix[0, ind_y1];
- Результат += Matrix[ind_x2 + 1, ind_y2];
- }
- else
- if (ind_x2 == 9)
- {
- Результат += Matrix[ind_x1 + 1, ind_y1];
- Результат += Matrix[0, ind_y2];
- }
- else
- {
- Результат += Matrix[ind_x1 + 1, ind_y1];
- Результат += Matrix[ind_x2 + 1, ind_y2];
- }
- }
- // Если буквы находятся в разных строках и разных столбцах
- if ((ind_x1 != ind_x2) && (ind_y1 != ind_y2))
- {
- Результат += Matrix[ind_x1, ind_y2];
- Результат += Matrix[ind_x2, ind_y1];
- }
- k = k + 2;
- }
- return Результат;
- }
- // ---------------------------
- // Дешифрование текста
- string РасшифроватьТекст(string Text, string Key)
- {
- СоздатьМатрицу(Key);
- string Результат = "";
- // индексы букв в столбцах
- int ind_x1 = 0;
- int ind_y1 = 0;
- int ind_x2 = 0;
- int ind_y2 = 0;
- int k = 0;
- while (k < Text.Length)
- {
- for (int i = 0; i < 10; i++)
- for (int j = 0; j < 16; j++)
- {
- if (Text[k] == Matrix[i, j])
- {
- ind_x1 = i;
- ind_y1 = j;
- }
- if (Text[k + 1] == Matrix[i, j])
- {
- ind_x2 = i;
- ind_y2 = j;
- }
- }
- // Если буквы находятся в одной строке
- if (ind_x1 == ind_x2)
- {
- if (ind_y1 == 0)
- {
- Результат += Matrix[ind_x1, 15];
- Результат += Matrix[ind_x2, ind_y2 - 1];
- }
- else
- if (ind_y2 == 0)
- {
- Результат += Matrix[ind_x1, ind_y1 - 1];
- Результат += Matrix[ind_x2, 15];
- }
- else
- {
- Результат += Matrix[ind_x1, ind_y1 - 1];
- Результат += Matrix[ind_x2, ind_y2 - 1];
- }
- }
- // Если буквы находятся в одном столбце
- if (ind_y1 == ind_y2)
- {
- if (ind_x1 == 0)
- {
- Результат += Matrix[9, ind_y1];
- Результат += Matrix[ind_x2 - 1, ind_y2];
- }
- else
- if (ind_x2 == 0)
- {
- Результат += Matrix[ind_x1 - 1, ind_y1];
- Результат += Matrix[9, ind_y2];
- }
- else
- {
- Результат += Matrix[ind_x1 - 1, ind_y1];
- Результат += Matrix[ind_x2 - 1, ind_y2];
- }
- }
- // Если буквы находятся в разных строках и разных столбцах
- if ((ind_x1 != ind_x2) && (ind_y1 != ind_y2))
- {
- Результат += Matrix[ind_x1, ind_y2];
- Результат += Matrix[ind_x2, ind_y1];
- }
- k = k + 2;
- }
- return Результат;
- }
- #endregion //Шифрование-Дешифрование
- }
- }
Решение задачи: «Чат с шифрованием по Плейферу. Как передать ключ для формирования матрицы?»
textual
Листинг программы
- private void ПолучитьСообщение(IAsyncResult aresut)
- {
- string Кеу, РасшифрованноеСообщение;
- try
- {
- int size = socket.EndReceiveFrom(aresut, ref epRemote);
- if (size > 0)
- {
- byte[] byteПолученныеДанные = new byte[1464];
- byteПолученныеДанные = (byte[])aresut.AsyncState;
- string ПолученныйТекст = Encoding.Unicode.GetString(byteПолученныеДанные);
- // выделить ключ и текст сообщения из полученных данных
- Кеу = ПолучитьКлючИзСообщения(ПолученныйТекст);
- string ПолученноеСообщение = ПолучитьТекстИзСообщения(ПолученныйТекст);
- // Дешифровка
- РасшифрованноеСообщение = РасшифроватьТекст(ПолученноеСообщение, Кеу);
- // вывести в список сообщений
- listMessage.Items.Add(Кеу + ": " + РасшифрованноеСообщение); //<- вот здесь выбрасывает исключение см. картинку
- }
- byte[] buffer = new byte[1500];
- socket.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref epRemote, new AsyncCallback(ПолучитьСообщение), buffer);
- }
- catch (Exception exp)
- {
- MessageBox.Show(exp.ToString());
- }
- }
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д