一、 实验目的
通过实际编程掌握仿射变换的加密及解密,加深对仿射变换的认识。
二、 实验要求:
1、 根据课上所讲的内容,写出仿射变换的加密、解密公式。
加密函数: Y=(AX+B)%26
解密函数: X=(A 的逆元)*(Y-B)%26
2、 编写一个通用的程序,不要只是针对这一个题目。
#include
int main(){
FILE *fp = ("fangshe1.txt", "rt");
FILE *res = fopen("fangshe2.txt", "wt+");
char ch;
char r;
int a = 17, b = 1, m = 26;
int k = 3;
r = (char) ((a * (ch-65) + b) % m + 65);
fputc(r, res);
}
else if(ch >= 97 && ch <= 122){
r = (char) ((a * (ch-97) + b) % m + 97);
fputc(r, res);
if(fp == NULL)
if(res == NULL)
printf("Cannot open file\n");
printf("Cannot open file\n");
ch = fgetc(fp);
while(ch != EOF){
if(ch >= 65 && ch <= 90){
}
else
fputc(ch ,res);
ch = fgetc(fp);
}
fclose(fp);
fclose(res);
}
三、 实验环境
运行 Windows 操作系统的 PC 机,具有 VC++等 C 语言编译环境
四、 实验内容
1、用仿射变换 3x+5 加密如下明文:data
2、用仿射变换 3x+5 解密如下密文:
FMXVEDKAPHFERBNDKRXRSREFMORUDSDKDVSHVUFEDKAPRKDL
YEVLRH HRH
思路:
1、先求 a 的逆元。
2、#include
#include
#define
N
26
//仿射变换默认模数为 26
//加密算法
char
//解密算法
char
*encode(char
*decode(char
*c_str,
int
a,
int
b,
int
n);
*m_str,
int
a,
int
b,
int
n);
setCoprime(int
//设置数组 coprime 为存放与 n 互素的元素
void
coprime[],
//获取 value1,value2 的最大公约数
int
//在 coprime 中寻找 a 的模 n 可逆元_a
int
getGcd(int
get_a(int
coprime[],
int
value1,
int
value2);
int
n);
a,
int
n);
int
{
int
int
main()
a
b
=
=
0;
0;
//str 存储明文
char
str[128]
=
"";
printf("输入 a,
%d",
scanf("%d
b 的值\n");
&a,
&b);
getchar();
//抵消换行符的干扰
printf("输入 str 的内容\n");
gets(str);
//注意输入大写字母字符串
//输出明文
printf("明文:%s\n",
str);
//加密
encode(str,
a,
b,
N);
//检验是否加密成功
printf("密文:%s\n",
str);
getchar();
getchar();
getchar();
getchar();
return
0;
}
char
{
char
assert
*encode(char
*c_str,
int
a,
int
b,
int
n)
*p_str
=
c_str;
//减小副作用
(c_str);
//判断明文字符串 c_str 是否为 NULL
'
==
*c_str) //遇到空格就跳过
(*c_str)
('
while
{
if
{
++c_str;
continue;
}
<
'A')
||
(*c_str
>
'Z'))
//不是‘A’到‘Z’之
((*c_str
if
间的就中断
assert(0);
'A'; //将字符转化为对应数字
(a*(*c_str)
+
b)%n;//加密核心算法
'A'; //将数字转化为字符
*c_str
*c_str
*c_str
-=
=
+=
++c_str;
}
return
}
p_str;
setCoprime(int
coprime[],
int
n)
void
{
i++)
n;
<
getGcd(n,
i))//判断是否 n,i 是否互素
=
i;
//将 i 存入 coprime 中
int
i
=
1;
(1
(;
i
==
for
if
*(coprime++)
}
int
{
int
int
gcd
divisor
=
getGcd(int
value1,
int
value2)
0;
=
//最大公约数
0;
//余数
do //辗转相除法
{
divisor
=
value1
%
value2;
gcd
=
value2;
value1
value2
=
=
value2;
divisor;
}while(divisor);
get_a(int
coprime[],
int
a,
int
n)
return
int
{
int
i
gcd;}
=
0;
(;
for
if
(1
return
coprime[i]
!=
0;
i++)
(a*coprime[i])%n)
==
coprime[i];
return
}
0;
3、将密文字母转化成数字,再按照计算公式求出结果
=
'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
'FMXVEDKAPHFERBNDKRXRSREFMORUDSDKDVSHVUFEDKAPRKDL
YEVLRH
H
''
letter
word
RH'
flag
=
=
a
b
=
=
3
5
word:
range(0,len(letter)):
i
==
letter[(a*j+b)%26]:
i
j
in
in
for
for
if
flag+=letter[j]
print(flag)
4、。
五、 程序运行结果:
六、