[Python] xor: cosi' lento?

michele a nectarine.it michele a nectarine.it
Mer 15 Ott 2008 13:15:38 CEST


Ciao,
ho scritto un semplice encoder in Python che deve effettuare dei  
semplici xor tra blocchi di dati (non mi soffermo sul procedimento, la  
questione  un'altra).
Il problema  che lo xor deve essere fatto su byte di dati, e quindi  
del tipo str; xor non  supportato per str, quindi devo scorrere la  
stringa tramite un ciclo, leggere il carattere corrispondente,  
trasformarlo in intero con ord(), fare lo xor, ritrasformare l'intero  
in carattere e poi metterlo nella stringa.
Suppongo che le operazioni che ho descritto nell'ultimo paragrafo  
siano quelle per cui impiego pi tempo: infatti, su una macchina  
abbastanza recente (dual core 3.0Ghz), l'esecuzione del metodo  
create_random_block impiega ben 0.5s:

took 48.9989998341s, avg: 0.489989998341s

Ovviamente non sono a conoscenza di un altro modo per effettuare lo  
xor tra byte di dati, ma mi sembra che il tempo richiesto per le  
operazioni sia effettivamente troppo alto (perfino java  pi veloce).

Secondo voi come potrei risolvere?
In coda trovate il mio codice completo.

Grazie


from __future__ import division
import random
import time
import sha
import os

class Encoder(object):
	def create_random_block(self, data, seed, blocksize):
		number_of_blocks = int(len(data)/blocksize)
		random.seed(seed)
		random_block = ['0'] * blocksize
		for index in range(number_of_blocks):
			if int(random.getrandbits(1)) == 1:
				block = data[blocksize*index:blocksize*index+blocksize]
				for bit in range(len(block)):
					random_block[bit] = chr(ord(random_block[bit])^ord(block[bit])) #  
workaround per fare xor bit a bit di str; xor e' solo supportato per  
int -> ord
		return ''.join(random_block)


x = Encoder()
piece = os.urandom(1024*1024)
blocksize = 16384
t1 = time.time()
for l in range(100):
	seed = random.getrandbits(32)
	block = x.create_random_block(piece, seed, blocksize)
t2 = time.time()
print 'took ' + str(t2-t1) + 's, avg: ' + str((t2-t1)/100.0) + 's'




Maggiori informazioni sulla lista Python