前幾天聽一個學長描述了一下他作的幾道頭條筆試題,本身空閒時間選了一道簡單的嘗試作了作,因爲沒有通過校驗,答案能對多少,本身也沒數,所以讀者就當看個樂子,答案是當不得真的。編碼
兩我的經過加密通訊的方式進行通訊,每條信息都被編譯成二進制數B(明文),其長度爲N。信息被寫下K次,每次向右移動0,1,……,k-1位。加密
B=1001010, K=4
1001010
1001010
1001010
1001010
而後對每一列進行異或操做,結果稱爲S(密文)
上面的結果就爲spa
1110100110
要求是寫一個程序去實現這種編碼的解密過程code
第一行兩個整數N和K
第二行一個二進制字符串S, 長度爲N+K-1
輸出明文Bblog
首先要明白異或運算是幹嗎的ip
異或運算:兩個數相等就置0,不等就置1。
因此能夠當作參與運算的1的數量是單數仍是偶數字符串
再次能夠知道B的長度爲Nit
而後很明顯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
位答案時:class
若是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; }