抛开性能和安全性考虑,并假设具有完美雪崩效应的散列函数,我应该将其用于校验和数据块:CRC32或散列截断为N个字节?即错过错误的可能性较小?特别:
数据块将通过网络传输并重复存储在磁盘上.块大小可以是1KB到1GB.
据我了解,CRC32可以检测高达32位的翻转,具有100%的可靠性,但在此之后,其可靠性接近1-2^(-32)并且对于某些模式来说更糟糕.总是有一个完美的4字节散列可靠性1-2^(-32),所以请看一下.
8字节散列应该具有更好的整体可靠性(2^(-64)错过错误的机会),所以它应该优先于CRC32吗?CRC64怎么样?
我想答案取决于在这种操作中可能出现的错误类型.我们是否可能会看到稀疏的1位翻转或大量的块损坏?另外,鉴于大多数存储和网络硬件都实现了某种CRC,不应该意外地进行位翻转吗?
"直觉"我指的是
int a = -1;
unsigned int b = 3;
Run Code Online (Sandbox Code Playgroud)
表达式(a < b)应该评估为1.
Stackoverflow上有很多问题已经问到为什么在这个或那个特殊情况下C编译器会抱怨签名/无符号比较.答案归结为整数转换规则等.然而,在比较烧结和无符号整数时,为什么编译器必须如此格外愚蠢似乎没有理由呢?使用上面的声明,为什么表达式喜欢
(a < b)
Run Code Online (Sandbox Code Playgroud)
不会自动替换
(a < 0 || (unsigned int)a < b)
Run Code Online (Sandbox Code Playgroud)
如果没有单机指令正确执行?
现在,对于以前的问题已经有了一些评论,"如果你必须混合有符号和无符号整数,那么你的程序就有问题".我不会买,因为libc本身使得无法生活在仅有符号或无符号的世界中(例如sprintf(),函数系列函数返回int为写入的字节数,send()返回ssize_t等).
我也不认为我可以购买下面评论中表达的一个想法,即将有符号整数隐式转换为无符号((d - '0' < 10U)"成语")赋予C程序员一些额外的权力,而不是显式的 cast(((unsigned int)(d - '0') < 10U)).但可以肯定的是,它打开了大量机会搞砸了.
是的,我很高兴编译器警告我它不能这样做(不幸的是只有我明确地问它).问题是 - 为什么不能呢?通常标准规则背后有很好的理由,所以我想知道这里有没有?