题目描述
有一种方式是使用密钥进行加密的方法,就是对明文的每个字符使用密钥上对应的密码进行加密,最终得到密文
例如明文是abcde,密钥是234,那么加密方法就是a对应密钥的2,也就是a偏移2位转化为c;明文b对应密钥的3,就是b偏移3位转化为e,同理c偏移4位转化为g。这时候密钥已经使用完,那么又重头开始使用。因此明文的d对应密钥的2,转化为f,明文的e对应密钥的3转化为h。所以明文abcde,密钥234,经过加密后得到密文是cegfh。
如果字母偏移的位数超过26个字母范围,则循环偏移,例如字母z偏移2位,就是转化为b,同理字母x偏移5位就是转化为c
要求:
使用三个指针p、q、s分别指向明文、密钥和密文,然后使用指针p和q来访问每个位置的字符,进行加密得到密文存储在指针s指向的位置。
除了变量定义和输入数据,其他过程都不能使用数组下标法,必须使用三个指针来访问明文、密钥和密文。
提示:当指针q已经移动到密钥的末尾,但明文仍然没有结束,那么q就跳回密钥头
输入
第一行输入t表示有t个测试实例
第二行输入一个字符串,表示第一个实例的明文, 字符串的最大长度不超过20
第三行输入一个数字串,表示第一个实例的密钥,数字串的最大长度不超过20
依次输入t个实例
输出
每行输出加密后的密文
输入样例
2
abcde
234
XenOS
56
输出样例
cegfh
CksUX
代码
#include <iostream>
#include <string.h>
using namespace std;
int main()
{
int t;
cin >> t;
char *p, *s;
char *q;
for(int i = 0; i < t; i++)
{
int j=0;
char a[21];
char b[21];
cin >> a;
cin >> b;
s = new char[21];
p = &a[0];
q = &b[0];
for (int o = 0; o <= strlen(a); o++) {
j = o % strlen(q);
if (*(p + o) >= 'a' && *(p + o) <= 'z') {
*(s + o) = (*(p + o) + *(q + j) - '0' - 'a') % 26 + 'a';
}
if (*(p + o) >= 'A' && *(p + o) <= 'Z') {
*(s + o) = (*(p + o) + *(q + j) - '0' - 'A') % 26 + 'A';
}
}
for (int o = 0; o < strlen(a); o++) {
cout << *(s+o);
}
cout << endl;
delete[]s;
}
return 0;
}
假如不用指针,我们可以让代码变得更简洁:
#include <iostream>
#include<string.h>
using namespace std;
int main()
{
char info[20],code[20];
int testnum;
cin >> testnum;
while (testnum--){
cin >> info>>code;
int j = 0;
for (int i = 0; i < strlen(info); i++) {
if (code[j] == 0)j = 0;
info[i] += code[j]-'0';
if (info[i] > 'Z' && info[i] < 'a')info[i] -= 26;
if (info[i] > 'z')info[i] -= 26;
j++;
}
cout << info<<endl;
}
}
另外提供函数封装版:
#include <iostream>
#include <cstring>
using namespace std;
char* encrypted(char* m, char* n) { //m为明文,n为密钥,返回res为密文
char* res = new char[21];
/*加密过程*/
int lenm = strlen(m), lenn = strlen(n),i=0,j=0;
//cout << lenm <<" " << lenn << endl;
for (i = 0; i < lenm; i++) {
if (*(n+j)==0)j = 0;
*(res+i) = *(m + i) + *(n + j) - '0'; //如果可以不按题目要求,可以直接修改指针指向的数据,不必拷贝到新内存区
if (*(res + i) >= 'Z' && *(res + i) <= 'a')*(res + i) -= 26;
else if (*(res + i) >= 'z' )*(res + i) -= 26;
//cout << *(res + i);
j++;
}
*(res + i) = 0; //注意要加结束符号'\0',即ascii码“0”,作为字符串结尾方便打印
//cout << endl;
return res;
}
int main()
{
int t;
cin >> t;
while (t--) {
char* str1 = new char[21]; //这里可以直接 char str1[21] 替代。
char* str2 = new char[21]; //同上,分配动态内存,动态内存存放在堆空间中
cin >> str1 >> str2;
char* pres = encrypted(str1, str2);
int n = 0; //输出密文
//cout<<pres<<endl;
while (*(pres + n) != 0) { // 这里可以直接 cout << pres<<endl;
cout << *(pres + n); //因为有结束符'\0',输出整个字符数组
n++;
}
cout << endl;
delete[]str1;
delete[]str2;
}
return 0;
}
声明:答案仅供参考,代码仅代表通过了oj测试样例,不代表逻辑的绝对严谨,如有疑问欢迎提出。
更新日志:文章将保持更新纠错
最后一次更新2022/9/12