ctypes - Using zlib crc32_combine in Python -


i trying use crc32_combine function zlib in python. although various other zlib functions available, 1 isn't part of "batteries included" standard library. i've tried 2 approaches: port c code python , calling zlib python ctypes. both give me different results, although not result i'm expecting. i'm presenting ctypes code since think executes faster , has smaller chance additional programmer errors.

the algorithm can combine 2 crc32 hashes when length of data of second hash provided. crc32_combine defined follows:

crc32(crc32(0, seq1, len1), seq2, len2) == crc32_combine(     crc32(0, seq1, len1), crc32(0, seq2, len2), len2) 

this output:

expected crc: 45e57586 combined crc: 567ee4e4 

the second line different when ran python 3.5.1 on win32. not python 2, result never expect either. put zlib1.dll in same directory script try out.

import zlib  def crc32_combine_ctypes(crc1, crc2, len2):     import ctypes     ctypes import util      lib = util.find_library('zlib1')     _zlib = ctypes.cdll(lib)     assert _zlib._name, "can't find zlib"      _zlib.crc32_combine.argtypes = [         ctypes.c_ulong, ctypes.c_ulong, ctypes.c_ulong]     _zlib.crc32_combine.restype = ctypes.c_ulong      return _zlib.crc32_combine(crc1, crc2, len2)  testfile = "zlib1.dll"  open(testfile, "rb") tf:     data = tf.read()  print("expected crc: %0.8x" % (zlib.crc32(data) & 0xffffffff))  cut = len(data) // 2 - 100 p1 = data[0:cut] p2 = data[cut:]  crc1 = zlib.crc32(p1) crc2 = zlib.crc32(p2) len1 = len(p1) len2 = len(p2)  combined = crc32_combine_ctypes(crc1, crc2, len2) print("combined crc: %0.8x" % (combined & 0xffffffff)) 

what doing wrong?

eryksun had right idea: used bad , old dll.

my port pure python code couple hundred times slower calling library ctypes. (numbers using timeit 1k iterations , 50m length parameter)

31.729 (function provided below)  0.120 (just _zlib.crc32_combine() call: no library loading included) 

the pure python code:

def crc32_combine(crc1, crc2, len2):     """explanation algorithm: https://stackoverflow.com/a/23126768/654160     crc32(crc32(0, seq1, len1), seq2, len2) == crc32_combine(         crc32(0, seq1, len1), crc32(0, seq2, len2), len2)"""     # degenerate case (also disallow negative lengths)     if len2 <= 0:         return crc1      # put operator 1 0 bit in odd     # crc-32 polynomial, 1, 2, 4, 8, ..., 1073741824     odd = [0xedb88320] + [1 << in range(0, 31)]     = [0] * 32      def matrix_times(matrix, vector):         number_sum = 0         matrix_index = 0         while vector != 0:             if vector & 1:                 number_sum ^= matrix[matrix_index]             vector = vector >> 1 & 0x7fffffff             matrix_index += 1         return number_sum      # put operator 2 0 bits in - gf2_matrix_square(even, odd)     even[:] = [matrix_times(odd, odd[n]) n in range(0, 32)]      # put operator 4 0 bits in odd     odd[:] = [matrix_times(even, even[n]) n in range(0, 32)]      # apply len2 zeros crc1 (first square put operator 1     # 0 byte, 8 0 bits, in even)     while len2 != 0:         # apply zeros operator bit of len2         even[:] = [matrix_times(odd, odd[n]) n in range(0, 32)]         if len2 & 1:             crc1 = matrix_times(even, crc1)         len2 >>= 1          # if no more bits set, done         if len2 == 0:             break          # iteration of loop odd , swapped         odd[:] = [matrix_times(even, even[n]) n in range(0, 32)]         if len2 & 1:             crc1 = matrix_times(odd, crc1)         len2 >>= 1          # if no more bits set, done     # return combined crc     crc1 ^= crc2     return crc1 

Comments

Popular posts from this blog

javascript - jQuery: Add class depending on URL in the best way -

caching - How to check if a url path exists in the service worker cache -

Redirect to a HTTPS version using .htaccess -