SP3373 PERMCODE - Permutation Code
题目描述
作为一家计算机取证公司的老板,你刚刚收到了一位新客户的神秘留言:
我,Albert Charles Montgomery,刚刚发现了一种绝妙的加密方法。让我来分享一下。
首先,你需要选定一组符号,命名为 $S$,比如可以选择字母 RATE。注意,这组符号的数量必须是 2 的幂,且符号的顺序很重要。举例说明,R 位于位置 0,A 位于位置 1,T 位于位置 2,E 位于位置 3。你还需要一个包含所有这些符号的排列 $P$,比如 TEAR。最后,你需要一个整数 $x$。如此一来,这些元素就构成了密钥。有了密钥,你便可以开始将长度为 $n$ 的明文信息 $M$(例如 $M[0], M[1], \ldots, M[n-1]$,它包含 $S$ 中的一些符号)转换成同样长度为 $n$ 的密文字符串 $C$(例如 $C[0], C[1], \ldots, C[n-1]$,也使用 $S$ 中的一些符号)。
加密算法的步骤如下:
1. 计算一个整数 $d$,为 $n^{1.5} + x$ 的整数部分除以 $n$ 后的余数,即 $d = (\text{int})(n^{1.5} + x) \% n$。
2. 将 $C[d]$ 设为 $S$ 中位置对应于 $M[d]$ 在 $P$ 中位置的符号。
3. 对于每个 $j \neq d$ 且 $j \in [0, n-1]$,将 $C[j]$ 设为 $S$ 中的位置等于 $M[j]$ 在 $P$ 中的位置与 $M[(j+1) \% n]$ 在 $S$ 中的位置进行异或运算后的值。注意,位异或运算符在 C、C++ 和 Java 中都是 "^"。
举个例子来说明这一过程:设 $S=\text{RATE}$,$P=\text{TEAR}$,$x=102$,$M=\text{TEETER}$,$n=6$。我们首先计算 $d$ 的值:$6^{1.5} + 102 = 116.696938$,再取余得 $d = 116 \% 6 = 2$。以下是构造密文 $C$ 的步骤。请注意,步骤的顺序并不影响结果。
| 位置 | 0 | 1 | 2 | 3 | 4 | 5 |
|---|---|---|---|---|---|---|
| $S$ | R | A | T | E | | |
| $P$ | T | E | A | R | | |
| $M$ | T | E | E | T | E | R |
| $C$ | E | T | A | E | A | A |
- 对于 $M[0]$ 是 T,T 在 $P[0]$。而 $M[1]$ 是 E,E 在 $S[3]$。因此,$C[0] = S[0 \text{ xor } 3] = S[3]$
- 对于 $M[1]$ 是 E,E 在 $P[1]$。$M[2]$ 同样是 E,在 $S[3]$。因此,$C[1] = S[1 \text{ xor } 3] = S[2]$
- 2 是 $d$。此时,$M[2]$ 是 E,而 E 在 $P[1]$。所以 $C[2] = S[1]$
- 对于 $M[3]$ 是 T,T 在 $P[0]$。而 $M[4]$ 是 E,在 $S[3]$。所以 $C[3] = S[0 \text{ xor } 3] = S[3]$
- 对于 $M[4]$ 是 E,E 在 $P[1]$。而 $M[5]$ 是 R,在 $S[0]$。所以 $C[4] = S[1 \text{ xor } 0] = S[1]$
- 对于 $M[5]$ 是 R,R 在 $P[3]$。而 $M[0]$ 是 T,在 $S[2]$。所以 $C[5] = S[3 \text{ xor } 2] = S[1]$
输入格式
输入由一个或多个 {密钥, 加密消息} 对组成。密钥用三行表示,第一行为整数 $x$,其中 $0 < x < 10,000$;第二行为字符串 $S$;第三行为字符串 $P$,它是 $S$ 的一个排列。$S$(及 $P$)的长度总是 2 的次幂,即 2、4、8、16 或 32。密钥后面是一行字符串 $C$,表示加密后的消息,长度介于 1 至 60 之间。字符 $S$、$P$ 和 $C$ 不包含空格,但可能包含除字母和数字之外的可打印字符。最后一行是一个单独的整数 0,表示输入结束。
输出格式
对于每个输入集,在一行内输出解密后的字符串,如示例输出所示。
**本翻译由 AI 自动生成**