代码如下:
#include<memory>
#include<iostream>
#include<vector>
#include<functional>
#include<cstring>
class DataBlob{
public:
DataBlob():length_(0) {}
const std::unique_ptr<uint8_t[]> & data() const { return data_; }
size_t length() const { return length_; }
void set_data(std::unique_ptr<uint8_t[]> data) { data_ = std::move(data); }
void set_length(size_t len) { length_ = len; }
private:
std::unique_ptr<uint8_t[]> data_;
size_t length_;
};
class CRC {
public:
CRC();
void setData(std::vector<uint8_t> & vec);
void setDivide(std::vector<uint8_t> & vec);
bool Check();
bool AddFCS();
void print() const;
private:
DataBlob data_;
DataBlob divide_;
};
CRC::CRC()
{
}
void CRC::setData(std::vector<uint8_t> & vec)
{
data_.set_length(vec.size());
data_.set_data(std::unique_ptr<uint8_t []>(new uint8_t[vec.size()]));
uint8_t *data_ptr = data_.data().get();
std::copy(vec.begin(), vec.end(), data_ptr);
}
void CRC::setDivide(std::vector<uint8_t> & vec)
{
divide_.set_length(vec.size());
divide_.set_data(std::unique_ptr<uint8_t []>(new uint8_t[vec.size()]));
uint8_t *data_ptr = divide_.data().get();
std::copy(vec.begin(), vec.end(), data_ptr);
}
bool CRC::Check()
{
if (0 == data_.length() || 0 == divide_.length())
{
return false;
}
uint8_t *data_ptr = data_.data().get();
uint8_t *divide_ptr = divide_.data().get();
size_t data_len = data_.length();
size_t divide_len = divide_.length();
const uint8_t *data_ptr_end = data_ptr + data_len;
//进行CRC计算
while (1)
{
//如果剩余长度小于被除数长度
if (divide_len > data_ptr_end - data_ptr)
{
break;
}
if (0 == *data_ptr) {
//忽略前导0
++data_ptr;
} else {
//模2除法
for (int i=0; i<divide_len; ++i)
{
data_ptr[i] = data_ptr[i] ^ divide_ptr[i];
}
}
}
while (data_ptr_end != data_ptr)
{
//余数不为0,则check失败
if (*data_ptr == 1) return false;
++data_ptr;
}
return true;
}
bool CRC::AddFCS()
{
if (0 == data_.length() || 0 == divide_.length())
{
return false;
}
uint8_t *data_ptr = data_.data().get();
uint8_t *divide_ptr = divide_.data().get();
size_t data_len = data_.length();
size_t divide_len = divide_.length();
//在要发送的数据后面,填补divide_len-1个0,存放FCS
std::unique_ptr<uint8_t []> new_data(new uint8_t[data_len + divide_len - 1]);
memset(new_data.get(), 0, data_len + divide_len - 1);
memcpy(new_data.get(), data_ptr, data_len);
uint8_t * new_data_ptr = new_data.get();
uint8_t * new_data_ptr_end = new_data_ptr + data_len + divide_len -1;
//进行CRC计算
while (1)
{
//如果剩余长度小于被除数长度
if (divide_len > new_data_ptr_end - new_data_ptr)
{
break;
}
if (0 == *new_data_ptr) {
//忽略前导0
++new_data_ptr;
} else {
//模2除法
for (int i=0; i<divide_len; ++i)
{
new_data_ptr[i] = new_data_ptr[i] ^ divide_ptr[i];
}
}
}
//用原数据覆盖前面data_len-1个字节,只保留余数,即FCS
memcpy(new_data.get(), data_ptr, data_len);
data_.set_data(std::move(new_data));
data_.set_length(data_len + divide_len - 1);
return true;
}
void CRC::print() const
{
std::cout<<"data:";
uint8_t *ptr = data_.data().get();
for (int i=0; i<data_.length(); ++i)
{
std::cout<<(int)ptr[i];
}
std::cout<<" divider:";
ptr = divide_.data().get();
for (int i=0; i<divide_.length(); ++i)
{
std::cout<<(int)ptr[i];
}
std::cout<<std::endl;
}
void crc_test_1()
{
CRC crc;
{
std::cout<<"test case 1===========================>\n";
std::vector<uint8_t> data = {1,0,0,1,1,0,1};
std::vector<uint8_t> divide = {1,1,1,1};
crc.setData(data);
crc.setDivide(divide);
crc.print();
if (false == crc.AddFCS())
{
std::cout<<"CRC::AddFCS failed\n";
return;
}
std::cout<<"After add FCS...\n";
crc.print();
if (false == crc.Check())
{
std::cout<<"CRC::Check failed\n";
return;
}
std::cout<<"CRC Check ok.\n";
}
{
std::cout<<"test case 2===========================>\n";
std::vector<uint8_t> data = {1,0,1,0,1,1,0,1,1,1,0,0,1};
std::vector<uint8_t> divide = {1,0,1,0};
crc.setData(data);
crc.setDivide(divide);
crc.print();
if (false == crc.AddFCS())
{
std::cout<<"CRC::AddFCS failed\n";
return;
}
std::cout<<"After add FCS...\n";
crc.print();
if (false == crc.Check())
{
std::cout<<"CRC::Check failed\n";
return;
}
std::cout<<"CRC Check ok.\n";
}
}
int main(int argc, const char** argv)
{
crc_test_1();
return 0;
}
编译:
g++ -o crc crc_test.cc -std=c++14
运行结果:

参考博客:
https://www.cnblogs.com/zpchcbd/p/15931308.htmlCRC码计算及原理(FCS帧校验序列生成)_fcs校验_cggwz的博客-优快云博客
这篇博客介绍了如何使用C++实现CRC码计算,提供了代码示例,并展示了编译和运行结果。文章旨在帮助读者理解CRC码(帧校验序列)的计算及其在数据校验中的应用。
2万+

被折叠的 条评论
为什么被折叠?



