您的位置:首页 > 其它

北大考研复试上机——W's Cipher

2018-01-17 18:38 417 查看

题目描述

Weird Wally's Wireless Widgets, Inc. manufactures an eclectic assortmentof small, wireless, network capable devices, ranging from dog collars,to pencils, to fishing bobbers. All these devices have very smallmemories. Encryption
algorithms like Rijndael, the candidate for theAdvanced Encryption Standard (AES) are demonstrably secure but theydon't fit in such a tiny memory. In order to provide some security fortransmissions to and from the devices, WWWW uses the followingalgorithm,
which you are to implement. Encrypting a message requiresthree integer keys, k1, k2, and k3. The letters [a-i] form one group,[j-r] a second group, and everything else ([s-z] and underscore) thethird group. Within each group the letters are rotated left by
kipositions in the message. Each group is rotated independently of theother two. Decrypting the message means doing a right rotation by kipositions within each group. Consider the message the_quick_brown_foxencrypted with ki values of 2, 3 and 1. The encrypted
string is_icuo_bfnwhoq_kxert. The figure below shows the decrypting rightrotations for one character in each of the three character groups.


Looking at all the letters in the group [a-i] we see {i,c,b,f,h,e}appear at positions {2,3,7,8,11,17} within the encrypted message. Aftera right rotation of k1=2,
these positions contain the letters{h,e,i,c,b,f}. The table below shows the intermediate strings that comefrom doing all the rotations in the first group, then all rotations inthe second group, then all the rotations in the third group. Rotatingletters in
one group will not change any letters in any of the othergroups.

All input strings contain only lowercase letters and underscores(_).Each string will be at most
80 characters long. The ki are all positiveintegers in the range 1-100.

输入描述:

Input consists of information for one or more encrypted messages. Each problem begins with one line containing k1, k2, and k3 followed by a line containing the encrypted message. The end of the input is signalled by a line with all key values of 0.

输出描述:

For each encrypted message, the output is a single line containing the decrypted string.

示例1

输入

2 3 1
_icuo_bfnwhoq_kxert
1 1 1
bcalmkyzx
3 7 4
wcb_mxfep_dorul_eov_qtkrhe_ozany_dgtoh_u_eji
2 4 3
cjvdksaltbmu
0 0 0


输出

the_quick_brown_fox
abcklmxyz
the_quick_brown_fox_jumped_over_the_lazy_dog
ajsbktcludmv


    思路:感觉这道题是直接从POJ里扒出来的。题目大意很好理解,分组加密,将明文字符串的字符分为三组,每组分别作不同的凯撒加密,即分别将第一组、第二组、第三组字符向前循环移动key1、key2、key3个位置。比较坑的是这里数据里的key它可以是大于这个字符串的长度的。题目要求写一个解密算法,也就是将上述的过程逆转一下。

    有这么几个难点,一是分别记录每组字符出现的位置,这里使用三个数组来记录,相当于把密文中的字符位置映射到一个连续的区间里;二是将字符循环右移key位,这里使用先将整个序列倒置,然后将前key个字符倒置,然后将key+1之后的字符倒置,通过这样的方式可以比较方便的实现循环右移。

#include <cstdio>
#include <cstdlib>
#include <climits>
#include <memory>
#include <cstring>
#include <cmath>
#include <map>
#include <iostream>
using namespace std;

int record_1[3000], count_1, key_1;
int record_2[3000], count_2, key_2;
int record_3[3000], count_3, key_3;

string message;

void rotate_right(int record[], int counter, int key)
{
int left = 0, right = counter - 1;
while(left < right)
swap(message[record[left++]], message[record[right--]]);
left = 0, right = key - 1;
while(left < right)
swap(message[record[left++]], message[record[right--]]);
left = key, right = counter - 1;
while(left < right)
swap(message[record[left++]], message[record[right--]]);
}

int main()
{
while (cin >> key_1 >> key_2 >> key_3)
{
if(key_1 == 0 && key_2 == 0 && key_3 == 0) break;

cin >> message;
count_1 = 0;
count_2 = 0;
count_3 = 0;
for(int i = 0; i < message.length(); i++)
{
if(message[i] >= 'a' && message[i] <= 'i') record_1[count_1++] = i;
else if(message[i] >= 'j' && message[i] <= 'r') record_2[count_2++] = i;
else record_3[count_3++] = i;
}
rotate_right(record_1, count_1, key_1 % count_1);
rotate_right(record_2, count_2, key_2 % count_2);
rotate_right(record_3, count_3, key_3 % count_3);
cout << message << "\n";
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: