ACM集训中出现的移位密码题 —— WERTYU

First Post:

Last Update:

Word Count:
1.1k

Read Time:
5 min

0x00 先看看题

A common typing error is to place the hands on the keyboard one row to the right of the correct position. So ‘Q’ is typed as ‘W’ and ‘J’ is typed as ‘K’ and so on. You are to decode a message typed in this manner.

一个常见的打字错误是把手放在键盘正确位置的右边一行。因此,“Q”被输入为“W”,“J”被输入为“K”,以此类推。你要解码用这种方式输入的信息。

  • 输入

Input consists of several lines of text. Each line may contain digits, spaces, upper case letters (except Q, A, Z), or punctuation shown above [except back-quote (‘)]. Keys labelled with words [Tab, BackSp, Control, etc.] are not represented in the input

输入由几行文本组成。每一行可以包含数字、空格、大写字母(除q、A、Z)或上面所示的标点符号[除反引号(‘)]。用[Tab, BackSp,Control等]标记的键在输入中不表示

  • 输出

You are to replace each letter or punction symbol by the one immediately to its left on the ‘QWERTY’ keyboard shown above. Spaces in the input should be echoed in the output.

您将替换每个字母或标点符号的一个立即到其左边的’ QWERTY ‘键盘如上所示。输入中的空格应该在输出中回显。

  • 示例输入

O S, GOMR YPFSU/

  • 示例输出

I AM FINE TODAY.

0x01 题目分析

这题很明显是根据键盘密码表对文字进行加密。所有输入的文字都根据其在键盘上的位置向右移动一位。因此,解密的话,就是根据相同的密码表向左移动一位即可。

  • 由题意产生的密码表
C++ 共 1 行
展开
1
pass = "`1234567890-=QWERTYUIOP[]\\ASDFGHJKL;'ZXCVBNM,./";

0x02 加解密分析

忽略题目中的无意行为,假设这是有意识的加密行为,我们如何用程序模拟这一过程。即,给出原文,得到密文。我们要做的,只是将原文的每一个字符变成密码表中他右边的那个字符即可。(假设原文不大于100个字符)

解密过程则是题目要求的过程,可以与加密过程共享一套代码,因为需要的是仅仅在移位的时候将每个字符根据密码表向左移动一位字符即可。

0x03 加密程序实现

  • C 代码
C 共 25 行
展开
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <stdio.h>
#include <string.h>

int main(int argc, const char* argv[]) {
const char pass[] = "`1234567890-=QWERTYUIOP[]\\ASDFGHJKL;'ZXCVBNM,./";
const int psize = strlen(pass);
char original[100];
char encrypted[100];
while (fgets(original,100,stdin)) {
int size = strlen(original);
memset(encrypted,0,100);
for (int i = 0; i < size; i++) {
for (int j = 0; j < psize; j++) {
if (original[i] == pass[j]) {
encrypted[i] = pass[j + 1];
}
if (original[i] == ' ') {
encrypted[i] = ' ';
}
}
}
fputs(encrypted,stdout);
}
return 0;
}
  • C++ 代码
C++ 共 24 行
展开
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <string>

using namespace std;

int main(int argc, const char* argv[]) {
string pass = "`1234567890-=QWERTYUIOP[]\\ASDFGHJKL;'ZXCVBNM,./";
string original;
string encrypted;
while (getline(cin,original)) {
encrypted.clear();
for (char &str : original) {
if (pass.find(str) != string::npos) {
encrypted += pass[pass.find(str) + 1];
}
if (str == ' ') {
encrypted += ' ';
}
}
cout << encrypted << endl;
}
return 0;
}
  • Python代码
PYTHON 共 9 行
展开
1
2
3
4
5
6
7
8
9
passc = " `1234567890-=QWERTYUIOP[]\\ASDFGHJKL;'ZXCVBNM,./"
while original := input():
encrypted = ""
for i in original:
if passc.find(i):
encrypted += passc[passc.find(i) + 1]
if i == ' ':
encrypted += ' '
print(encrypted)

0x04 解密程序实现

  • C 代码
C 共 25 行
展开
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <stdio.h>
#include <string.h>

int main(int argc, const char* argv[]) {
const char pass[] = "`1234567890-=QWERTYUIOP[]\\ASDFGHJKL;'ZXCVBNM,./";
const int psize = strlen(pass);
char original[100];
char decrypted[100];
while (fgets(original,100,stdin)) {
int size = strlen(original);
memset(decrypted,0,100);
for (int i = 0; i < size; i++) {
for (int j = 0; j < psize; j++) {
if (original[i] == pass[j]) {
decrypted[i] = pass[j - 1];
}
if (original[i] == ' ') {
decrypted[i] = ' ';
}
}
}
fputs(decrypted,stdout);
}
return 0;
}
  • C++ 代码
C++ 共 24 行
展开
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <string>

using namespace std;

int main(int argc, const char* argv[]) {
string pass = "`1234567890-=QWERTYUIOP[]\\ASDFGHJKL;'ZXCVBNM,./";
string original;
string decrypted;
while (getline(cin,original)) {
decrypted.clear();
for (char &str : original) {
if (pass.find(str) != string::npos) {
decrypted += pass[pass.find(str) - 1];
}
if (str == ' ') {
decrypted += ' ';
}
}
cout << decrypted << endl;
}
return 0;
}
  • Python代码
PYTHON 共 9 行
展开
1
2
3
4
5
6
7
8
9
passc = " `1234567890-=QWERTYUIOP[]\\ASDFGHJKL;'ZXCVBNM,./"
while original := input():
decrypted = ""
for i in original:
if passc.find(i):
decrypted += passc[passc.find(i) - 1]
if i == ' ':
decrypted += ' '
print(decrypted)