一、实验目的
通过实现简单的线性反馈移位寄存器(LFSR),理解LFSR的工作原理、本原多项式的重要意义
二、实验内容
1)利用C\C++语言实现给定的LFSR;
2)通过不同初始状态生成相应的序列,并观察它们的周期有什么特点;
3)利用生成的序列对文本进行加/解密(按对应位作模2加运算)。
给定的LFSR为:
- 实验步骤
1.总体理解,LFSR每个状态对应一个输出,所以需要定义三个变量分别为
int array[5]; //暂存状态
int state[32][5]; //存储状态,总共有2^5共32种不同的状态
int seq[32]; //输出序列
2.由所给的图得知反馈函数f(x)=a1^a4,即a5=a1^a4,得到下面的主要函数int temp=arr[0]^arr[3];
3.关于不同的状态;定义了三个相关函数
//打印当前状态
void print(int *arr)
//求出下一状态
void next(int *arr)
//获得状态并存储
void get_state(int *arr, int *s)
4.求解周期:将上文中的state二维数组作为参数依此比较每一状态,求出周期
定义了一个比较函数int cmp_s(int s[32][5]),比较state数组中存储的32个不同的状态、
5.由于是模2运算,所以加密和解密函数都可以使用同一个加密解密函数
void enc(int *cipher, int *m, int *seq, int num),seq传入加密序列,然进行异或
其中,关于加密序列的使用,循环使用然后与二进制的明文进行异或
代码如下:
// 序列密码.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//f(x)=a1^a4,即a5=a1^a4
#include "pch.h"
#include<iostream>
#include<math.h>
using namespace std;
#include<fstream>
#include<string>
#define n 5
//求输入
int LFSR(int *arr)
{
int temp=arr[0]^arr[3];
return temp;
}
//打印
void print(int *arr)
{
cout << "当前状态:";
for (int i = 0; i < n; i++)
{
cout<< arr[i];
}
cout << "\t";
cout << "输出:" << arr[0] << endl;
}
//求出下一状态
void next(int *arr)
{
int a5 = LFSR(arr);
for (int i = 0; i < n - 1; i++)
{
arr[i] = arr[i + 1];
}
arr[n - 1] = a5;
}
//获得状态并存储
void get_state(int *arr, int *s)
{
for (int i = 0; i < n; i++)
{
s[i] = arr[i];
}
}
//为了获取周期对状态进行比较
int cmp_s(int s[32][5])
{
for (int i = 1; i < 32; i++)
{
int j;
for (j = 0; j < 5; j++)
{
if (s[0][j] != s[i][j])
break;
else continue;
}
if (j == 5)
{
return i;
}
}
}
string change(char c)
{
string data;
for (int i = 0; i < 8; i++)
{
// data+=c&(0x01<<i);
if ((c >> (i - 1)) & 0x01 == 1)
{
data += "1";
}
else
{
data += "0";
}
}
for (int a = 1; a < 5; a++)
{
char x = data[a];
data[a] = data[8 - a];
data[8 - a] = x;
}
return data;
}
void enc(int *cipher, int *m, int *seq, int num)
{
int counter = 0;
int counter_num = 0;
int num_8 = 8 * num;//num传入filenum,因为是8位,filenum为符号数,所以位数为8*filenum
while (counter_num<num_8)
{
cipher[counter_num]=seq[counter]^m[counter_num];
counter++;
counter_num++;
if (counter == 31)
counter = 0;
}
}
int main()
{
int array[5];
int state[32][5]; //存储状态,总共有2^5共32种不同的状态
int seq[32]; //输出序列
int s_num = 0;
cout << "请输入初始状态:";
for (int i = 0; i < n; i++)
{
cin >> array[i];
}
get_state(array,state[s_num]);
cout << s_num<<":";
print(state[s_num]);
seq[s_num] = array[0];
//下一状态
for (int i = 1; i < 32; i++)
{
next(array);
++s_num;
get_state(array, state[s_num]);
cout << s_num<<":";
print(state[s_num]);
seq[s_num] = array[0];
}
cout << "输出序列为:";
for (int i = 0; i < 32; i++)
{
cout << seq[i];
}
cout << endl;
cout<<"周期为:"<<cmp_s(state)<<endl;
char ch[200];//存明文
char c;
int i = 0, filenum;
char filename[81];
ifstream f_in;
rewind(stdin); //清空缓冲区
cout << endl;
cout << "输入要加密的文件名:";
cin.getline(filename, 81);
f_in.open(filename, ios::in | ios::out);
if (!f_in)
{
cout << "Open input file error!" << endl;
exit(0);
}
while (!f_in.eof())
{
f_in.get(c);
ch[i] = c;
i++;
}
f_in.close();
filenum = i - 1;
//输出明文
cout << endl;
cout << "原文为:";
for (int num = 0; num < filenum; num++)
cout << ch[num];
cout << endl;
//把明文转为二进制存入二维数组binary中
int binary[200][8] = {0};
for (int j = 0; j < filenum; j++)
{
int temp[8];
string da = change(ch[j]);
for (int i = 0; i < 8; i++)
{
temp[i] = da[i];
if (temp[i] == 48)
temp[i] = 0;
else temp[i] = 1;
}
for (int i = 0; i < 8; i++)
{
//cout << temp[i];
binary[j][i] = temp[i];
}
//cout << endl;
}
/*for (int i = 0; i < filenum; i++)
{
for (int j = 0; j < 8; j++)
{
cout << binary[i][j];
}
cout << endl;
}*/
int M[1600] = { 0 };
int count = 0;
for (int i = 0; i < filenum; i++)
{
for (int j = 0; j < 8; j++)
{
M[count]=binary[i][j];
//cout << M[count];
count++;
}
}
cout << endl << "明文表示为:";
for (int i = 0; i < count; i++)
{
cout << M[i];
}
cout << endl;
cout << endl << "密文表示为:";;
int cipher[1600];
enc(cipher,M,seq,filenum);
for (int i = 0; i < count; i++)
{
cout << cipher[i];
}
cout << endl;
cout << endl << "解码出的明文为:";;
int c_M[1600];
enc(c_M, cipher, seq, filenum);
for (int i = 0; i < count; i++)
{
cout << c_M[i];
}
cout << endl;
cout <<endl<< "解码出的原文为:";
for (int i = 0; i < filenum; i++)
{
int temp_num = 0;
int temp_i = 8 * i;
temp_num = c_M[0+temp_i] * 128 + c_M[1 + temp_i] * 64 + c_M[2 + temp_i] * 32 + c_M[3 + temp_i] * 16 + c_M[4 + temp_i] * 8 + c_M[5 + temp_i] * 4 + c_M[6 + temp_i] * 2 + c_M[7 + temp_i] * 1;
char c_n = temp_num;
cout << c_n;
}
return 0;
}
结果如下: