POSIX cksum and Boost.CRC
POSIX cksum and Boost.CRC
我正在尝试使用Boost.CRC实现简单的POSIX cksum
。
我使用的代码相当于:
for(int i = 1; i<argc; ++i)
{
support::file current(argv[i], support::file::access::read);
size_t octets = 0;
boost::crc_32_type crc;
while(true)
{
size_t bytes_read = current.read_some(buffer_size, buffer);
octets += bytes_read;
crc.process_bytes(&buffer[0], bytes_read);
if(bytes_read < buffer_size)
break;
}
if(i>1)
support::print("n");
support::print(boost::lexical_cast<string>(crc.checksum()) + " " + boost::lexical_cast<string>(octets) + " " + argv[i]);
}
其中support::file
是一个简单的fopen
/fread
二进制文件I/O包装器,我成功地用于cat
实现。support::print
给出与std::cout
相同的输出,但我需要它在Windows上可靠的非ascii输出。
Boost头有这个:
typedef crc_optimal<32, 0x04C11DB7, 0xFFFFFFFF, 0xFFFFFFFF, true, true> crc_32_type;
作为唯一的32位CRC类型定义。对于一个空文件(touch test && cksum test
),它给出了错误的答案(用GNUWin32 coretils cksum
检查)。我已经尝试使用上面的typedef并将0xFFFFFFFF
值中的一个或两个修改为0,我得到了空文件的正确结果,但任何其他文件仍然给出了不同的结果。
如何提高。与POSIX cksum
规范相关的CRC ?
这不是你问题的答案,而是我进行的调查的结果。当我在VHDL中构建以太网控制器的简单实现时,我曾经与CRC作斗争,并且我做意识到实现有时可能由于未知的原因而变化很大。
好的,我们开始吧。您在boost/crc.hpp
中找到的typedef
:
typedef crc_optimal<32, 0x04C11DB7, 0xFFFFFFFF, 0xFFFFFFFF, true, true> crc_32_type;
是一个简单的CRC生成器声明,它将为以太网生成CRC。模板的参数如下:Bits
(由发电机输出的比特数),TruncPoly
(使用的多项式发电机),InitRem
(最初的剩余送入算法在处理之前输入的第一个字节),FinalXor
(输出值的值应该XORed
之后处理所有输入的字节),ReflectIn
和ReflectRem
(如果输入字节和/或输出应该bit-reflected,例如一点一点0变成7,等等)。以太网不仅要求使用给定的多项式计算输出,而且还要求可以从该typedef中读取约束。
根据cksum
的规范,它的CRC生成器的类型定义应该像这样:
typedef crc_optimal<32, 0x04C11DB7, 0, 0xFFFFFFFF, false, false> cksum_crc_type;
这是因为:
- 规范没有指定生成器的起始值,因此为0。
- 输出值应按规范第4条补充。同样的结果也可以通过将值与1相乘来实现。
- 位反射在任何地方都没有提到,因此不会执行。
然而,与普通crc相比,cksum
有一个显著的区别:
(…)后跟一个或多个八位元组,表示字符的长度文件作为二进制值,最低有效位优先。最小的应使用能够表示该整数的八位字节数。
普通的CRC生成器不考虑被处理的字节数。这也解释了为什么在处理零长度文件时会得到好的结果,而在处理较大的文件时会得到不好的结果。
不幸的是,我找不到一个简单的解决方案。我猜你能做的是修改process_bytes
方法在以下方式:
template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
bool ReflectIn, bool ReflectRem >
inline
void
BOOST_CRC_OPTIMAL_NAME::process_bytes
(
void const * buffer,
std::size_t byte_count
)
{
unsigned char const * const b = static_cast<unsigned char const *>(
buffer );
process_block( b, b + byte_count );
for(; byte_count; byte_count >>= 8)
rem_ = (rem_ << 8) ^ crc_table_type::table_[((rem_ >> 24) ^ byte_count) & 0xFF];
}
通过这样的实现,该方法给出了与cksum
相同的结果。for
循环由GNU coretils提供。
希望我帮到你。
- 理解boost::asio-async_read在无需读取内容时的行为
- boost::进程间消息队列引发错误
- 如何运行位于boost/libs/python/example/tutorial目录中的hello.cpp和Jamfil
- cmake如何在fedora工作站中找到boost静态库包
- CMake项目Boost库错误:Boost/config/compiler/gcc.hpp:165:10:致命错误:cs
- Boost Graph Library,修复节点大小
- 什么是"#include <boost/functional/hash.hpp> "?
- 基于boost的程序的静态链接——zlib问题
- C++:如何在CLion IDE中安装Boost
- C++Boost Asio Pool线程,带有lambda函数和传递引用变量
- 如何在boost beast http请求中设置http头
- Boost Spirit,获取迭代器内部语义动作
- boost::asio::steady_timer()与sleep()我应该使用哪一个
- 使用 Boost 计算 ECMA-128 64 位 CRC
- Boost CRC 16 bit
- Boost CRC CCITT输出值不同
- 带有boost::CRC_32_type的CRC结果与java.util.zip.CRC32不同
- C ++ Boost 组合 CRC 校验和
- 编译器警告在boost crc.hpp与Visual c++(错误C4244)
- POSIX cksum and Boost.CRC