在csdn苦寻答案无果
奈何作业明天截至
苦苦鏖战三小时
终于搞定!!!
希望copy的朋友可以关注我一波
另外,头歌不能复制粘贴,如何解决?,评论区留言,我@方法!!
多谢多谢!!!
任务描述
本关任务:编写一个能实现移位密码的小程序,对输入的明文字符串进行移位加密后打印输出。
相关知识
移位加密是密码学中一种非常经典、也是很重要的加密方法,学好移位加密对后面其他加密方法的学习有着至关重要的作用。
为了完成本关任务,你需要掌握: 1.数论中的模运算; 2.定义模 m 上的运算; 3.移位密码体制。
模运算知识补充 假设a和b均为整数,m是一正整数。若m整除b−a,则可将其表示为: a≡b(mod m) 该式读作“a与b模m同余”,正整数m称为模数。
下面给出计算一组数据中符合指定模数的同余的数字对,具体 C++ 代码示例如下:
constexpr int mod=9; // 模数 mod 取值为9
int a[10]= {2,11,12};
for(size_t i=1; i<3; i++) // 循环遍历数组 a 中所有的数字对
if((a[i]-a[i-1])%mod==0) // 判断mod是否可以整除两数之差
cout<<a[i-1]<<"与"<<a[i]<<"模"<<mod<<"同余"<<endl;
输出: 2与11模9同余
上述代码通过遍历数组 a 中的所有数字对,判断模数能否整除数字对中两数之差,从而找出符合条件的数字对。
模上的运算 通俗的理解,模 m 上的运算就是:在模 m 的集合上定义加法和乘法,下面给出具体定义。
令Zm
表示集合{0,1,...,m-1},在其上的加法和乘法运算类似于普通实数域上的加法和乘法,所不同的只是所得的值是取模以后的余数。具体运算法则如下:
1.对加法运算封闭:对任意的a,b∈Zm
,有a+b∈Zm
。
2.加法运算满足交换律:对任意的a,b∈Zm
,有a+b=b+a。
3.加法运算满足结合律:对任意的a,b,c∈Zm
,有(a+b)+c=a+(b+c)。
4.0是加法单位元:对任意的a∈Zm
,有a+0=0+a=a。
5.任意a∈Zm
的加法逆元为−a,因为a+(−a)=(−a)+a=0。
6.对乘法运算满足封闭性:对任意的a,b∈Zm
,有ab∈Zm
7.乘法运算满足交换律:对任意的a,b∈Zm
,有a×b=b×a。
8.乘法运算满足结合律:对任意的a,b,c∈Zm
,有(a×b)×c=a×(b×c)。
9.1是乘法的单位元:对任意的a,b,c∈Zm
,有a×1=1×a=a。
10.乘法和加法之间存在分配率:对任意的a,b,c∈Zm
,有(a+b)×c=(a×c)+(b×c)。
这里给出判断一组给定数字进行模运算是否满足性质10的 C++ 代码实现示例:
constexpr int mod=9; // 模数取值为9
int a=3,b=4,c=5;
if(a*(b+c)%mod==(a*b+a*c)%mod) //判断乘法与加法之间是否存在分配率
cout<<"乘法和加法之间存在分配率"<<endl;
需要注意的是这里最后的结果是取模后的余数。
移位密码体制 通俗的来讲,移位密码体制就是通过一个线性变换,即一次方程,是使得在该变换下,明文和密文是一一对应的。下面给出具体的移位的密码体制。 令P=C=K=Z26
(这里的P表示明文空间,C代表密文空间,K代表密钥空间)。对0<=K<=25,任意x,y属于Z26
,定义: Ek
(x)=(x+K)mod26,这个是加密式子,具体是对每一位明文字符x进行右移K位得到密文。 Dk
(y)=(y−K)mod26,这个是解密式子,具体是对每一位密文字符y进行左移K位得到明文。
另外当K=3的时候,此密码体制叫做凯撒密码。
编程要求
本关的编程任务是,补全右侧编辑器中 Begin-End 区间的代码,实现对只含有小写字母的字符串进行K位加密。具体要求如下:
先读取输入 K,表示移位密码的参数。然后读取输入的一个只含小写字母的字符串。要求你输出该字符串经过 K 位加密之后的密文串,其中串的长度在 100 以内,0<=K<=25。
测试说明
平台会对你编写的代码进行测试:
测试输入: 1
a
预期输出: b
测试输入: 2
abc
预期输出: cde
后续答案!!!!!!!!!
第1关:移位密码
#include<bits/stdc++.h>
using namespace std;
char S[100];
int main()
{
int K;
int i,len;
scanf("%d",&K);
cin>>S;
len=strlen(S);
for(i=0;i<len;i++){
S[i]=(S[i]-'a'+K)%26+'a';
cout<<S[i];
}
}
第2关:vigenere密码
#include <iostream>
#include <cstring>
#include <bits/stdc++.h>
using namespace std;
char A[103], B[103];
//在下面Begin和End之间补全代码,对输入的字符串进行维吉尼亚加密
int main()
{
cin >> A; //输入密钥字符串
cin >> B; //输入明文字符串
/*********** Begin ***********/
int keyIndex = 0;
string ciphertext;
for (char ch : B) {
// 忽略非字母字符
if (!isalpha(ch)) {
ciphertext += ch;
continue;
}
// 将字符转换为小写
char plainChar = tolower(ch);
// 计算密钥字符
char keyChar = tolower(A[keyIndex]);
// 计算密文字符
int shift = keyChar - 'a';
char cipherChar = (plainChar - 'a' + shift) % 26 + 'a';
// 添加到密文字符串
ciphertext += cipherChar;
// 更新密钥索引
keyIndex = (keyIndex + 1) % strlen(A);
}
// 输出密文
cout << ciphertext << endl;
/*********** End ***********/
}
第3关:周期置换密码
#include <iostream>
#include <vector>
#include <string>
std::string encryptPeriodicSubstitution(int keyLength, std::vector<int> key, std::string plaintext) {
std::string ciphertext = "";
for (int i = 0; i < plaintext.length(); i += keyLength) {
for (int j = 0; j < keyLength; j++) {
if (i + key[j] - 1 < plaintext.length()) {
ciphertext += plaintext[i + key[j] - 1];
}
}
}
return ciphertext;
}
int main() {
int keyLength;
std::cin >> keyLength;
std::vector<int> key(keyLength);
for (int i = 0; i < keyLength; i++) {
std::cin >> key[i];
}
std::string plaintext;
std::cin.ignore(); // 消耗换行符
std::getline(std::cin, plaintext);
std::string ciphertext = encryptPeriodicSubstitution(keyLength, key, plaintext);
std::cout << ciphertext << std::endl;
return 0;
}
还请点个关注!!!!