BOOST::CRC 使用 process.block() 方法创建校验和
BOOST::CRC creating checksum with process.block() method
我目前正在尝试在自定义结构 UMGR_s 的长度上创建校验和。我确实使用了 BOOST::crc 方法 process.block() 和我的结构的开始和结束地址。
问题是每次我 运行 这种方法时我都会得到不同的校验和,即使结构中的数据保持一致。我不确定我在这里做错了什么。
int checksum_manager::createCRC(UMGR_s *CRCdata)
{
boost::crc_32_type result;
result.process_block(CRCdata, CRCdata + 1);
return result.checksum();
};
回顾你之前的问题:
#include <string>
#include <type_traits>
struct UMGR_s {
std::string name;
std::string description;
std::string dlt_id;
std::string log_mode;
std::string log_level;
std::string log_dir_path;
uint ipc_port;
uint reconnection_retry_offset;
uint msg_buf_size;
int checksum;
};
static_assert(std::is_standard_layout<UMGR_s>{});
static_assert(not std::is_trivial<UMGR_s>{});
static_assert(not std::is_pod<UMGR_s>{});
这不是 POD。正如您已经注意到的那样,简单地发送位是不可靠的。
将其视为C++对象并编写校验和函数例如:
int calcCRC() {
boost::crc_32_type crc;
crc.process_bytes(name.data(), name.size());
crc.process_bytes(description.data(), description.size());
crc.process_bytes(dlt_id.data(), dlt_id.size());
crc.process_bytes(log_mode.data(), log_mode.size());
crc.process_bytes(log_level.data(), log_level.size());
crc.process_bytes(log_dir_path.data(), log_dir_path.size());
crc.process_block(&ipc_port, &ipc_port+1);
crc.process_block(&reconnection_retry_offset, &reconnection_retry_offset+1);
crc.process_block(&msg_buf_size, &msg_buf_size+1);
return crc.checksum();
}
看到了Live On Coliru.
示例一致 returns 0xbf21e978
,并且没有 UB 或 valgrind/ASAN 警告。
更好的是,减少它 error-prone:
struct CRC {
boost::crc_32_type crc;
void operator()(std::string_view s) {
crc.process_bytes(s.data(), s.size());
}
template <typename T, typename = std::enable_if_t<std::is_integral_v<T>>>
void operator()(T const& i) {
static_assert(std::is_trivial_v<T>);
static_assert(not std::is_class_v<T>);
crc.process_bytes(&i, sizeof(i));
}
auto get() { return crc.checksum(); }
};
这意味着您现在可以“只”写:
int calcCRC() {
CRC crc;
crc(name);
crc(description);
crc(dlt_id);
crc(log_mode);
crc(log_level);
crc(log_dir_path);
crc(ipc_port);
crc(reconnection_retry_offset);
crc(msg_buf_size);
return crc.get();
}
现场演示
#include <string>
#include <iostream>
#include <type_traits>
#include <boost/crc.hpp>
struct CRC {
boost::crc_32_type crc;
void operator()(std::string_view s) {
crc.process_bytes(s.data(), s.size());
}
template <typename T, typename = std::enable_if_t<std::is_integral_v<T>>>
void operator()(T const& i) {
static_assert(std::is_trivial_v<T>);
static_assert(not std::is_class_v<T>);
crc.process_bytes(&i, sizeof(i));
}
auto get() { return crc.checksum(); }
};
struct UMGR_s {
std::string name;
std::string description;
std::string dlt_id;
std::string log_mode;
std::string log_level;
std::string log_dir_path;
uint ipc_port;
uint reconnection_retry_offset;
uint msg_buf_size;
int checksum;
int calcCRC() {
CRC crc;
crc(name);
crc(description);
crc(dlt_id);
crc(log_mode);
crc(log_level);
crc(log_dir_path);
crc(ipc_port);
crc(reconnection_retry_offset);
crc(msg_buf_size);
return crc.get();
}
};
static_assert(std::is_standard_layout<UMGR_s>{});
static_assert(not std::is_trivial<UMGR_s>{});
//static_assert(not std::is_pod<UMGR_s>{});
int main() {
UMGR_s data {
"UMGR",
"UpdateManager",
"1234",
"kConsole",
"kVerbose",
"",
33,
0,
1000,
0,
};
data.checksum = data.calcCRC();
std::cout << "crc: " << std::hex << std::showbase << data.checksum << "\n";
}
观察它仍然打印相同的 CRC:
crc: 0xbf21e978
我目前正在尝试在自定义结构 UMGR_s 的长度上创建校验和。我确实使用了 BOOST::crc 方法 process.block() 和我的结构的开始和结束地址。
问题是每次我 运行 这种方法时我都会得到不同的校验和,即使结构中的数据保持一致。我不确定我在这里做错了什么。
int checksum_manager::createCRC(UMGR_s *CRCdata)
{
boost::crc_32_type result;
result.process_block(CRCdata, CRCdata + 1);
return result.checksum();
};
回顾你之前的问题:
#include <string>
#include <type_traits>
struct UMGR_s {
std::string name;
std::string description;
std::string dlt_id;
std::string log_mode;
std::string log_level;
std::string log_dir_path;
uint ipc_port;
uint reconnection_retry_offset;
uint msg_buf_size;
int checksum;
};
static_assert(std::is_standard_layout<UMGR_s>{});
static_assert(not std::is_trivial<UMGR_s>{});
static_assert(not std::is_pod<UMGR_s>{});
这不是 POD。正如您已经注意到的那样,简单地发送位是不可靠的。
将其视为C++对象并编写校验和函数例如:
int calcCRC() {
boost::crc_32_type crc;
crc.process_bytes(name.data(), name.size());
crc.process_bytes(description.data(), description.size());
crc.process_bytes(dlt_id.data(), dlt_id.size());
crc.process_bytes(log_mode.data(), log_mode.size());
crc.process_bytes(log_level.data(), log_level.size());
crc.process_bytes(log_dir_path.data(), log_dir_path.size());
crc.process_block(&ipc_port, &ipc_port+1);
crc.process_block(&reconnection_retry_offset, &reconnection_retry_offset+1);
crc.process_block(&msg_buf_size, &msg_buf_size+1);
return crc.checksum();
}
看到了Live On Coliru.
示例一致 returns 0xbf21e978
,并且没有 UB 或 valgrind/ASAN 警告。
更好的是,减少它 error-prone:
struct CRC {
boost::crc_32_type crc;
void operator()(std::string_view s) {
crc.process_bytes(s.data(), s.size());
}
template <typename T, typename = std::enable_if_t<std::is_integral_v<T>>>
void operator()(T const& i) {
static_assert(std::is_trivial_v<T>);
static_assert(not std::is_class_v<T>);
crc.process_bytes(&i, sizeof(i));
}
auto get() { return crc.checksum(); }
};
这意味着您现在可以“只”写:
int calcCRC() {
CRC crc;
crc(name);
crc(description);
crc(dlt_id);
crc(log_mode);
crc(log_level);
crc(log_dir_path);
crc(ipc_port);
crc(reconnection_retry_offset);
crc(msg_buf_size);
return crc.get();
}
现场演示
#include <string>
#include <iostream>
#include <type_traits>
#include <boost/crc.hpp>
struct CRC {
boost::crc_32_type crc;
void operator()(std::string_view s) {
crc.process_bytes(s.data(), s.size());
}
template <typename T, typename = std::enable_if_t<std::is_integral_v<T>>>
void operator()(T const& i) {
static_assert(std::is_trivial_v<T>);
static_assert(not std::is_class_v<T>);
crc.process_bytes(&i, sizeof(i));
}
auto get() { return crc.checksum(); }
};
struct UMGR_s {
std::string name;
std::string description;
std::string dlt_id;
std::string log_mode;
std::string log_level;
std::string log_dir_path;
uint ipc_port;
uint reconnection_retry_offset;
uint msg_buf_size;
int checksum;
int calcCRC() {
CRC crc;
crc(name);
crc(description);
crc(dlt_id);
crc(log_mode);
crc(log_level);
crc(log_dir_path);
crc(ipc_port);
crc(reconnection_retry_offset);
crc(msg_buf_size);
return crc.get();
}
};
static_assert(std::is_standard_layout<UMGR_s>{});
static_assert(not std::is_trivial<UMGR_s>{});
//static_assert(not std::is_pod<UMGR_s>{});
int main() {
UMGR_s data {
"UMGR",
"UpdateManager",
"1234",
"kConsole",
"kVerbose",
"",
33,
0,
1000,
0,
};
data.checksum = data.calcCRC();
std::cout << "crc: " << std::hex << std::showbase << data.checksum << "\n";
}
观察它仍然打印相同的 CRC:
crc: 0xbf21e978