Найти - Пользователи
Полная версия: Плохой random или я не умею его готовить?
Начало » Python для новичков » Плохой random или я не умею его готовить?
1
Gradient
Пытаюсь изобразить консольный генератор паролей.

Простой пример:
from random import randint as rnd
pw = ''
pwl = rnd(15, 25)

while len(pw) < pwl:
pw += chr(rnd(0x30, 0xFF))

print(pw)
Это как-то никуда не годится: буквы часто повторяются, многие подряд идут. Есть ощущение, что я что-то делаю не так.
А как правильно?

P.S. инициализация ДСЧ помогает не особо: статистика от этого качественно не изменяется.

P.P.S. У меня Windows. Может, под Linux реализация ДСЧ получше?

P.P.P.S Я учусь, так что рад любой конструктивной критике кода.
regall
Странно, у меня этот код отрабатывает, причем генерит совершенно разные последовательности

35ЙyђЛ—Ж:\АЦ0&#152;в‰EЪћ
™Џa•Qо3ЇIФэcP¦t™|®И
ЛRШмЃТИял鬻E‚BПRѕХ
`љQ†Сs7rчqГџЁЫD€ыWњ
o|њИен•ёfЎ‰ўiѓCх G«
њ›vwfцмKhwemЌJMиГ;©
@}ЊѕBЎІ@dU‘Гѓћ…8т«ў
J“›ИђJсжr5нтљ0ЌЅљ@Э
°b«м0Hьvфф^щYх0Н°~Ы
СУtҐЊНЫ¦‚—ВTZЕlЎДvт
ОС: WinXP SP 3, Python 2.5.4
igor.kaist
:) может просто вам не везет, это все таки рандом ?
Gradient
Мда… Я пример пересократил. В “реальной жизни” я всё-таки выбираю не все символы, так что распределение выборки может поплыть. Так что на сам рандом тут гнать преждевременно. Ступил.
Вот пример получше:
pw = ''
pwl = rnd(15, 25)

while len(pw) < pwl:
ch = chr(rnd(0x30, 0xFF))
if (ch >= 'A')&(ch <= 'Z'): pw += ch
elif (ch >= 'a')&(ch <= 'z'): pw += ch
elif (ch >= '0')&(ch <= '9'): pw += ch
elif '`~!@#$%^&*(){}[]?_+-="|/\<>,.'.find(ch) >= 0: pw += ch
# elif (ch >= 'А')&(ch <= 'Я'): pw += ch
# elif (ch >= 'а')&(ch <= 'я'): pw += ch

print pw
Пока “пофиксил” ограничением на количество одинаковых символов.

Плюс, есть проблема с русскими буквами: если разрешить их, то через print они выводятся правильно, но, например, вставляются через буфер обмена кракозябрами. При этом encode не помогает: на кириллице вылетает exception “нет такого символа в таблице”. Странно: почему строка из “честного юникода” не хочет быть перекодированной в cp1251… Или опять же, я неправ, что любая строка в питоне - юникодная.
regall
А для чего такие сложности?
Можно же облагородить как-то:
from string import digits, letters, punctuation
from random import randint, choice
seq = digits + letters + punctuation
pwl = rnd(15, 25)
pw = ''.join([choice(seq) for i in xrange(pwl)])
P.S. Опять же легко сюда добавить строку, например, больших кириллических символов:
>>> cyr_high = ''.join([chr(i) for i in xrange(ord('А'), ord('Я')+1)])
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB