CRC32 C++使用布尔数组和手动逐位异或实现

CRC32 C++ implementation using bool array and manually XORing bit by bit

本文关键字:位异或 实现 数组 C++ 布尔 CRC32      更新时间:2023-10-16

我在理解CRC32应该如何以正常方式工作方面有问题。
我已经从维基和其他站点实现了机制:https://en.wikipedia.org/wiki/Cyclic_redundancy_check#Computation 你一点一点地xor元素.
对于CRC32,我使用了来自wiki的多项式,它也无处不在:

x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1
with binary representation: 1 0000 0100 1100 0001 0001 1101 1011 0111

我正在为输入字符串"1234"计算 CRC32 仅用于测试。 这是程序的输出:
https://i.stack.imgur.com/tG4wk.png
如您所见,异或计算正确,CRC32为"619119D1"。
当我使用在线计算器甚至 c++ boost lib 计算它时,答案是"9BE3E0A3"。
正常的逐位异或输入字符串有什么问题?我应该在最后添加一些东西还是什么? 我不想使用库和任何其他魔术代码来计算它,因为我必须在我的研究项目中以这种方式实现它。 我也尝试过没有 x^32 的多项式,最后否定位,从 1s 而不是 0 开始(你必须添加 32 个零(,答案也不同。我不知道我现在应该怎么做来解决这个问题。 这是代码的一部分(有点改变(,我有 buffor 3part * 32 位,我从文件加载 4 个字符到中间部分,从开始到中间加载 xor,最后我 xor 中间部分和结尾 ->结尾是 CRC32。

My pseudo schema:
1) Load 8 chars
2) | First part | Middle Part | CRC32 = 0 |
3) XOR
4) | 0 0 0 0 | XXXXXXX | 0 0 0 0 |
5) memcpy - middle part to first part
6) | XXXXXXX | XXXXXXX | 0 0 0 0  |
7) Load 4 chars
8) | XXXXXXX | loaded 4chars | 0 0 0 0 |
9) repeat from point 4 to the end of file
10) now we have: | 0 0 0 0 | XXXXXX | 0 0 0 0 |
11) last xor from middle part to end
12) Result: | 0 0 0 0 |  0 0 0 0 | CRC32 |

可能带有输出的屏幕会更有帮助。
我稍后将使用智能指针等 ;)

bool xorBuffer(unsigned char *buffer) {
bool * binaryTab = nullptr;
try {
// CRC-32
// 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
//  1  0  0  0  0  0  1  0  0  1  1  0  0  0  0  0  1  0  0  0  1  1  1  0  1  1  0  1  1  0  1  1  1
const int dividerSizeBits = 33;
const bool binaryDivider[dividerSizeBits] = { 1,0,0,0,0,0,1,0,0,1,1,0,0,0,0,0,1,0,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1 };
const int dividerLength = countLength(binaryDivider, dividerSizeBits);
const int dividerOffset = dividerSizeBits - dividerLength;  // when divider < 33 bits
bool * binaryTab = charTabToBits(buffer);
// check tab if first part = 0
while (!checkTabIfEmpty(binaryTab)) {
// set the beginnning
int start = 0;
for (start = 0; start < 32; start++)
if (binaryTab[start] == true)
break;
for (int i = 0; i < dividerLength; i++)
binaryTab[i + start] = binaryTab[i + start] ^ binaryDivider[i + dividerOffset];    
}
// binaryTab -> charTab
convertBinaryTabToCharTab(binaryTab, buffer);
}
catch (exception e) {
delete[] binaryTab;
return false;
}
delete[] binaryTab;
return true;
}
std::string CRC::countCRC(std::string fileName){
// create variables
int bufferOnePartSize = 4;
int bufferSize = bufferOnePartSize * 3;
bool EOFFlag = false;
unsigned char *buffer = new unsigned char[bufferSize];
for (int i = 0; i < 3 * bufferOnePartSize; i++)
buffer[i] = 0;
// open file
ifstream fin;
fin.open(fileName.c_str(), ios_base::in | ios_base::binary);
int position = 0;
int count = 0;
// while -> EOF
if (fin.is_open()) {
// TODO check if file <= 4 -> another solution
char ch;
int multiply = 2;
bool skipNormalXor = false;
while (true) {
count = 0;
if (multiply == 2)
position = 0;
else
position = bufferOnePartSize;
// copy part form file to tab
while (count < bufferOnePartSize * multiply && fin.get(ch)) {
buffer[position] = (unsigned char)ch;
++count;
++position;
}
cout << endl;
// if EOF write zeros to end of tab
if (count == 0) {
cout << "TODO: end of file" << endl;
EOFFlag = true;
skipNormalXor = true;
}
else if (count != bufferOnePartSize * multiply) {
for (int i = count; i < bufferOnePartSize * multiply; i++) {
buffer[position] = 0;
position++;
}
EOFFlag = true;
}
if (!skipNormalXor) {
// -- first part
multiply = 1;
// xor the buffer
xorBuffer(buffer);
}
if (EOFFlag) {  // xor to the end
xorBuffer(buffer + bufferOnePartSize);
break;
}
else {
// copy memory
for (int i = 0; i < bufferOnePartSize; i++)
buffer[i] = buffer[i + bufferOnePartSize];
}
}
cout << "n Endn";
fin.close();
}
stringstream crcSum;
for (int i = 2 * bufferOnePartSize; i < bufferSize; i++) {
//buffer[i] = ~buffer[i];
crcSum << std::hex << (unsigned int)buffer[i];
}
cout << endl << "CRC: " << crcSum.str() << endl;
delete[] buffer;
return crcSum.str();
}

CRC 不仅仅由多项式定义。您需要定义位排序、CRC 寄存器的初始值和 CRC 的最终独占或。对于给出"1234"0x9be3e0a3的标准CRC-32,从最低有效位开始处理位,寄存器的初始值为0xffffffff,并且您排除或最终结果与0xffffffff