简易校验和(checksum)算法
in Algorithm Pageviews
校验和(checksum)常用在验证一段网络报文或一个文件是否被篡改。假如网络报文每个字节用2位十六进制数字表达,某种校验和的计算规则如下:
- 若待校验内容的字节长度不是 4 的倍数,则在尾部使用值为 0xFF 的字节补齐为4的倍数(最多补充3个字节)。
- 假设补齐后的字节长度除以 4,得到一个正整数 n
- 若 n 等于 1,内容就是校验和
- 若 n 大于 1,首先取开头 4 个字节,与第 5-8 字节进行异或运算,然后运算结果与随后的 4 个字节继续进行异或运算,直至结束,最后的结果即为校验和。
现在给定一段网络报文,请计算并输出校验和。
输入
十六进制字符串表示的,合法的网络报文,每 2 个字符(输入仅为[0-9A-F])表示一个字节,字符串不存在空格,长度范围: [2, 200]
输出
十六进制字符串形式的校验和,格式如0000000A
,固定8个字符,不足时使用前导0补充;
字母使用大写字母(A-F)来表示;
样例1
输入:
61626364323031324C6162
输出:
1F3330A9
样例2
输入:
687561776569
输出:
0D1C9E88
代码实现如下:
#include <bits/stdc++.h>
using namespace std;
class Solutiond {
public:
string SimpleCheckSum(const string &inputStr)
{
string input = inputStr;
int u = (input.size() / 2) % 4;
while ((u != 0) && (4 - u)) {
input += "FF";
u++;
}
int n = input.size() / 2 / 4;
if (n == 1) {
return input;
}
string str = input.substr(0, 8);
int xor = stoi(str, nullptr, 16);
for (size_t i = 8; i < input.size(); i += 8) {
str = input.substr(i, 8);
xor ^= stoi(str, nullptr, 16);
}
stringstream ss;
ss << setfill('0') << setw(8) << hex << xor;
string res;
ss >> res;
return res;
}
};