mk wrote:
> On 2010-02-24 03:50, Paul Rubin wrote:
>> The stuff about converting 4 random bytes to a decimal string and then
>> peeling off 2 digits at a time is pretty awful, and notice that since
>> 2**32 is 4294967296, in the cases where you get 10 digits, the first
>> 2-digit pair is never higher than 42.
> 
> Yikes! I didn't think about that. This is probably where (some part of)
> probability skewing comes from.
> 
> Anyway, the passwords for authorized users will be copied and pasted
> from email into in the application GUI which will remember it for them,
> so they will not have to remember and type them in. So I have little in
> the way of limitations of password length - even though in *some* cases
> somebody might have to (or be ignorant enough) to retype the password
> instead of pasting it in.
> 
> In that case the "diceware" approach is not necessary, even though I
> will certainly remember this approach for a case when users will have to
> remember & type the passwords in.
> 
> The main application will access the data using HTTP (probably), so the
> main point is that an attacker is not able to guess passwords using
> brute force.
> 
> Using A-z with 10-char password seems to provide 3 orders of magnitude
> more combinations than a-z:
> 
>>>> 57 ** 10
> 362033331456891249L
>>>> 25 ** 10
> 95367431640625L
> 
> Even though I'm not sure it is worth it, assuming 1000 brute-force
> guesses per second (which over the web would amount pretty much to DOS),
> this would take # days:
> 
>>>> 57 ** 10 / (1000 * 3600 * 24)
> 4190200595L
>>>> 25 ** 10 / (1000 * 3600 * 24)
> 1103789L
> 
> Even then I'm not getting completely uniform distribution for some reason:
> 
> d 39411
> l 39376
> f 39288
> a 39275
> s 39225
> r 39172
> p 39159
> t 39073
> k 39071
> u 39064
> e 39005
> o 39005
> n 38995
> j 38993
> h 38975
> q 38958
> c 38938
> b 38906
> g 38894
> i 38847
> m 38819
> v 38712
> z 35321
> y 35228
> w 35189
> x 35075
> 
> Code:
> 
> import operator
> 
> def gen_rand_word(n):
>     with open('/dev/urandom') as f:
>         return ''.join([chr(ord('a') + ord(x) % 26) for x in f.read(n)])
> 
> def count_chars(chardict, word):
>     for c in word:
>         try:
>             chardict[c] += 1
>         except KeyError:
>             chardict[c] = 0
> 
> if __name__ == "__main__":
>     chardict = {}
>     for i in range(100000):
>         w = gen_rand_word(10)
>         count_chars(chardict, w)
>     counts = list(chardict.items())
>     counts.sort(key = operator.itemgetter(1), reverse = True)
>     for char, count in counts:
>         print char, count
> 
>> I'd write your code something like this:
>>
>>      nletters = 5
>>
>>      def randomword(n):
>>          with open('/dev/urandom') as f:
>>              return ''.join([chr(ord('a')+ord(c)%26) for c in f.read(n)])
>>
>>      print randomword(nletters)
> 
> Aw shucks when will I learn to do the stuff in 3 lines well instead of
> 20, poorly. :-/
> 
When you've got as much experience as Paul?

regards
 Steve
-- 
Steve Holden           +1 571 484 6266   +1 800 494 3119
PyCon is coming! Atlanta, Feb 2010  http://us.pycon.org/
Holden Web LLC                 http://www.holdenweb.com/
UPCOMING EVENTS:        http://holdenweb.eventbrite.com/

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

Reply via email to