Fastest bitwise xor between two multibyte binary data variables

后端 未结 7 1856
耶瑟儿~
耶瑟儿~ 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:33

    Disclaimer:As other posters have said, this is a really bad way to encrypt files. This article demonstrates how to reverse this kind of obfuscation trivially.

    first, a simple xor algorithm:

    def xor(a,b,_xor8k=lambda a,b:struct.pack("!1000Q",*map(operator.xor,
                        struct.unpack("!1000Q",a),
                        struct.unpack("!1000Q",b)))
            ):
        if len(a)<=8000:
            s="!%iQ%iB"%divmod(len(a),8)
            return struct.pack(s,*map(operator.xor,
                struct.unpack(s,a),
                struct.unpack(s,b)))
        a=bytearray(a)
        for i in range(8000,len(a),8000):
            a[i-8000:i]=_xor8k(
                a[i-8000:i],
                b[i-8000:i])
        a[i:]=xor(a[i:],b[i:])
        return str(a)
    

    secondly the wrapping xor algorithm:

    def xor_wrap(data,key,_struct8k=struct.Struct("!1000Q")):
        l=len(key)
        if len(data)>=8000:
            keyrpt=key*((7999+2*l)//l)#this buffer is accessed with whatever offset is required for a given 8k block
            #this expression should create at most 1 more copy of the key than is needed
            data=bytearray(data)
            offset=-8000#initial offset, set to zero on first loop iteration
            modulo=0#offset used to access the repeated key
            for offset in range(0,len(data)-7999,8000):
                _struct8k.pack_into(data,offset,*map(operator.xor,
                    _struct8k.unpack_from(data,offset),
                    _struct8k.unpack_from(keyrpt,modulo)))
                modulo+=8000;modulo%=l
            offset+=8000
        else:offset=0;keyrpt=key*(len(data)//l+1)#simple calculation guaranteed to be enough
        rest=len(data)-offset
        srest=struct.Struct("!%iQ%iB"%divmod(len(data)-offset,8))
        srest.pack_into(data,offset,*map(operator.xor,
            srest.unpack_from(data,offset),
            srest.unpack_from(keyrpt,modulo)))
        return data
    

提交回复
热议问题