CRC32 In Python(与 CRC32b 相比)
CRC32 In Python (vs CRC32b)
我正在尝试生成一些 crc32 哈希,但似乎 zlib
和 binascii
使用 crc32b 算法,即使它们各自的函数只是 zlib.crc32
和 binascii.crc32
.我可以尝试使用其他 python 哈希生成资源吗?有趣的是,我之前发现 R 的 'digest' 包也实现了 crc32b,但没有提到 crc32。
我所说的 CRC32 和 CRC32b 的一些例子:
在这里您可以在下拉列表中看到两者:http://www.md5calc.com/crc32
这里CRC32b在右边:https://hash.online-convert.com/crc32-generator
这是一个以 php 为中心的关于区分的讨论:What is the difference between crc32 and crc32b?
这里我们可以看到python正在实现CRC32b:
谢谢
他们所说的 "crc32" 是 CRC-32/BZIP2 in this catalog。他们所谓的 "crc32b" 是 PKZip CRC-32 (ITU V.42),通常简称为 CRC-32,因为它在该目录中。 "crc32" 和 "crc32b" 的这种使用显然是 PHP 作者发明的符号。
您可以在 PHP documentation page for hash()
上找到一组示例哈希。那里计算了字符串 "hello" 的哈希值,并且可以根据实现进行检查。我链接的目录使用“123456789”进行检查。
您可以自己轻松计算出BZIP2 CRC。下面是一些 C 代码作为示例:
uint32_t crc32bzip2(uint32_t crc, void const *mem, size_t len) {
unsigned char const *data = mem;
if (data == NULL)
return 0;
crc = ~crc;
while (len--) {
crc ^= (unsigned)(*data++) << 24;
for (unsigned k = 0; k < 8; k++)
crc = crc & 0x80000000 ? (crc << 1) ^ 0x4c11db7 : crc << 1;
}
crc = ~crc;
return crc;
}
如果您使用 NULL
调用数据指针,它将 return CRC 的初始值,在本例中为零。然后你可以用当前的 CRC 和字节来调用它来更新 CRC,它会 return 结果 CRC。
A Python 版本计算来自标准输入的字节的 CRC-32/BZIP2:
#!/usr/local/bin/python3
import sys
a = bytearray(sys.stdin.buffer.read())
crc = 0xffffffff
for x in a:
crc ^= x << 24;
for k in range(8):
crc = (crc << 1) ^ 0x04c11db7 if crc & 0x80000000 else crc << 1
crc = ~crc
crc &= 0xffffffff
print(hex(crc))
如果需要,crcany 将生成更高效的基于 table 的版本(在 C 中)。
我对Mark Adler的答案做了一些改进,将数据拆分成分区后快了20+倍,但我不知道为什么。
#!/usr/local/bin/python3
import random
import timeit
def crc32_bzip2(data, precrc=None, bs=None):
def crc32_bzip2_block(data, precrc=None):
crc = 0xFFFFFFFF if precrc is None else (precrc ^ 0xFFFFFFFF)
for x in data:
crc ^= x << 24
for k in range(8):
if crc & 0x80000000:
crc = (crc << 1) ^ 0x04C11DB7
else:
crc = crc << 1
crc = ~crc
crc &= 0xFFFFFFFF
return crc
crc = None
bs = bs if bs else len(data)
blocks = [data[i:i+bs] for i in range(0, len(data), bs)]
for b in blocks:
crc = crc32_bzip2_block(b, crc)
return crc
# testing
bs = 512
datasize = 1024 * 50
data = bytearray(random.getrandbits(8) for _ in range(datasize))
number = 1
setup = 'from __main__ import crc32_bzip2, data, bs'
a = timeit.timeit('crc32_bzip2(data)', setup=setup, number=number)
b = timeit.timeit('crc32_bzip2(data, bs=bs)', setup=setup, number=number)
print(f'{a:.3}', f'{b:.3}', f'{a/b:.3}', sep='\t')
# 3.66 0.127 28.8, on the environment:
# Intel i5-6300U CPU notebook
# Python 3.6.6 64bit
# Windows 7 SP1 64bit
我正在尝试生成一些 crc32 哈希,但似乎 zlib
和 binascii
使用 crc32b 算法,即使它们各自的函数只是 zlib.crc32
和 binascii.crc32
.我可以尝试使用其他 python 哈希生成资源吗?有趣的是,我之前发现 R 的 'digest' 包也实现了 crc32b,但没有提到 crc32。
我所说的 CRC32 和 CRC32b 的一些例子:
在这里您可以在下拉列表中看到两者:http://www.md5calc.com/crc32
这里CRC32b在右边:https://hash.online-convert.com/crc32-generator
这是一个以 php 为中心的关于区分的讨论:What is the difference between crc32 and crc32b?
这里我们可以看到python正在实现CRC32b:
谢谢
他们所说的 "crc32" 是 CRC-32/BZIP2 in this catalog。他们所谓的 "crc32b" 是 PKZip CRC-32 (ITU V.42),通常简称为 CRC-32,因为它在该目录中。 "crc32" 和 "crc32b" 的这种使用显然是 PHP 作者发明的符号。
您可以在 PHP documentation page for hash()
上找到一组示例哈希。那里计算了字符串 "hello" 的哈希值,并且可以根据实现进行检查。我链接的目录使用“123456789”进行检查。
您可以自己轻松计算出BZIP2 CRC。下面是一些 C 代码作为示例:
uint32_t crc32bzip2(uint32_t crc, void const *mem, size_t len) {
unsigned char const *data = mem;
if (data == NULL)
return 0;
crc = ~crc;
while (len--) {
crc ^= (unsigned)(*data++) << 24;
for (unsigned k = 0; k < 8; k++)
crc = crc & 0x80000000 ? (crc << 1) ^ 0x4c11db7 : crc << 1;
}
crc = ~crc;
return crc;
}
如果您使用 NULL
调用数据指针,它将 return CRC 的初始值,在本例中为零。然后你可以用当前的 CRC 和字节来调用它来更新 CRC,它会 return 结果 CRC。
A Python 版本计算来自标准输入的字节的 CRC-32/BZIP2:
#!/usr/local/bin/python3
import sys
a = bytearray(sys.stdin.buffer.read())
crc = 0xffffffff
for x in a:
crc ^= x << 24;
for k in range(8):
crc = (crc << 1) ^ 0x04c11db7 if crc & 0x80000000 else crc << 1
crc = ~crc
crc &= 0xffffffff
print(hex(crc))
如果需要,crcany 将生成更高效的基于 table 的版本(在 C 中)。
我对Mark Adler的答案做了一些改进,将数据拆分成分区后快了20+倍,但我不知道为什么。
#!/usr/local/bin/python3
import random
import timeit
def crc32_bzip2(data, precrc=None, bs=None):
def crc32_bzip2_block(data, precrc=None):
crc = 0xFFFFFFFF if precrc is None else (precrc ^ 0xFFFFFFFF)
for x in data:
crc ^= x << 24
for k in range(8):
if crc & 0x80000000:
crc = (crc << 1) ^ 0x04C11DB7
else:
crc = crc << 1
crc = ~crc
crc &= 0xFFFFFFFF
return crc
crc = None
bs = bs if bs else len(data)
blocks = [data[i:i+bs] for i in range(0, len(data), bs)]
for b in blocks:
crc = crc32_bzip2_block(b, crc)
return crc
# testing
bs = 512
datasize = 1024 * 50
data = bytearray(random.getrandbits(8) for _ in range(datasize))
number = 1
setup = 'from __main__ import crc32_bzip2, data, bs'
a = timeit.timeit('crc32_bzip2(data)', setup=setup, number=number)
b = timeit.timeit('crc32_bzip2(data, bs=bs)', setup=setup, number=number)
print(f'{a:.3}', f'{b:.3}', f'{a/b:.3}', sep='\t')
# 3.66 0.127 28.8, on the environment:
# Intel i5-6300U CPU notebook
# Python 3.6.6 64bit
# Windows 7 SP1 64bit