2012级周慧霞排列码源码[整理版]
/*************************************************
Author:xzhou
Date:2012-12-30
Version:1.0
Description:方法源自《信息安全技术》(武汉大学出版社),P59排序码实现方法
**************************************************/
#include "stdafx.h"
#include "stdlib.h"
#include "memory.h"
//#include "CodeTable.h"
/*************************************************
Function: orderCode
Description: 排列码加密
Calls: none
Input: 1.加密文件路径
2.加密密钥(要求是32bit),算法内部加有验证方法
3.加密后文件路径
Output: 加密成功与否
Return: 加密成功为true,否则为false
Others: 算法来自《信息安全技术》(武汉大学出版社),P59排序码实现方法
*************************************************/ bool orderCode (char* file_path,unsigned char* first_code, char* new_file_path);
/*************************************************
Function: releaseOrderCode
Description: 排列码加密
Calls: none
Input: 1.解密文件路径
2.解密密钥(要求是32bit),算法内部加有验证方法
3.解密后文件路径
Output: 解密成功与否
Return: 解密密成功为true,否则为false
Others: 算法来自《信息安全技术》(武汉大学出版社),P59排序码实现方法
*************************************************/ bool releaseOrderCode (char* file_path, unsigned char* first_code, char* new_file_path);
void changeCode(unsigned char* cSour, unsigned char* cDest, unsigned char* code_input,
unsigned char preS);
void charPlus(unsigned char* cSour, unsigned char* cDest); void leftMove(unsigned char* cSour, unsigned char* cDest, int flag); int _tmain(int argc, _TCHAR* argv[])
{
//if (argc != 4)
//{
// printf("输入参数有误");
//}
while(true)
{
printf("请选择所需要的功能:\n\t1.加密文件\n\t2.解密文件\n\t3.退出\n\t");
int flag = 0;
char file_path[50] = {'\0'};
char new_file_path[50] = {'\0'};
unsigned char first_code[5] = {'\0'};
scanf_s("%d", &flag);
if (flag < 1 || flag > 3)
{
printf("\t输入错误~\n\t");
continue;
}
switch (flag)
{
case 1:printf("请输入明文文件路径:\n\t");
scanf_s("%s", file_path, 49);
//puts(file_path);
printf("请输入加密后文件路径:\n\t");
scanf_s("%s", new_file_path, 49);
//puts(new_file_path);
printf("请输入4位密文:\n\t");
scanf_s("%s", first_code, 5);
//puts(first_code);
orderCode(file_path, first_code, new_file_path);
break;
case 2:printf("请输入密文文件路径:\n\t");
scanf_s("%s", file_path, 49);
//puts(file_path);
printf("请输入解密后文件路径:\n\t");
scanf_s("%s", new_file_path, 49);
//puts(new_file_path);
printf("请输入4位密文:\n\t");
scanf_s("%s", first_code, 5);
//puts(first_code);
releaseOrderCode(file_path, first_code, new_file_path);
break;
case 3:exit(0);
default:break;
}
}
return 0;
}
bool orderCode (char* file_path, unsigned char* first_code, char* new_file_path)
{
//在本程序中,没有输入256个
表
关于同志近三年现实表现材料材料类招标技术评分表图表与交易pdf视力表打印pdf用图表说话 pdf
,只录入了1张密码表(如果可以实现24行随机排
序算法,则可以实现256张表的实现),
//所以在加密过程中,密钥的第1字节并没有用到,这样也给加密后的结果产生很大影
响,不过已经可以实现加密码过程
if (sizeof(first_code) != 4)
{
printf("input code error!");
return false;
}
int table[24][4] = {0, 1, 2, 3,
0, 1, 3, 2,
0, 2, 1, 3,
0, 2, 3, 1,
0, 3, 1, 2,
0, 3, 2, 1,
1, 0, 2, 3,
1, 0, 3, 0,
1, 2, 0, 3,
1, 2, 3, 0,
1, 3, 0, 2,
1, 3, 2, 0,
2, 0, 1, 3,
2, 0, 3, 1,
2, 1, 0, 3,
2, 1, 3, 0,
2, 3, 0, 1,
2, 3, 1, 0,
3, 0, 1, 2,
3, 0, 2, 1,
3, 1, 0, 2,
3, 1, 2, 0,
3, 2, 0, 1,
3, 2, 1, 0};
FILE* stream;//建立要打开的文件
errno_t err;
if ((err = fopen_s(&stream, file_path, "rb")) != NULL)//对文件进行只读的二进制打开
{
printf("open file error");
}
unsigned char code[5] = {'\0'};
unsigned char codeNext[5] = {'\0'};
for (int m = 0; m < 4; m++)
{
codeNext[m] = code[m] = first_code[m];
}
FILE* input_stream;
if ((err = fopen_s(&input_stream, new_file_path, "w+")) != NULL)
{
printf("open file error");
}//建立密文文件,如果文件存在,则先进行内容清空
unsigned char buf[512] = {'\0'};//建立缓冲区并初始化
unsigned char input_buf[512] = {'\0'};
unsigned char code_input[5] = {'\0'};
for (int i = 0; i< 4; i++)
{
code_input[i] = ~code[i] & 0xF0 | (code[i] & 0x0F);
}
fseek(stream, 0, SEEK_SET);//设置文件当前位置为第一位
while (true)
{//对读入文件进行循环
int read_flag = fread(buf, 1, sizeof(buf), stream);
if (read_flag == 0)
{
// delete code;
fclose(input_stream);
fclose(stream);
return true;
}
if (read_flag < sizeof(buf))
{//如果文件读入长度小于buf,则要进行判断
if (ferror(stream) != 0)
{//文件读入长度小于buf原因
printf("file reads error!");
// delete code;
fclose(input_stream);
fclose(stream);
return false;
}
}
int i = 0;//对buf循环的标志位
while (i < read_flag)
{//循环buf
unsigned char temp_pre_code = buf[i];
unsigned char aft_code = '\0';
//下面将对每4位一次加密
unsigned char pre_code[2] = {'\0'};
unsigned char change_code[2] = {'\0'};
change_code[0] = pre_code[0] = temp_pre_code;
change_code[0] = pre_code[0] >>= 4;
temp_pre_code = buf[i];
change_code[1] = pre_code[1] = temp_pre_code & 0x0F;
for (int n = 0; n <= 1; n++)
{//分别对高低4位进行加密(由于C语言不可产生单个4位数,所以只能手动计算生成)
int code_num = (int)(unsigned char)code[1];
unsigned char code_reverse[2];
code_reverse[0] = code[2];
code_reverse[1] = code[3];
code_num = code_num % 24;//计算code第二字节的余数
unsigned char temp;
unsigned char cal_code = pre_code[n];
pre_code[n] = '\0';
//char pre_res = '\0';
//判断是否需要对要排列的位进行取反(如果将switch修改为用for可能代码量会少些……后话)
for (int m = 0; m < 4; m++)
{
temp = cal_code;
int swit = table[code_num][m] - m;
switch (m)
{
case 0:temp = temp & 0x08;
switch (table[code_num][m])
{
case 0:if ((code_reverse[0] & 0x80) != 0x0)
{
temp = temp ^ 0x08;
}
break;
case 1:if ((code_reverse[0] & 0x40) != 0x0)
{
temp = temp ^ 0x08;
}
break;
case 2:if ((code_reverse[0] & 0x20) != 0x0)
{
temp = temp ^ 0x08;
}
break;
case 3:if ((code_reverse[0] & 0x10) != 0x0)
{
temp = temp ^ 0x08;
}
break;
}
break;
case 1:temp = temp & 0x04;
switch (table[code_num][m])
{
case 0:if ((code_reverse[0] & 0x08) != 0x0)
{
temp = temp ^ 0x04;
}
break;
case 1:if ((code_reverse[0] & 0x04) != 0x0)
{
temp = temp ^ 0x04;
}
break;
case 2:if ((code_reverse[0] & 0x02) != 0x0)
{
temp = temp ^ 0x04;
}
break;
case 3:if ((code_reverse[0] & 0x01) != 0x0)
{
temp = temp ^ 0x04;
}
break;
}
break;
case 2:temp = temp & 0x02;
switch (table[code_num][m])
{
case 0:if ((code_reverse[1] & 0x80) != 0x0)
{
temp = temp ^ 0x02;
}
break;
case 1:if ((code_reverse[1] & 0x40) != 0x0)
{
temp = temp ^ 0x02;
}
break;
case 2:if ((code_reverse[1] & 0x20) != 0x0)
{
temp = temp ^ 0x02;
}
break;
case 3:if ((code_reverse[1] & 0x10) != 0x0)
{
temp = temp ^ 0x02;
}
break;
}
break;
case 3:temp = temp & 0x01;
switch (table[code_num][m])
{
case 0:if ((code_reverse[1] & 0x08) != 0x0)
{
temp = temp ^ 0x01;
}
break;
case 1:if ((code_reverse[1] & 0x04) != 0x0)
{
temp = temp ^ 0x01;
}
break;
case 2:if ((code_reverse[1] & 0x02) != 0x0)
{
temp = temp ^ 0x01;
}
break;
case 3:if ((code_reverse[1] & 0x01) != 0x0)
{
temp = temp ^ 0x01;
}
break;
}
break;
}
//根据前面所提取的swit进行位移动
if (swit < 0)
{
temp <<= abs(swit);
}
else
{
temp >>= swit;
}
pre_code[n] = pre_code[n] | temp;//取所有位的或结果,组成最终结果
}
//修改密钥
changeCode(code, codeNext, code_input, change_code[n]);
for (int cc = 0; cc < 4; cc++)
{
code[cc] = codeNext[cc];
}
}
pre_code[0] <<= 4;//移回高位
aft_code = pre_code[0];
aft_code = aft_code | pre_code[1];//拼接回整字节
input_buf[i] = aft_code;//加入输入buf
i++;
}
fwrite(input_buf, 1, read_flag, input_stream);//将input_buf写入文件
//清空2个buf,以备后来使用
memset(input_buf, '\0', sizeof(input_buf));
memset(buf, '\0', sizeof(buf));
}
}
bool releaseOrderCode (char* file_path, unsigned char* first_code, char* new_file_path)
{//解密算法基本上是加密的正序反计算
if (sizeof(first_code) != 4)
{
printf("input code error!");
return false;
}
int re_table[24][4];
int table[24][4] = {0, 1, 2, 3,
0, 1, 3, 2,
0, 2, 1, 3,
0, 2, 3, 1,
0, 3, 1, 2,
0, 3, 2, 1,
1, 0, 2, 3,
1, 0, 3, 2,
1, 2, 0, 3,
1, 2, 3, 0,
1, 3, 0, 2,
1, 3, 2, 0,
2, 0, 1, 3,
2, 0, 3, 1,
2, 1, 0, 3,
2, 1, 3, 0,
2, 3, 0, 1,
2, 3, 1, 0,
3, 0, 1, 2,
3, 0, 2, 1,
3, 1, 0, 2,
3, 1, 2, 0,
3, 2, 0, 1,
3, 2, 1, 0};
//注意与加密时不同,首先要对加密时的表进行反运算,让其自动适应解密程序
for (int i = 0; i < 24; i++)
{
for (int j = 0; j < 4; j++)
{
re_table[i][table[i][j]] = j;
}
}
errno_t err;
FILE* stream;//建立要打开的文件
if ((err = fopen_s(&stream, file_path, "rb")) != NULL)//对文件进行只读的二进制打开
{
printf("open file error");
return false;
}
unsigned char code[5] = {'\0'};
unsigned char codeNext[5] = {'\0'};
for (int m = 0; m < 4; m++)
{
codeNext[m] = code[m] = first_code[m];
}
FILE* input_stream;
if ((err = fopen_s(&input_stream, new_file_path, "w+")) != NULL)//建立明文文件,如果文
件存在,则先进行内容清空
{
fclose(stream);
printf("open/create output file error!");
return false;
}
unsigned char buf[512] = {'\0'};//建立缓冲区并初始化
unsigned char input_buf[512] = {'\0'};
unsigned char code_input[5] = {'\0'};
for (int i = 0; i< 4; i++)
{
code_input[i] = ~code[i] & 0xF0 | (code[i] & 0x0F);
}
fseek(stream, 0, SEEK_SET);//设置文件当前位置为第一位
while (true)
{//对读入文件进行循环
int read_flag = fread(buf, 1, sizeof(buf), stream);
if (read_flag == 0)
{
// delete code;
fclose(input_stream);
fclose(stream);
return true;
}
if (read_flag < sizeof(buf))
{//如果文件读入长度小于buf,则要进行判断
if (ferror(stream) != 0)
{//文件读入长度小于buf原因
printf("file reads error!");
// delete code;
fclose(input_stream);
fclose(stream);
return false;
}
}
int i = 0;//对buf循环的标志位
while (i < read_flag)
{//循环buf
unsigned char temp_pre_code = buf[i];
unsigned char aft_code = '\0';
//下面将对每4位一次加密
unsigned char pre_code[2] = {'\0'};
unsigned char release_code[2] = {'\0'};
pre_code[0] = temp_pre_code;
pre_code[0] >>= 4;
temp_pre_code = buf[i];
pre_code[1] = temp_pre_code & 0x0F;
for (int n = 0; n <= 1; n++)
{//分别对高低4位进行加密(由于C语言不可产生单个4位数,所以只能手动计算生成)
int code_num = (int)code[1];
//下面一部分是对密钥进行变换,也就是将原来关于取反部分的两个字节进行反射变换
unsigned char code_reverse[2] = {'\0'};
//char re_code_reverse[2] = {'\0'};
//char new_code_reverse[2] = {'\0'};
//char called_code = 0x8F;
unsigned char temp_cal_code[4] = {'\0'};
code_reverse[0] = code[2];
code_reverse[1] = code[3];
unsigned char temp_code[4];
temp_code[0] = temp_code[1] = code[2];
temp_code[2] = temp_code[3] = code[3];
temp_code[0] >>= 4;
temp_code[1] = temp_code[1] & 0x0F;
temp_code[2] >>= 4;
temp_code[3] = temp_code[3] & 0x0F;
unsigned char move_cal = 0x08;
for (int x = 0; x < 4; x++)
{
unsigned char move_res = 0x08;
for (int y = 0; y < 4; y++)
{
unsigned char temp_use = temp_code[y];
if ((temp_use & move_cal) != 0x0)
{
temp_cal_code[x] = temp_cal_code[x] | move_res;
}
move_res >>= 1;
}
move_cal >>= 1;
}
temp_cal_code[0] <<= 4;
temp_cal_code[2] <<= 4;
code_reverse[0] = temp_cal_code[0] | temp_cal_code[1];
code_reverse[1] = temp_cal_code[2] | temp_cal_code[3];//至此密钥反变换全部完成,
code_num = code_num % 24;//计算code第二字节的余数
unsigned char temp;
unsigned char cal_code = pre_code[n];
pre_code[n] = '\0';
//char pre_res = '\0';
//判断是否需要对要排列的位进行取反
for (int m = 0; m < 4; m++)
{
temp = cal_code;
int swit = re_table[code_num][m] - m;
switch (m)
{
case 0:temp = temp & 0x08;
switch (re_table[code_num][m])
{
case 0:if ((code_reverse[0] & 0x80) != 0x0)
{
temp = temp ^ 0x08;
}
break;
case 1:if ((code_reverse[0] & 0x40) != 0x0)
{
temp = temp ^ 0x08;
}
break;
case 2:if ((code_reverse[0] & 0x20) != 0x0)
{
temp = temp ^ 0x08;
}
break;
case 3:if ((code_reverse[0] & 0x10) != 0x0)
{
temp = temp ^ 0x08;
}
break;
}
break;
case 1:temp = temp & 0x04;
switch (re_table[code_num][m])
{
case 0:if ((code_reverse[0] & 0x08) != 0x0)
{
temp = temp ^ 0x04;
}
break;
case 1:if ((code_reverse[0] & 0x04) != 0x0)
{
temp = temp ^ 0x04;
}
break;
case 2:if ((code_reverse[0] & 0x02) != 0x0)
{
temp = temp ^ 0x04;
}
break;
case 3:if ((code_reverse[0] & 0x01) != 0x0)
{
temp = temp ^ 0x04;
}
break;
}
break;
case 2:temp = temp & 0x02;
switch (re_table[code_num][m])
{
case 0:if ((code_reverse[1] & 0x80) != 0x0)
{
temp = temp ^ 0x02;
}
break;
case 1:if ((code_reverse[1] & 0x40) != 0x0)
{
temp = temp ^ 0x02;
}
break;
case 2:if ((code_reverse[1] & 0x20) != 0x0)
{
temp = temp ^ 0x02;
}
break;
case 3:if ((code_reverse[1] & 0x10) != 0x0)
{
temp = temp ^ 0x02;
}
break;
}
break;
case 3:temp = temp & 0x01;
switch (re_table[code_num][m])
{
case 0:if ((code_reverse[1] & 0x08) != 0x0)
{
temp = temp ^ 0x01;
}
break;
case 1:if ((code_reverse[1] & 0x04) != 0x0)
{
temp = temp ^ 0x01;
}
break;
case 2:if ((code_reverse[1] & 0x02) != 0x0)
{
temp = temp ^ 0x01;
}
break;
case 3:if ((code_reverse[1] & 0x01) != 0x0)
{
temp = temp ^ 0x01;
}
break;
}
break;
}
//根据前面所提取的swit进行位移动
if (swit < 0)
{
temp <<= abs(swit);
}
else
{
temp >>= swit;
}
pre_code[n] = pre_code[n] | temp;//取所有位的或结果,组成最终结果
}
changeCode(code, codeNext, code_input, pre_code[n]);
for (int cc = 0; cc < 4; cc++)
{
code[cc] = codeNext[cc];
}
}
pre_code[0] <<= 4;//移回高位
aft_code = pre_code[0];
aft_code = aft_code | pre_code[1];//拼接回整字节
input_buf[i] = aft_code;//加入输入buf
i++;
}
fwrite(input_buf, 1, read_flag, input_stream);//将input_buf写入文件
//清空2个buf,以备后来使用
memset(input_buf, '\0', sizeof(input_buf));
memset(buf, '\0', sizeof(buf));
}
}
void changeCode(unsigned char* cSour, unsigned char* cDest, unsigned char* code_input,
unsigned char preS)
{
// int flag = 0;
// unsigned char temp = 0;
//temp[3] = 0;
//unsigned char tSour[5] = {'\0'};
//for (int i = 0; i < 4; i++)
//{
// tSour[i] = code_input[i];
//}
unsigned char flag = 0;
cSour[3]++;
for (int i = 3; i >= 0; i--)
{
cSour[i] += flag;
if (cSour[i] == 0)
{
flag = 1;
}
else
{
flag = 0;
}
}
// charPlus(temp, tSour);
leftMove(code_input, cDest, 1);
cDest[3] = cDest[3] | preS;
for (int i = 0; i < 4; i++)
{
code_input[i] = cDest[i];
}
charPlus(cSour, cDest);
for (int i = 0; i < 4; i++)
{
cSour[i] = cDest[i];
}
leftMove(cSour, cDest, 0); }
void charPlus(unsigned char* cSour, unsigned char* cDest)
{
// int iSour[4] = {0}; // int iDest[4] = {0};
unsigned char flag = 0;
for (int i = 0; i < 4; i++)
{
// iSour[i] = (int)cSour[i]; // iDest[i] = (int)iDest[i];
}
unsigned char temp = 0;
for (int i = 3; i >= 0; i--)
{
temp = cDest[i] + cSour[i] + flag;
if (cDest[i] < temp)
{
flag = 1;
cDest[i] = temp;
}
else
{
flag = 0;
cDest[i] = temp;
}
}
}
void leftMove(unsigned char* cSour, unsigned char* cDest, int flag)
{
if (flag != 0 && flag != 1)
{
return;
}
for (int i = 0; i < 3; i++)
{
unsigned char tempH = cSour[i];
tempH <<= 4;
unsigned char tempL = cSour[i + 1];
tempL >>= 4;
cDest[i] = tempH | tempL;
}
if (flag == 0)
{
unsigned char tempH = cSour[3];
tempH <<= 4;
unsigned char tempL = cSour[0];
tempL >>= 4;
cDest[3] = tempH | tempL;
}
else if (flag == 1)
{
unsigned char tempH = cSour[3];
tempH <<= 4;
cDest[3] = tempH;
}