newbie question: any better way to write this code?
Peter Otten
__peter__ at web.de
Wed Dec 27 11:05:59 EST 2006
neoedmund wrote:
> i want to let a byte array to be xor with some value.
> but code show below i wrote seems not so .. good..., any better way to
> write such function? thanks.
> [code]
> def xor(buf):
> bout=[]
> for i in range(len(buf)):
> x = ord(buf[i])
> x ^= 123
> bout.append(chr(x))
> return "".join(buf)
'bout' not 'buf', I think.
A simple improvement: loop over the characters:
def xor2(buf):
#...
for c in buf:
x = ord(c)
#...
If you want to xor always with the same value you can prepare a lookup map
once for every possible input value:
_map = dict((chr(i), chr(i ^ 123)) for i in range(256))
def xor3(buf, _map=_map):
return "".join(_map[c] for c in buf)
However, you still have to loop over the characters of buf in Python. Here's
a way to move that loop (in the generator expression) into the
str.translate() method which is coded in C:
_map = "".join(chr(i^123) for i in range(256))
def xor4(buf):
return buf.translate(_map)
Now let's do some measurements:
$ python2.5 -m timeit -s"from xor import xor; s = 'alpha ' * 10" "xor(s)"
10000 loops, best of 3: 87.9 usec per loop
$ python2.5 -m timeit -s"from xor import xor2; s = 'alpha ' * 10" "xor2(s)"
10000 loops, best of 3: 78.4 usec per loop
$ python2.5 -m timeit -s"from xor import xor3; s = 'alpha ' * 10" "xor3(s)"
10000 loops, best of 3: 38.5 usec per loop
$ python2.5 -m timeit -s"from xor import xor4; s = 'alpha ' * 10" "xor4(s)"
1000000 loops, best of 3: 1.15 usec per loop
But what if you don't know the value to xor with in advance?
def xor5(buf, n=123):
map = "".join(chr(i^123) for i in range(256))
return buf.translate(map)
$ python2.5 -m timeit -s"from xor import xor5; s = 'alpha ' * 10" "xor5(s)"
1000 loops, best of 3: 221 usec per loop
There goes our speed-up. I can think of various ways to remedy that, but if
your input strings are long you might not even care:
$ python2.5 -m timeit -s"from xor import xor2; s = 'alpha ' * 1000" "xor
(s)"
100 loops, best of 3: 7.93 msec per loop
$ python2.5 -m timeit -s"from xor import xor5; s = 'alpha ' * 1000" "xor
(s)"
1000 loops, best of 3: 242 usec per loop
Peter
More information about the Python-list
mailing list