C++ (Qt)
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <qmath.h>
#include <QTime>
#include <QRandomGenerator>
#include <QTextCodec>
qint64 make_Key(qint64, qint64);
quint64 make_RSA(quint64, quint64, quint64);
quint64 makePrimeDigit();
bool isPrime(quint64);
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private:
Ui::Widget *ui;
public slots:
void press_pbtn_01();
void press_pbtn_02();
void press_pbtn_03();
void press_pbtn_04();
};
#endif // WIDGET_H
C++ (Qt)
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
// инициализация ГСЧ
qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
QObject::connect(ui->pbtn_01,SIGNAL(clicked()),this,SLOT(press_pbtn_01()));
QObject::connect(ui->pbtn_02,SIGNAL(clicked()),this,SLOT(press_pbtn_02()));
QObject::connect(ui->pbtn_03,SIGNAL(clicked()),this,SLOT(press_pbtn_03()));
QObject::connect(ui->pbtn_04,SIGNAL(clicked()),this,SLOT(press_pbtn_04()));
}
Widget::~Widget()
{
delete ui;
}
// кнопка "получить"
void Widget::press_pbtn_01()
{
quint64 easy1, easy2;
quint64 modul = 0xF000000000000000;
while(modul > 0x7FFFFFFFFFFFFFFF)
{
easy1 = makePrimeDigit();
easy2 = makePrimeDigit();
modul = easy1 * easy2;
}
//easy1 = 4146278621;
//easy2 = 1970034377;
//modul = easy1 * easy2;
ui->lineEdit_03->setText(QString::number(easy1));
ui->lineEdit_04->setText(QString::number(easy2));
// Простое число Мерсенна
// обычно используется в RSA в виде открытой экспоненты для увеличения производительности
quint64 open_kl = 65537;
quint64 m = (easy1 - 1) * (easy2 - 1);
quint64 close_kl = make_Key(open_kl, m);
ui->lineEdit_06->setText(QString::number(modul));
ui->lineEdit_07->setText(QString::number(close_kl));
}
// кнопка шифровать RSA
void Widget::press_pbtn_02()
{
quint64 open_kl, modul, rsa;
quint64 buf;
QString str1, str2;
QStringList lstr;
QStringList lstr2;
QByteArray barr;
bool ok;
QTextCodec *codec = QTextCodec::codecForName("UTF-8");
str1 = ui->textEdit_01->toPlainText();
barr = codec->fromUnicode(str1);
barr.prepend(qrand() % 255 + 1);
int cxb = barr.size();
int cxi = 0;
// простое шифрование байтовой последовательности
for(int i = 1; i < cxb; i++)
{
barr[i] = barr.at(i-1) ^ barr.at(i);
}
// чтение
while(cxb)
{
buf = 0;
for(int i = 0; i < 7; i++)
{
cxb--;
quint8 qw = barr.at(cxi++);
buf |= qw;
if(i == 6 || !cxb) break;
buf <<= 8;
}
str1 = QString::number(buf, 16);
lstr << str1;
//ui->textEdit_01->append(str1);
}
// шифрование
ui->textEdit_02->append("");
lstr2.clear();
open_kl = 65537;
str1 = ui->lineEdit_02->text();
modul = str1.toULongLong();
for(int i = 0; i < lstr.size(); i++)
{
str1 = lstr.at(i);
quint64 x = str1.toULongLong(&ok, 16);
rsa = make_RSA(x, open_kl, modul);
str2 = QString::number(rsa, 16);
if(str2 == "0") continue;
lstr2 << str2;
ui->textEdit_02->append(str2);
}
}
// кнопка дешифровать RSA
void Widget::press_pbtn_03()
{
quint64 modul, rsa;
QString str1, str2;
QStringList lstr;
QStringList lstr2;
QByteArray barr;
bool ok;
QTextCodec *codec = QTextCodec::codecForName("UTF-8");
str1 = ui->textEdit_02->toPlainText();
lstr2 = str1.split(QRegExp("[\n]"),QString::SkipEmptyParts);
str1 = ui->lineEdit_06->text();
modul = str1.toULongLong();
//ui->textEdit_02->append("");
//lstr.clear();
//дешифрование
str1 = ui->lineEdit_07->text();
quint64 close_kl = str1.toULongLong();
for(int i = 0; i < lstr2.size(); i++)
{
str1 = lstr2.at(i);
quint64 x = str1.toULongLong(&ok, 16);
rsa = make_RSA(x, close_kl, modul);
str2 = QString::number(rsa, 16);
if(str2.length() % 2) str2.prepend("0");
lstr << str2;
//ui->textEdit_02->append(str2);
}
// формирование строки
for(int i = 0; i < lstr.size(); i++)
{
str1 = lstr.at(i);
for(int j = 0; j < 14; j+=2)
{
if(str1.length() == 1)
{
str2 = "0";
str2 += str1[j+1];
}
else
{
str2 = str1[j];
str2 += str1[j+1];
}
quint8 k = str2.toInt(&ok, 16);
if(k > 0) barr.append(k);
}
}
// простое дешифрование байтовой последовательности
for(int i = barr.size()-1; i > 0; i--)
{
barr[i] = barr.at(i-1) ^ barr.at(i);
}
barr.remove(0, 1);
QString str = codec->toUnicode(barr);
str.remove(QChar(0));
ui->textEdit_01->append(str);
}
// кнопка clear
void Widget::press_pbtn_04()
{
ui->textEdit_01->clear();
ui->textEdit_02->clear();
}
// расширенный алгоритм Евклида
quint64 extended_evclid(quint64 a, quint64 m)
{
quint64 q, r, x, x1, x2;
x2 = 1;
x1 = 0;
while (m > 0)
{
q = a / m;
r = a - q * m;
a = m;
m = r;
x = x2 - q * x1;
x2 = x1;
x1 = x;
}
return x2;
}
// обратное по модулю
qint64 make_Key(qint64 a, qint64 m)
{
qint64 x = extended_evclid(a, m);
x = (x % m + m) % m;
return x;
}
quint64 sum_mod (quint64 x, quint64 y, quint64 m)
{
if(m - x > y) return x + y;
return y - (m - x);
}
quint64 mul_mod(quint64 x, quint64 y, quint64 m)
{
quint64 tmp;
quint64 res = 0 ;
if(x > y)
{
tmp = x ;
x = y;
y = tmp;
}
while(x)
{
if(x & 1) res = sum_mod(res, y, m);
y = sum_mod(y , y , m);
x >>= 1;
}
return res ;
}
quint64 make_RSA(quint64 x, quint64 n, quint64 m)
{
quint64 res = 1 ;
while(n)
{
if(n & 1) res = mul_mod(res, x, m);
x = mul_mod(x, x, m);
n >>= 1;
}
return res ;
}
bool isPrime(quint64 a)
{
quint64 x;
quint64 n = sqrt(a)/6 + 1;
if(a == 2) return true;
if(a == 3) return true;
if(!(a % 2)) return false;
if(!(a % 3)) return false;
for(quint64 i = 1; i < n; i++)
{
x = 6 * i;
if(!(a % (x-1))) return false;
if(!(a % (x+1))) return false;
}
return true;
}
// синтез простого числа
quint64 makePrimeDigit()
{
quint32 a = 0x80000000;
quint32 b = 0xfffffff0;
quint64 x = QRandomGenerator::global()->bounded(a, b);
if(!(x % 2)) x++;
while(!isPrime(x))
{
x += 2;
}
return x;
}