#include <stdio.h>
#include <iostream>
#include <string.h>
#include <cmath>
#include <string>
#include <set>
#include <map>
#include <vector>
#include <time.h>

using namespace std;

long long gcd(long long a, long long b)
{
if (b == 0) return a;
else return gcd(b, a%b);
}

long long ext_gcd(long long a, long long b, long long &x, long long &y)
{
if (a == 0 && b == 0) return -1;
if (b == 0)
{
x = 1;
y = 0;
return a;
}
long long d = ext_gcd(b, a%b, y, x);
y -= a / b*x;
return d;
}

long long mod_reverse(long long a, long long n)
{
long long x, y;
long long d = ext_gcd(a, n, x, y);
if (d == 1)
return (x%n + n) % n;
else
return -1;
}

struct Hellman
{
int n;
int a[100010];
int b[100010];
int c[100010];
void solve()
{
cout << "*******************************" << endl;
printf("本数据假定递增序列(1,3,5,10)\nM=20,W=7\n明文为13的加密解秘过程\n");
cout << "*******************************" << endl<<endl<<endl;

//scanf("%d", &n);//输入长度n
int sum = 0;
int pos = 1;
n = 4;

//随机生成超递增序列
/*
while (1)
{
srand(time(NULL));
int tmp = rand() % 1000;
if (tmp > sum)
{
a[pos++] = tmp;//私钥
sum += tmp;
}
if (pos == n + 1) break;
}
*/

sum = 19;
a[1] = 1;
a[2] = 3;
a[3] = 5;
a[4] = 10;

//随机生成M W
int M = double(rand() / RAND_MAX)* (sum + 1001 - sum + 1) + sum + 1;
int W = M - 1;
/*
while (gcd(M, W) != 1)
{
srand(time(0));
int aa = 1;
int bb = M - 1;
W = rand() / RAND_MAX * (bb - aa) + aa;
}
*/

M = 20;
W = 7;

//公钥
for (int i = 1;i <= n;i++)
{
b[i] = W * a[i] % M;
}

///取明文
cout << "请输入明文:" << endl;
int clear;
scanf("%d", &clear);
int len = 1;
int num[100010];
int tmp = clear;
cout << "加密:" << endl;
cout << "start" << endl;
cout << ".............." << endl;
cout << "end" << endl;
//获得比特流
while (tmp)
{
if (tmp & 1)
num[len++] = 1;
else
num[len++] = 0;
tmp >>= 1;
}


//加密c
int c = 0;
for (int i = 1;i < len;i++)
c += num[len - i] * b[i];

cout << "加密得到的数字c为:" << endl;
cout << c << endl;

//int d = mod_reverse(W, M) * c % M;
int d = 3;
c = c*d%M;
cout << "加密得到的转换的c为:" << endl;
cout << c << endl;
int ans[10010];
memset(ans, 0, sizeof(ans));

for (int i = n;i >= 1;i--)
{
if (c >= a[i])
{
ans[i] = 1;
c = c - a[i];
}
}
cout << "解密:"<< endl;
int tt = 0;
for (int i = 1;i <= n;i++)
{
printf("%d", ans[i]);
if (ans[i]) tt += pow(2,n-i);
}
cout << "----" << tt << endl;
}
}hellman;

int main()
{
hellman.solve();
return 0;
}