您的位置:首页 > 编程语言 > C语言/C++

C语言学习笔记(八)---简单的背包加密算法练习

2017-11-14 16:04 323 查看
最近学了点加密算法于是打算自己写一个小程序来实现这些加解密过程。先从简单的背包加密开始吧。

源代码贴在下面,exe文件下载密码:iitg

一、算法设计

背包算法-百度百科

1.算法设计过程

首先考虑到明文多由各种字符组成,如“Just for fun.“。然后思考权衡后(有了自知之明之后)决定加密后的密文为多个数字,每个数字对应一个字符。与字符对应的数字首先想到ASCII码,于是考虑对ASCII码的二进制格式进行背包加密。

但这样加密的强度显然是不够的,于是在前辈的指导下借鉴了cbc的方法进行扩散

2.公开钥

考虑到每个字符占8byte,使用8个数字作为公开钥。

a:{217,218,219,222,228,240,262,100}

初始向量:P

3.秘密钥

b:{1,3,5,11,23,47,91,200}

M,W^-1:{433,2}

4.明文

Just for fun.

5.密文

340 457 1008 319 1104 905 1039 1388 703 1029 730 787 1126

6.加解密运算过程

(0).准备工作

定义初始向量iv:P并对其进行加密——>490

(1).加密(以加密’I’为例)

读取字符’I’——>得到其ASCII码值:73——>与前一位密文或初始向量加密值进行异或:163——>转化为二进制:10100011——>使用公开钥进行加密计算得到密文:775(1*100+1*240+1*217+1*218)

(2).解密(以解密701为例)

读取密文数字775——>计算c=(W^-1*c)modM:251——>使用b对其求解:-93——>与前一位密文或初始向量加密值后八位进行异或:01001001——>得到ASCII码:73——>得到明文:‘I’

二、简单的C语言实现

//
//  main.c
//  BagLock
//
//  Created by passer_by_a on 2017/11/14.
//  Copyright © 2017年 passer_by_a. All rights reserved.
//
#include <stdio.h>
#include <math.h>

char p[100]={0};//plaintext
int n;//the length of plaintext
int c[100]={0};//ciphertext
int a[11]={0};
int b[]={1,3,5,11,23,47,91,200};//超递增数列
int M=433,W=217,w=2;//密钥

void aCreate()//通过b计算出a
{
for(int i=0;;i++)
{
if(b[i]) a[i]=(W*b[i])%M;
else break;
}
}

char FindAnswer(int o)//求解背包问题
{
int answer1[10]={0};
for(int i=0;i<8;i++)
{
if(o/b[7-i])
{
answer1[7-i]=o/b[7-i];
o-=b[7-i];
}
}
int t=0;
for(int i=0;i<=7;i++)
{
if(answer1[i]) t+=pow(2,i);
}
return t;
}

void translateP()//对明文逐个进行加密
{

for(int i=0;i<=n;i++)
{
int k=0;
int cp=pow(2,8);
if(i!=0) k=((int)p[i])^(c[i-1]%cp);
else k=(int)p[i];
int ans=0;
for(int j=0;j<8;j++)
{
ans+=(k%2)*a[j];
k/=2;
}
c[i]=ans;
}
}

void translateC()//对密文逐个进行解密
{
for(int i=n;i>=1;i--)
{
int c1=((c[i])*w)%M;
c[i]=FindAnswer(c1)^c[i-1];
p[i]=(char)c[i];
}
}

void encode()//加密
{
aCreate();
p[0]='P';
printf("This program will encrypt your text into numbers.\n");
printf("Please input the plaintext :");
for(int i=1;;i++)
{
scanf("%c",&p[i]);
n=i-1;
if(p[i]=='\n') break;
}
translateP();
printf("The ciphertext is:");
for(int i=1;i<=n;i++)
{
printf("%d ",c[i]);
}
printf("\n");
}

void decode()//解密
{
printf("This program will decrypt your numbers into text.\n");
printf("Please input the ciphertext and input '#' to end:");
for(int i=1;;i++)
{
scanf("%d",&c[i]);
char o=getchar();
n=i;
if(o=='#') break;
}
translateC();
printf("The plaintext is:");
for(int i=1;i<=n;i++)
{
printf("%c",p[i]);
}
printf("\n");
}

int main() {
int num;
p[0]='P';
c[0]=490;
printf("Num 1 for encrypt, and num 0 for decrypt.\n");
scanf("%d",&num);
getchar();

if(num) encode();
else decode();
return 0;
}


三、菜鸡自白

背包加密实际上是种很高级的加密算法,但由于我能力有限,写出来的算法很弱,但麻雀虽小,五脏俱全,大概还是有点意思的吧。有一个非常致命的点是我不会解背包问题,所以用了暴力方法(事先准备好所有解的情况,然后一个一个比较),但是在这个程序弱弱的环境下,好像还是不太影响效率的。。。

在机智舍友的指导下改成了比较6的背包问题求解算法,再借鉴了cbc的扩散方式,虽然还是一个个加密,一个个解密,但大概也算是具体而微了吧。

学这些加密算法真的挺有意思的(就是头有点凉)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: