CRC32 和 zip文件的crc 字段
来源:互联网 发布:大连淘宝运营 编辑:程序博客网 时间:2024/05/22 02:28
python中的计算
注意,python 的计算结果是有符号的,如果要转为unsigned 可以和0xffffffff与操作
>>> import zlib>>> import binasciis = b'hello,word!'>>> zlib.crc32(s)3035098857>>> binascii.crc32(s)3035098857>>> zlib.crc32(b"hello") & 0xffffffff907060870
0x04c11db7 和 0xedb88320
Python中用的是后面的
这两个数字其实是相互的二进制形式的反转,具体参考链接2
所以两个数字相对应的table 也是各自的反转(不只是table中每个位置对应的数字要反转,下标也要反转)
相应的两个table 的 实质的计算顺序分辨是,先高位,和先低位
比如要校验的串是\x01\x02
先高位,用0x04c11db7
第一步是把bit0
和初始串(0xffffffff)的高位抑或,也就是 1111 1111 1111 1111 1111 1111 1111 1111
然后因为第一位是1,补0后的后面的16位 和 0x04c11db7 抑或操作
按照上面的步骤16次预算的结果,相当于在0x04c11db7下 计算下面这个串的校验码 1110 1101 1111 1111 1111 1111 1111 1111 0000 0000
从左向右算,计算过程要左移
先低位,用0xedb88320
相当于用0xedb88320计算串 0000 0000 1111 1111 1111 1111 1111 1111 1101 1110
从右向左算,计算过程要右移
下面是生成crc table 和测试的代码:
from zlib import crc32def mycrc(input): x=inverse32(0x04c11db7) init=0xffffffff t=init for i in input: t=t^ord(i) for j in range(8): mask=1 if(mask&t!=0): t=(t>>1)^x else: t=(t>>1) return t^0xffffffffdef inverse8(x): y=0 for i in range(8): y=(y<<1)|(x&1) x=x>>1 return ydef inverse32(x): r=0x00000000 for i in range(32): r=(r<<1)|(x&1) x=x>>1 return rdef creat_table1(): x=0x04c11db7 init=0 l=[0L]*256 for i in range(256): t=init^(i<<24) for j in range(8): mask=1<<31 if(mask&t!=0): t=(t<<1)^x else: t=(t<<1) l[i]=t return ldef creat_table3():#table1 inverse l1=creat_table1() l3=[0L]*256 for i in range(256): j=inverse8(i) l3[j]=inverse32(l1[i]) return l3def creat_table2(): x=inverse32(0x04c11db7) init=0 l=[0]*256 for i in range(256): t=init^i for j in range(8): mask=1 if(mask&t!=0): t=(t>>1)^x else: t=(t>>1) l[i]=t return ldef test(): assert (0==inverse8(0)) assert (0x80==inverse8(1)) assert (0x40==inverse8(2)) assert (0xc0==inverse8(3)) assert (0==inverse32(0)) assert (0x80000000==inverse32(1)) assert (0x40000000==inverse32(2)) assert (0xc0000000==inverse32(3)) l1=creat_table1() l2=creat_table2() l3=creat_table3() assert (l2==l3) for i in range(256): i=chr(i) assert (mycrc(i)&0xffffffff==crc32(i)&0xffffffff) # for i in range(256): # print(bin(i),bin(inverse8(i))) # l=l2 # for i in range(0,256,4): # print(hex((l[i])&0xffffffff),hex((l[i+1])&0xffffffff),hex((l[i+2])&0xffffffff),hex((l[i+3])&0xffffffff))if __name__=="__main__": test()
zip 文件中的校验字段
文件格式参考:
1.格式:https://en.wikipedia.org/wiki/Zip_(file_format)
2.格式文档:https://pkware.cachefly.net/webdocs/APPNOTE/APPNOTE-6.2.0.txt
3.算法和文件格式的汇总:http://www.cnblogs.com/esingchan/p/3958962.html
首先zip中使用的crc32 和python 中的这中是相同的
文档中提到的magic number(0xdebb20e3 ) 应该并不是多项式的表示。
不过串”\x00\x00\x00\x00”crc32后取反刚好是这个数字
>>> hex(crc32("\x00\x00\x00\x00")^0xffffffff&0xffffffff)'0xdebb20e3L'
可能因为英文水平差,看了好久也没有找到crc字段具体是如何计算的,到底是什么内容的crc32,然后把zip文件的头,整体,都crc了一下,结果还是对不上。。。(好像网络协议中的crc是有包含package头的,然后就被误导了)
卡了两天后发现,这个crc是压缩前文件的crc。。。如果只有一个文件,那么local header 和central header 中的crc 是一样的。
一个例子,
这个zip文件是test.txt的压缩,第二行末尾和第三行开始可以看出文件名。text.txt 的内容是
abcd
就是第三行文件名和central header标识中间的部分
蓝色分别是local header 和 central header的标识,红色是两个部分的crc abcd
的CRC刚好就是红框中的数字,只不过差个大端小端,你懂的
>>> hex(crc32("abcd")&0xffffffff)'0xed82cd11L'
参考
0.
http://www.cnblogs.com/darkpig/p/5676076.html
1.crc table
http://blog.csdn.net/joeblackzqq/article/details/37910839
2.详细计算
http://blog.csdn.net/sparkliang/article/details/5671510
- CRC32 和 zip文件的crc 字段
- 我学习CRC32、CRC16、CRC原理和算法的总结(与WINRAR结果一致)
- 我学习CRC32、CRC16、CRC原理和算法的总结(与WINRAR结果一致)
- C语言获取文件CRC32算法附加CRC原理(转)
- CRC-32(crc32)算法
- Qt:计算CRC校验值(CRC16和CRC32)
- 获取文件的CRC32值
- crc32的用法和感触
- 压缩zip文件和解压zip格式的文件
- 写着玩的zip解压和压缩zip文件
- 获取文件CRC和MD5
- 获取文件CRC和MD5
- java.util.zip.CRC32翻译
- 计算一个文件的CRC32值
- JAVA计算文件的crc32校验码
- .Net 获取文件的CRC32标识
- java 生成文件的 CRC32校验码
- 对M4芯片的CRC模块改造来计算标准CRC32
- 【Unity编程】 Unity界面概览
- 16 3sum closest
- Windows安装TensorFlow
- CentOS 7安装与配置JDK8
- 解决winfrom下TextBox不支持透明背景色
- CRC32 和 zip文件的crc 字段
- 监督学习-支持向量机模板
- [LeetCode] 417. Pacific Atlantic Water Flow 解题报告
- C语言const与指针
- '\n' 与'\r'
- 短小精悍的HTML模板引擎
- Java 输入流读取文本文件换行符问题
- spring 注入静态工具类
- 使用 XMLHttpRequest 实现 Ajax