Bottleneck: easy obscurity "encryption" via xor
Oren Tirosh
oren-py-l at hishome.net
Wed Jul 30 05:57:28 EDT 2003
On Wed, Jul 30, 2003 at 12:03:06AM +0200, Tino Lange wrote:
> Hi!
>
> I identified a bottleneck in my programs.
>
> I just want to "encrypt" data by easy xoring. Ok - that's no
> encryption at all - I know. But it's hardly readable - and that's
> enough :-) Just some quick obscurity.
>
> It turns out not to be quick at all. I really didn't expect this to be
> a bottleneck, but it takes quite some time.
If you want higher performance always try to use things that operate
on larger chunks. When you do things byte-by-byte you start to notice the
fact that Python is really an interpreter.
As noted by Bengt Richter xoring with a constant value can be done by
str.translate. It doesn't work for variable values, though.
This code does around 250kb/second on a Pentium 800. XORing is done 32
bits at a time. Conversion to and from character strings is done in even
larger chunks using the array module instead of using ord() and chr().
Oren
from __future__ import generators
import sha
def xor_stream_to_arrays(fin, seed, hashfunc=sha):
""" fin is a file-like object.
yields arrays that may be written to a stream """
from array import array
h = hashfunc.new(seed)
maskchunk = h.digest()
chunksize = len(maskchunk)
while True:
datachunk = fin.read(chunksize)
if len(datachunk) < chunksize:
break
yield array('l', [x^y for (x,y) in zip(
array('l', maskchunk),
array('l', datachunk))])
h.update('x')
maskchunk = h.digest()
maskchunk = maskchunk[:len(datachunk)] # trim to length of remainder
# do the rest by bytes:
yield array('b', [x^y for (x,y) in zip(
array('b', maskchunk),
array('b', datachunk))])
def xor_stream_to_stream(fin, fout, seed):
""" fin, fout are file-like objects """
for a in xor_stream_to_arrays(fin, seed):
fout.write(buffer(a))
def xor_string_to_string(s, seed):
""" gets a string, returns a string """
from cStringIO import StringIO
fin = StringIO(s)
fout = StringIO()
xor_stream_to_stream(fin, fout, seed)
return fout.getvalue()
More information about the Python-list
mailing list