Fastest bitwise xor between two multibyte binary data variables

后端 未结 7 1777
耶瑟儿~
耶瑟儿~ 2021-01-02 01:05

What is the fastest way to implementat the following logic:

def xor(data, key):
    l = len(key)

    buff = \"\"
    for i in range(0, len(data)):
        b         


        
7条回答
  •  迷失自我
    2021-01-02 01:23

    This code should work in Python 2.6+ including Py3k.

    from binascii import hexlify as _hexlify
    from binascii import unhexlify as _unhexlify
    
    
    def packl(lnum, padmultiple=0):
        """Packs the lnum (which must be convertable to a long) into a
        byte string 0 padded to a multiple of padmultiple bytes in size. 0
        means no padding whatsoever, so that packing 0 result in an empty
        string.  The resulting byte string is the big-endian two's
        complement representation of the passed in long."""
    
        if lnum == 0:
            return b'\0' * padmultiple
        elif lnum < 0:
            raise ValueError("Can only convert non-negative numbers.")
        s = hex(lnum)[2:]
        s = s.rstrip('L')
        if len(s) & 1:
            s = '0' + s
        s = _unhexlify(s)
        if (padmultiple != 1) and (padmultiple != 0):
            filled_so_far = len(s) % padmultiple
            if filled_so_far != 0:
                s = b'\0' * (padmultiple - filled_so_far) + s
        return s
    
    def unpackl(bytestr):
        """Treats a byte string as a sequence of base 256 digits
        representing an unsigned integer in big-endian format and converts
        that representation into a Python integer."""
    
        return int(_hexlify(bytestr), 16) if len(bytestr) > 0 else 0
    
    def xor(data, key):
        dlen = len(data)
        klen = len(key)
        if dlen > klen:
            key = key * ((dlen + klen - 1) // klen)
        key = key[:dlen]
        result = packl(unpackl(data) ^ unpackl(key))
        if len(result) < dlen:
             result = b'\0' * (dlen - len(result)) + result
        return result
    

    This will also work in Python 2.7 and 3.x. It has the advantage of being a lot simpler than the previous one while doing basically the same thing in approximately the same amount of time:

    from binascii import hexlify as _hexlify
    from binascii import unhexlify as _unhexlify
    
    def xor(data, key):
        dlen = len(data)
        klen = len(key)
        if dlen > klen:
            key = key * ((dlen + klen - 1) // klen)
        key = key[:dlen]
        data = int(_hexlify(data), 16)
        key = int(_hexlify(key), 16)
        result = (data ^ key) | (1 << (dlen * 8 + 7))
        # Python 2.6/2.7 only lines (comment out in Python 3.x)
        result = memoryview(hex(result))
        result = (result[4:-1] if result[-1] == 'L' else result[4:])
        # Python 3.x line
        #result = memoryview(hex(result).encode('ascii'))[4:]
        result = _unhexlify(result)
        return result
    

提交回复
热议问题