#include <vector>
using namespace std;
// 选手不需要实现该函数,这里仅作声明以供调用
vector<bool> send_packet(vector<bool> A);
// Aisha 的发送策略
void send_message(vector<bool> M, vector<bool> C) {
// 阶段一:用 31 个数据包,绝对安全地将数组 C 传给 Basma
for (int i = 0; i < 31; i++) {
vector<bool> A(31, C[i]);
send_packet(A);
}
// 阶段二:传输消息长度 S 以及消息内容 M
int S = M.size();
vector<bool> data;
// 用 11 个比特编码长度 S (1024 需要 11 位)
for (int i = 0; i < 11; i++) {
data.push_back((S >> i) & 1);
}
// 放入实际的消息 M
for (int i = 0; i < S; i++) {
data.push_back(M[i]);
}
// 补齐到 16 的倍数,方便每次发送 16 个比特
while (data.size() % 16 != 0) {
data.push_back(0);
}
// 找出 16 个安全的列 (C[i] == 0 代表安全)
vector<int> safe_cols;
for (int i = 0; i < 31; i++) {
if (!C[i]) {
safe_cols.push_back(i);
}
}
// 每次拿出 16 个比特发出去
for (size_t i = 0; i < data.size(); i += 16) {
vector<bool> A(31, 0); // 被篡改的位置填 0,无所谓
for (int j = 0; j < 16; j++) {
A[safe_cols[j]] = data[i + j];
}
send_packet(A);
}
}
// Basma 的接收策略
vector<bool> receive_message(vector<vector<bool>> R) {
vector<bool> C(31);
// 阶段一:从前 31 个数据包中恢复掩码 C
for (int i = 0; i < 31; i++) {
int count = 0;
for (int j = 0; j < 31; j++) {
if (R[i][j]) count++;
}
// 如果 1 的个数 >= 16,则说明原本发出的就是 1 (因为安全位有 16 个)
C[i] = (count >= 16);
}
// 找出安全的 16 个位置
vector<int> safe_cols;
for (int i = 0; i < 31; i++) {
if (!C[i]) {
safe_cols.push_back(i);
}
}
// 阶段二:从后续的数据包里在安全位置上提取比特
vector<bool> data;
for (size_t p = 31; p < R.size(); p++) {
for (int j = 0; j < 16; j++) {
data.push_back(R[p][safe_cols[j]]);
}
}
// 读取前 11 个比特来还原消息长度 S
int S = 0;
for (int i = 0; i < 11; i++) {
if (data[i]) {
S |= (1 << i);
}
}
// 根据还原出的长度 S,截取实际的消息 M
vector<bool> M(S);
for (int i = 0; i < S; i++) {
M[i] = data[11 + i];
}
return M;
}