# Copyright (c) 2002 Bryce "Zooko" Wilcox-O'Hearn # portions Copyright (c) 2001 Autonomous Zone Industries # This file is licensed under the # GNU Lesser General Public License v2.1. # See the file COPYING or visit http://www.gnu.org/ for details. """ What word has three letters and a 'x' in it? Not that one silly. """ import array, operator from pyutil.humanreadable import hr from pyutil.assertutil import _assert, precondition, postcondition try: import c_xor c_xor = c_xor.xor print 'NOTE: c_xor found, using accelerated C version of xor' except: c_xor = None print 'NOTE: c_xor not found, using 100% python implementation of xor' def py_xor(str1, str2): precondition(len(str1) == len(str2), "str1 and str2 are required to be of the same length.", str1=str1, str2=str2) if len(str1)%4 == 0: a1 = array.array('i', str1) a2 = array.array('i', str2) for i in range(len(a1)): a2[i] = a2[i]^a1[i] elif len(str1)%2 == 0: a1 = array.array('h', str1) a2 = array.array('h', str2) for i in range(len(a1)): a2[i] = a2[i]^a1[i] else: a1 = array.array('c', str1) a2 = array.array('c', str2) for i in range(len(a1)): a2[i] = chr(ord(a2[i])^ord(a1[i])) return a2.tostring() def py_xor_simple(str1, str2): """ Benchmarks show that this is the same speed as py_xor() for small strings and much slower for large strings, so don't use it. --Zooko 2002-04-29 """ precondition(len(str1) == len(str2), "str1 and str2 are required to be of the same length.", str1=str1, str2=str2) return ''.join(map(chr, map(operator.__xor__, map(ord, str1), map(ord, str2)))) # Now make "xor.xor()" be the best xor we've got: global xor xor = None if callable(c_xor): xor = c_xor elif callable(py_xor): xor = py_xor elif callable(py_xor_simple): xor = py_xor_simple else: raise "HEY! WHERE IS MY XOR IMPLEMENTATION?" # for unit tests, see pyutil/test/test_xor.py. For benchmarks, see pyutil/test/bench_xor.py.