前几天听一个学长描述了一下他做的几道头条笔试题,自己空闲时间选了一道简单的尝试做了做,由于没有经过校验,答案能对多少,自己也没数,因此读者就当看个乐子,答案是当不得真的。
题目描述
两个人通过加密通信的方式进行通信,每条信息都被编译成二进制数B(明文),其长度为N。信息被写下K次,每次向右移动0,1,……,k-1位。
例如
B=1001010, K=4
1001010
1001010
1001010
1001010
然后对每一列进行异或操作,结果称为S(密文)
上面的结果就为
1110100110
要求是写一个程序去实现这种编码的解密过程
输入
第一行两个整数N和K
第二行一个二进制字符串S, 长度为N+K-1
输出
输出明文B
解题思路
首先要明白异或运算是干嘛的
异或运算:两个数相等就置0,不等就置1。
所以可以看成参与运算的1的数量是单数还是偶数
再次可以知道B的长度为N
然后很明显B的第一位和最后一位就等于S的第一位和最后一位。
private static byte[] decrypt(int N, int K, byte[] S) {
byte[] answer = new byte[N];
answer[0] = S[0];
answer[N - 1] = S[S.length - 1];
}
可以看出 计算部分要分为两种情况,计算第i
位答案时:
如果i < k
就需要和前面k - i
个答案进行运算
如果i >= k
就需要和前面k
个答案进行运算
解码的完整代码如下
private static byte[] decrypt(int N, int K, byte[] S) {
byte[] answer = new byte[N];
answer[0] = S[0];
answer[N - 1] = S[S.length - 1];
for (int i = 1; i < N - 1; i++) {
int count = 0;
int temp; // 用于存储循环次数
if (i < K) {
temp = K - i;
// 前K个结束
} else {
temp = K;
}
for (int j = 0; j < temp; j++) {
if (answer[j] == 1)
count++;
}
if (count % 2 == 1) {
if (S[i] == 1) {
answer[i] = 1;
} else {
answer[i] = 0;
}
} else {
if (S[i] == 1) {
answer[i] = 0;
} else {
answer[i] = 1;
}
}
}
return answer;
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。