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. :-/
Regards,
mk
--
http://mail.python.org/mailman/listinfo/python-list