Re: encrypting files + filestreams?

2007-08-15 Thread Marshall T. Vandegrift
per9000 <[EMAIL PROTECTED]> writes:

> I am trying to figure out the best way to encrypt files in python.

Looking at your code and questions, you probably want to pick up a
cryptography handbook of some sort (I'd recommend /Practical
Cryptography/) and give it a read.

> But I have some thoughts about it. By pure luck (?) this file happened
> to be N*512 bytes long so I do not have to add crap at the end - but
> on files of the size N*512 + M (M != 521) I will add some crap to make
> it fit in the algorithm.

BTW, AES has a block size of 16, not 512.

> When I later decrypt I will have the stuff I do not want. How do
> people solve this? (By writing the number of relevant bytes in
> readable text in the beginning of the file?)

There are three basic ways of solving the problem with block ciphers.
Like you suggest, you can somehow store the actual size of the encrypted
data.  The second option is to store the number of padding bytes
appended to the end of the data.  The third is to use the block cipher
in cipher feedback (CFB) or output feedback (OFB) modes, both of which
transform the block cipher into a stream cipher.  The simplest choice
coding-wise is to just use CFB mode, but the "best" choice depends upon
the requirements of your project.

> Also I wonder if this can be solved with filestreams (Are there
> streams in python? The only python file streams I found in the evil
> search engine was stuff in other forums.)

Try looking for information on "file-like objects."  Depending on the
needs of your application, one general solution would be to implement a
file-like object which decorates another file-like object with
encryption on its IO operations.

> crptz = AES.new("my-secret_passwd")

I realize this is just toy code, but this is almost certainly not what
you want:

  - You'll get a much higher quality key -- and allow arbitrary length
passphrases -- by producing the key from the passphrase instead of
using it directly as the key.  For example, taking the SHA-256 hash
of the passphrase will produce a much higher entropy key of the
correct size for AES.

  - Instantiating the cipher without specifying a mode and
initialization vector will cause the resulting cipher object to use
ECB (electronic codebook) mode.  This causes each identical block in
the input stream to result in an identical block in the output
stream, which opens the door for all sorts of attacks.

Hope this helps!

-Marshall

-- 
http://mail.python.org/mailman/listinfo/python-list


Coroutines and argument tupling

2007-08-15 Thread Marshall T. Vandegrift
Hi,

I'm trying to write a decorator which allows one to produce simple
coroutines by just writing a function as a generator expression which
re-receives it's arguments as a tuple from each yield.  For example:

@coroutine
def nextn(n=1):
values = []
for i in itertools.count():
while n <= 0:
(n,) = (yield values)
values = []
values.append(i)
n = n - 1

print nextn() # => [0]
print nextn(3)# => [1, 2, 3]
print nextn(n=2)  # => [4, 5]
print nextn() # => [6]

I've got this working, but have two questions.  First, is there a better
way to generically transform function arguments into a tuple than I'm
doing now?  That way being with this pretty hideous chunk of code:

class ArgPacker(object):
def __init__(self, function):
args, varargs, varkw, defaults = inspect.getargspec(function)
self.args = args or []
self.varargs = (varargs is not None) and 1 or 0
self.varkw = (varkw is not None) and 1 or 0
self.nargs = len(self.args) + self.varargs + self.varkw
defaults = defaults or []
defargs = self.args[len(self.args) - len(defaults):]
self.defaults = dict([(k, v) for k, v in izip(defargs, defaults)])

def pack(self, *args, **kwargs):
args = list(args)
result = [None] * self.nargs
for i, arg in izip(xrange(len(self.args)), self.args):
if args:
result[i] = args.pop(0)
elif arg in kwargs:
result[i] = kwargs[arg]
del kwargs[arg]
elif arg in self.defaults:
result[i] = self.defaults[arg]
else:
return None
if self.varargs:
result[len(self.args)] = args
elif args:
return None
if self.varkw:
result[-1] = kwargs
elif kwargs:
return None
return tuple(result)

I also tried a version using exec, which was much tighter, but used
exec.

Second, am I trying to hammer a nail with a glass bottle here?  The
ugliness of the ArgPacker class makes me suspect that I should perhaps
just manually create and track a generator when I need a function with
generator-like properties.

Thanks!

-Marshall

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Coroutines and argument tupling

2007-08-15 Thread Marshall T. Vandegrift
Bjoern Schliessmann <[EMAIL PROTECTED]> writes:

>> I'm trying to write a decorator which allows one to produce simple
>> coroutines by just writing a function as a generator expression
>> which re-receives it's arguments as a tuple from each yield.  
>
> May I ask why? Passing it the same arguments over and over is no
> use; and there is the send method.

That's what I meant.  The wrapper produced by the decorator passes the
arguments back into the generator as a tuple via the `send' method.

>> The ugliness of the ArgPacker class makes me suspect that I should
>> perhaps just manually create and track a generator when I need a
>> function with generator-like properties.
>
> What do you mean? I don't quite understand why you'd have to "track"
> a generator for getting generator-like properties.

Using the trivial `nextn' example from my original post with my
decorator lets you do just:

print nextn(2)# => [0, 1]
print nextn(3)# => [2, 3, 4]
print nextn() # => [5]

Without the decorator that becomes:

gen = nextn(2)
print gen.next()  # => [0, 1] 
print gen.send(3) # => [2, 3, 4]
print gen.send(1) # => [5]

The former is just that smidgen nicer, and allows you to continue to
make use of argument defaults and varadic arguments if so desired.

-Marshall
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Coroutines and argument tupling

2007-08-15 Thread Marshall T. Vandegrift
"[EMAIL PROTECTED]" <[EMAIL PROTECTED]> writes:

> Do you really need a generator or co-routine to do this?  Maybe
> you can just use a closure:

For my trivial example, sure -- there are lots of ways to do it.  Here's
a slightly better example: the `read' method of a file-like object which
sequentially joins the contents of a sequence of other file-like
objects:

@coroutine
def read(self, size=-1):
data = ''
for file in self.files:
this = file.read(size - len(data))
data = ''.join([data, this])
while this:
if len(data) == size:
_, size = (yield data)
data = ''
this = file.read(size - len(data))
data = ''.join([data, this])
yield data
while True:
yield ''

-Marshall

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Coroutines and argument tupling

2007-08-16 Thread Marshall T. Vandegrift
Bjoern Schliessmann <[EMAIL PROTECTED]> writes:

> The solution I'd use is a decorator that calls next automatically one
> time after instantiation. Then you can use send normally, and don't
> have to care about any initial parameters, which makes the code
> clearer (initial parameters should be used for setup purposes, but not
> for the first iteration, IMHO). It'd look like this (from PEP 342,
> http://www.python.org/dev/peps/pep-0342/):

I'd seen the consumer decorator, and it certainly is cleaner than just
using a generator.  I don't like how it hides the parameter signature in
the middle of the consumer function though, and it also doesn't provide
for argument default values.  It's the difference between:

...
def __init__(self, ...):
...
self.consumer = self._function(value)
...

def function(self, first, second=3, *args, **kwargs):
self.consumer.send((first, second, args, kwargs))

@consumer
def _function(self, setup):
...
first, second, args, kwargs = yield # initial 'next'
while condition:
...
first, second, args, kwargs = yield retval

Versus just:

@coroutine
def function(self, first, second=3, *args, **kwargs):
...
while condition:
...
first, second, args, kwargs = yield retval

Thanks in any case for the replies!  Since I've apparently decided my
ArgPacker is worth it, the complete code for my coroutine decorator
follows.

-Marshall


import inspect
import types
import functools
from itertools import izip

__all__ = [ 'coroutine' ]

class ArgPacker(object):
def __init__(self, function):
args, varargs, varkw, defaults = inspect.getargspec(function)
self.args = args or []
self.varargs = (varargs is not None) and 1 or 0
self.varkw = (varkw is not None) and 1 or 0
self.nargs = len(self.args) + self.varargs + self.varkw
defaults = defaults or []
defargs = self.args[len(self.args) - len(defaults):]
self.defaults = dict([(k, v) for k, v in izip(defargs, defaults)])

def pack(self, *args, **kwargs):
args = list(args)
result = [None] * self.nargs
for i, arg in izip(xrange(len(self.args)), self.args):
if args:
result[i] = args.pop(0)
elif arg in kwargs:
result[i] = kwargs[arg]
del kwargs[arg]
elif arg in self.defaults:
result[i] = self.defaults[arg]
else:
return None
if self.varargs:
result[len(self.args)] = args
elif args:
return None
if self.varkw:
result[-1] = kwargs
elif kwargs:
return None
return tuple(result)

class coroutine(object):
"""Convert a function to be a simple coroutine.

A simple coroutine is a generator bound to act as much as possible like a
normal function.  Callers call the function as usual while the coroutine
produces new return values and receives new arguments with `yield'.
"""
def __init__(self, function):
self.function = function
self.gname = ''.join(['__', function.__name__, '_generator'])
self.packer = ArgPacker(function)
coroutine = self
def method(self, *args, **kwargs):
return coroutine.generate(self, self, *args, **kwargs)
self.method = method
functools.update_wrapper(self, function)
functools.update_wrapper(method, function)

def __get__(self, obj, objtype=None):
return types.MethodType(self.method, obj, objtype)

def __call__(self, *args, **kwargs):
return self.generate(self, *args, **kwargs)

def generate(self, obj, *args, **kwargs):
try:
generator = getattr(obj, self.gname)
except AttributeError:
generator = self.function(*args, **kwargs)
setattr(obj, self.gname, generator)
retval = generator.next()
else:
packed = self.packer.pack(*args, **kwargs)
if packed is None:
self.function(*args, **kwargs) # Should raise TypeError
raise RuntimeError("ArgPacker reported spurious error")
retval = generator.send(packed)
return retval

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Encryption and hashing

2007-08-17 Thread Marshall T. Vandegrift
Kless <[EMAIL PROTECTED]> writes:

> For who knows any of criptography I comment that you can use
> algorithms as secure as Rijndael, Twofish, or Serpent with the CFB
> cipher mode. And for hash you can use RIPEMD, SHA-2 or WHIRLPOOL.

PyCrypto does includes the AES version of Rijndael as Crypto.Cipher.AES
and the 256-bit version of SHA-2 as Crypto.Hash.SHA256.

-Marshall

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Class destruction

2007-08-22 Thread Marshall T. Vandegrift
Nils Oliver Kröger <[EMAIL PROTECTED]> writes:

> If you want to "reuse" the file, you will have to delete your classes
> instance explicitly using the del statement ... this will also call
> the destructor.

Sometimes, but not always.  The `del' statement simple removes the
reference to the instance and decrements its reference count.  The
__del__() routine for the instance still only gets called whenever the
object is actually garbage collected.  Furthermore, the Python Reference
Manual notes that:

Circular references which are garbage are detected when the option
cycle detector is enabled (it's on by default), but can only be
cleaned up if there are no Python-level __del__() methods involved.
[http://docs.python.org/ref/customization.html]

The proper way to handle the case presented by the OP is for the class
to expose a close()-like method and/or -- for use with Python 2.5 and
later -- implement the methods of the context manager protocol
[http://docs.python.org/ref/context-managers.html].  The following code
supports basic usage:

def close(self):
self._file.close()
print "File closed"

def __enter__(self):
return self

def __exit__(self, *exc_info):
self.close()
return False

Then the users of this class can freely do any of:

f = fout(filename)
...
f.close()

with fout(filename) as f:
...

with closing(fout(filename)) as f:
...

HTH,

-Marshall

-- 
http://mail.python.org/mailman/listinfo/python-list

Re: Code design problem

2007-08-29 Thread Marshall T. Vandegrift
Marco Nawijn <[EMAIL PROTECTED]> writes:

> The problem I face is that the implementation of the application class
> is completely different for the local and remote case. The local case
> is a straightforward implemenation using the subprocess module, the
> remote case is a CORBA implementation. Somehow I would like to switch
> from implementation class at runtime depending on whether or not the
> host parameter is specified or not.
>
> The Application, local implementation and remote implementation all
> have the same interface, so a possibility might be something like the
> following:



> To me forwarding each call in the Application class looks a little bit
> redundant and I would like to get rid of it. Does anyone have any
> comments or suggestions? Can metaclass programming come to rescue?

It sounds like you could probably get away with just a factory function:

def Application(program, host=None):
if host is None:
return LocalApplication(program)
else:
return RemoteApplication(program, host)

Then just implement the same interface and/or derive from a common base
class for LocalApplication and RemoteApplication.

HTH!,

-Marshall

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Short, crazy example: list-derived class, with __iadd__

2007-08-29 Thread Marshall T. Vandegrift
Moon <[EMAIL PROTECTED]> writes:

> class Vec(list):
> def __init__(self):
> list.__init__(self, [0.0, 0.0])
>
> def __iadd__(self, other):
> assert isinstance(other, Vec)
> self[0] += other[0]
> self[1] += other[1]
> print "right now, v is: ", self, " as you'd expect"
  return self
>
>
> v = Vec()
> w = Vec()
> w[0] = 1.0
> w[1] = 2.0
> print "v starts:", v
>
> print "(w is:", w, " which is fine)"
>
> v += w
>
> print "(w still is:", w
>
  print "after iadd, v: ", v

>
> # - running it: 

v starts: [0.0, 0.0]
(w is: [1.0, 2.0]  which is fine)
right now, v is:  [1.0, 2.0]  as you'd expect
(w still is: [1.0, 2.0]
after iadd, v:  [1.0, 2.0]

-Marshall

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: list index()

2007-08-30 Thread Marshall T. Vandegrift
[EMAIL PROTECTED] writes:

> What's with the index() function of lists throwing an exception on not
> found? Let's hope this is rectified in Python 3. If nothing else, add
> a function that doesn't throw an exception. There are a million
> situations where you can have an item not be in a list and it is not
> an exception situation.

The Python string types have both the method `index()` which throws an
exception and the method `find()` which implements the same behavior but
returns -1 for not-found substrings.  I would naively have assumed the
`list` type to provide both as well, but it provides only `index()`.

Anyone know the reason for this lack of parallelism?

-Marshall

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: strings (dollar.cents) into floats

2007-08-30 Thread Marshall T. Vandegrift
luca bertini <[EMAIL PROTECTED]> writes:

> i have strings which look like money values (ie 34.45)
> is there a way to convert them into float variables?
> everytime i try I get this error: "numb = float(my_line) ValueError:  
> empty string for float()"
> "

You actually have problems here -- the immediate, and the one which will
get you later :-).  First, that error message indicates that you passed
an empty string to `float()`:

>>> float("")
Traceback (most recent call last):
  File "", line 1, in ?
ValueError: empty string for float()

Second, if you the values your script is handling are actually monetary
values, you really don't want to represent them with `float`s anyway:

>>> float("34.45")
34.453

Binary floating point values are necessarily inexact.  I'm not 100% sure
what the best-practices are for representing monetary values in Python,
but the `decimal` module is probably a good start.

HTH,

-Marshall

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: super() doesn't get superclass

2007-09-20 Thread Marshall T. Vandegrift
Michele Simionato <[EMAIL PROTECTED]> writes:

> I am not against mixins (even if I am certainly very much against the
> *abuse* of mixins, such as in Zope 2). What I would advocate (but I
> realize that it will never happen in Python) is single inheritance +
> mixins a la Ruby.

Ruby might be a bad example here.  Although the Ruby language syntax
only supports single inheritance, mixins are implemented as multiple
inheritance under the hood.  That is, inheriting from a class and
including a class as a mixin modifies the sub-/mixing class in exactly
the same way.

-Marshall

-- 
http://mail.python.org/mailman/listinfo/python-list