using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Numerics;
namespace RSA
{
public partial class MainForm : Form
{
public long P, Q, D, E, M, N = 0;
string Source, fn = "";
public long[] cipherText;
public struct Key
{
public long index;
public long N;
public Key(long lIndex, long lN)
{
index = lIndex;
N = lN;
}
}
public static long[] Encode(string sMessage, Key oKey)
{
long[] numericMessage = new long[sMessage.Length];
int length = sMessage.Length;
for (int i = 0; i < length; i++)
{
numericMessage[i] = (long)sMessage[i];
}
return Process(numericMessage, oKey);
}
public static string Decode(long[] numericMessage, Key oKey)
{
long[] processedMessage = Process(numericMessage, oKey);
StringBuilder message = new StringBuilder();
int length = processedMessage.Length;
for (int i = 0; i < length; i++)
{
message.Append((char)processedMessage[i]);
}
return message.ToString();
}
public static long ModularExponantiation(long num, Key oKey)
{
long C = 1;
long E = 0;
while (E++ < oKey.index)
{
C = (C * num) % oKey.N;
}
return C;
}
public static long[] Process(long[] src_text, Key oKey)
{
long[] ciphertext = new long[src_text.Length];
int length = src_text.Length;
for (int i = 0; i < length; i++)
{
ciphertext[i] = ModularExponantiation(src_text[i], oKey);
}
return ciphertext;
}
public MainForm()
{
InitializeComponent();
label1.Visible = false;
#region FileDialog Settings
openFileDialog1.DefaultExt = "txt";
openFileDialog1.Filter = "Текстовые документы|*.txt";
openFileDialog1.Title = "Открыть документ";
openFileDialog1.Multiselect = false;
#endregion
}
private void OpenDocument() // Функция открытия документа
{
openFileDialog1.FileName = string.Empty;
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
fn = openFileDialog1.FileName;
Encoding enc = Encoding.GetEncoding(1251);
try
{
// Чтение файла
StreamReader sr = new StreamReader(fn, enc); //Открывает поток для чтения файла
SourceTextBox.Text = sr.ReadToEnd(); // Считываем документ до конца
SourceTextBox.SelectionStart = SourceTextBox.TextLength;
sr.Close(); // Закрываем поток
}
catch (Exception exc) // Отлавливаем ошибку
{
MessageBox.Show("Ошибка чтения файла.\n"
+ exc.ToString(), "Error!",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
}
}
private void button3_Click(object sender, EventArgs e)
{
OpenDocument();
TextBox1Length.Text = Convert.ToString(SourceTextBox.TextLength);
} // Кнопка "Открыть Документ"
// Наибольший общий делитель
private static long gcd(long x, long y)
{
long g;
g = y;
while (x > 0) // Пока не равен 0
{
g = x;
x = y % x;
y = g;
}
return g;
}
// Проверка на взаимопростоту
private static long MutuallySimple(long m)
{
Random rd = new Random(DateTime.Now.Millisecond);
int tmp_d;
long d = 0, check;
bool quit = false;
while (quit == false)
{
tmp_d = rd.Next(2, 100);
d = Convert.ToInt64(tmp_d);
check = gcd(m, d);
if (check == 1) // Если = 1 то простое число
{
quit = true;
}
}
return d;
}
// Расширенный алгоритм Евклида
private static long ExtGCD(long x, long y)
{
long a, b, q, r, u1, u2;
long t;
a = Convert.ToInt64(x);
b = Convert.ToInt64(y);
u1 = 1;
u2 = 0;
while (b != 0)
{
q = a / b;
r = a % b;
a = b; b = r;
t = u2;
u2 = u1 - q * u2;
u1 = t;
}
return u1;
}
private void ApplyPQButton_Click(object sender, EventArgs e)
{
if (PTextBox.Text.Length == 0 && QTextBox.Text.Length == 0 )
{
MessageBox.Show("Введите значение P и Q!");
return;
} else if (PTextBox.Text.Length == 0)
{
MessageBox.Show("Введите значение P!");
return;
}
else if (QTextBox.Text.Length == 0)
{
MessageBox.Show("Введите значение Q!");
return;
}
P = Convert.ToUInt32(PTextBox.Text);
Q = Convert.ToUInt32(QTextBox.Text);
N = P * Q;
M = (P-1) * (Q-1);
D = MutuallySimple(M);
long tmp_E;
tmp_E = ExtGCD(D, M);
if (tmp_E <= 0)
{
while (tmp_E < 0)
{
D = MutuallySimple(M);
tmp_E = ExtGCD(D, M);
}
}
E = Convert.ToInt64(tmp_E);
p_label.Text = Convert.ToString(P);
q_label.Text = Convert.ToString(Q);
e_label.Text = Convert.ToString(E);
d_label.Text = Convert.ToString(D);
n_label.Text = Convert.ToString(N);
m_label.Text = Convert.ToString(M);
}
private void ClearButton_Click(object sender, EventArgs e)
{
p_label.Text = "0";
q_label.Text = "0";
n_label.Text = "0";
m_label.Text = "0";
d_label.Text = "0";
e_label.Text = "0";
}
private void CryptButton_Click(object sender, EventArgs e)
{
if (SourceTextBox.Text.Length == 0)
{
MessageBox.Show("Нет текста для шифрации");
return;
}
ResultTextBox.ResetText();
textBox1.ResetText();
Key publicKey = new Key(E, N);
Source = SourceTextBox.Text;
cipherText = Encode(Source, publicKey);
for (int i = 0; i < cipherText.Length - 1; i++)
{
textBox1.Text += Convert.ToString(Convert.ToChar(cipherText[i]));
ResultTextBox.Text += cipherText[i];
ResultTextBox.Text += " ";
}
TextBox2Length.Text = Convert.ToString(ResultTextBox.TextLength);
}
private void DecryptButton_Click(object sender, EventArgs e)
{
if (ResultTextBox.Text.Length == 0)
{
MessageBox.Show("Нет текста для дешифрации");
return;
}
ResultTextBox.ResetText();
Key privateKey = new Key(D, N);
ResultTextBox.Text = Decode(cipherText, privateKey);
TextBox2Length.Text = Convert.ToString(ResultTextBox.TextLength);
if (SourceTextBox.Text == ResultTextBox.Text)
{
label1.Visible = true;
label1.Text = "Дешифрование успешно!";
label1.ForeColor = Color.Green;
}
else
{
label1.Visible = true;
label1.Text = "Дешифрование неудачно!";
label1.ForeColor = Color.Red;
}
}
private void SourceTextBox_TextChanged(object sender, EventArgs e)
{
TextBox1Length.Text = Convert.ToString(SourceTextBox.TextLength);
}
private void MainForm_Load(object sender, EventArgs e)
{
}
private void label12_Click(object sender, EventArgs e)
{
}
private void n_label_Click(object sender, EventArgs e)
{
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
}
private void d_label_Click(object sender, EventArgs e)
{
}
private void openFileDialog1_FileOk(object sender, CancelEventArgs e)
{
}
private void textBox2_TextChanged(object sender, EventArgs e)
{
}
private void label13_Click(object sender, EventArgs e)
{
}
}
}