The module in question provides classes used to execute Markov encryption and decryption on arrays of bytes. ME was inspired by a combination of Markov chains with the puzzle of Sudoku. This version is a rewrite of the original recipe and has various changes and optimizations for Python 2.5 et cetera.Besides the addition of documentation, how could the code's API be improved?Without writing an implementation in C, are there any places to make it faster?Because of the module's length, it has been posted on ActiveState for access: Markov Encryption...class Key(object):    ...    @classmethod    def new(cls, chars_used, chain_size):        selection, blocks = list(set(chars_used)), []        for _ in range(chain_size):            _CHAOS.shuffle(selection)            blocks.append(''.join(selection))        return cls(tuple(blocks))    def __init__(self, data):        self.__test_data(data)        self.__make_vars(data)    ...    def test_primer(self, primer):        primer.test_key(self)    def encode(self, prefix, current):        assert len(prefix) == self.__prefix_len, \               'Prefix size is not compatible with key dimensions!'        return self.__base[(sum(table[probe] for table, probe in            zip(self.__axes, prefix)) - self.__offset + current) % self.__size]    def decode(self, prefix, current):        assert len(prefix) == self.__prefix_len, \               'Prefix size is not compatible with key dimensions!'        return self.__inverse[(sum(table[probe] for table, probe in            zip(self.__axes, prefix)) - self.__offset) % self.__size][current]    ...class Primer(object):    ...    @classmethod    def new(cls, key):        base = key.base        return cls(''.join(_CHAOS.choice(base) for _ in range(key.prefix_len)))    def __init__(self, data):        self.__test_data(data)        self.__data = data    ...    @property    def data(self):        return self.__data...def encrypt(data, key, primer):    engine = Encrypter(key, primer)    return engine.process(data), engine.primerdef decrypt(data, key, primer):    engine = Decrypter(key, primer)    return engine.process(data), engine.primerdef auto_encrypt(data, chain_size, plain_text=''):    key = Key.new(set(data) - set(plain_text), chain_size)    primer = Primer.new(key)    return Encrypter(key, primer).process(data), key, primerEdit: The documentation for the new classmethods is below, copied from the 3.x version of the code.@classmethoddef new(cls, bytes_used, chain_size):    Return a Key instance created from bytes_used and chain_size.    Creating a new key is easy with this method. Call this class method    with the bytes you want the key to recognize along with the size of    the chains you want the encryption/decryption processes to use.    selection, blocks = list(set(bytes_used)), []    for _ in range(chain_size):        _CHAOS.shuffle(selection)        blocks.append(bytes(selection))    return cls(tuple(blocks))@classmethoddef new(cls, key):    Return a Primer instance from a parent Key.    Primers must be compatible with the keys they are used with. This    method takes a key and constructs a cryptographically sound primer    that is ready to use in the beginning stages of encryption.    base = key.base    return cls(bytes(_CHAOS.choice(base)                     for _ in range(key.dimensions - 1)))
Markov Encryption API in Python 2.5
python;optimization;api;cryptography