Уведомления

Группа в Telegram: @pythonsu

#1 Ноя. 23, 2009 11:12:30

Gradient
От:
Зарегистрирован: 2009-06-03
Сообщения: 40
Репутация: +  0  -
Профиль   Отправить e-mail  

Плохой random или я не умею его готовить?

Пытаюсь изобразить консольный генератор паролей.

Простой пример:

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 Я учусь, так что рад любой конструктивной критике кода.



Офлайн

#2 Ноя. 23, 2009 11:34:18

regall
От: Киев
Зарегистрирован: 2008-07-17
Сообщения: 1583
Репутация: +  3  -
Профиль   Отправить e-mail  

Плохой random или я не умею его готовить?

Странно, у меня этот код отрабатывает, причем генерит совершенно разные последовательности

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



Отредактировано (Ноя. 23, 2009 11:37:08)

Офлайн

#3 Ноя. 23, 2009 11:34:40

igor.kaist
От:
Зарегистрирован: 2007-11-12
Сообщения: 1879
Репутация: +  3  -
Профиль   Отправить e-mail  

Плохой random или я не умею его готовить?

:) может просто вам не везет, это все таки рандом ?



Отредактировано (Ноя. 23, 2009 11:37:12)

Офлайн

#4 Ноя. 23, 2009 12:39:31

Gradient
От:
Зарегистрирован: 2009-06-03
Сообщения: 40
Репутация: +  0  -
Профиль   Отправить e-mail  

Плохой random или я не умею его готовить?

Мда… Я пример пересократил. В “реальной жизни” я всё-таки выбираю не все символы, так что распределение выборки может поплыть. Так что на сам рандом тут гнать преждевременно. Ступил.
Вот пример получше:

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… Или опять же, я неправ, что любая строка в питоне - юникодная.



Отредактировано (Ноя. 23, 2009 12:40:16)

Офлайн

#5 Ноя. 23, 2009 13:01:23

regall
От: Киев
Зарегистрирован: 2008-07-17
Сообщения: 1583
Репутация: +  3  -
Профиль   Отправить e-mail  

Плохой random или я не умею его готовить?

А для чего такие сложности?
Можно же облагородить как-то:

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)])



Отредактировано (Ноя. 23, 2009 13:04:47)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version