简易校验和(checksum)算法

solve actually problem!

校验和(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;
    }
};