V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
HHH01
V2EX  ›  Python

Python 问题求教

  •  
  •   HHH01 · 2019-11-01 22:04:30 +08:00 · 3188 次点击
    这是一个创建于 1860 天前的主题,其中的信息可能已经有所发展或是发生改变。

    老师又布置了一道题,生成随机密码,就是要从一个生成随机密码的模块中获取密码,随机密码是 2,3 或者 4 位的,就是说有时是 length 是 2,有时 3,有时 4,随机。。。

    我现在需要随机输入一个数字比如 10,代表 10 位密码,然后从模块中得到这些密码,要求用到 def。 我的思路是,定义一个函数,先获取一个随机密码 i,然后如果我输入的 n 大于这个随机密码长度,那就在原来基础上在获取一个随机密码,直到 i 的长度等于我输入的值的大小, def easy_password(n): int(n)>1 i = get_random_text() while len(i)<int(n): i = i+get_random_text() if len(i) == n: return i

    print(easy_password(5))

    但是,这样有个很大问题,经常会出现 None。。。比如我想 n=5,如果第一次 i=3,再获取一次 i 的时候,i 有可能等于 6 或者 7,这样就直接 None 了。。。 我也不知道我思路对不对,求大家给点提示或者思路。。。

    我想如何能在出现 None 时重新获取密码,直到 len ( i )== n 再 return ? 或者有没有更好的办法?

    技术大拿来救救我吧,想了一天了。 原题如下。

    Exercise 3. Random passwords are safe but it is hard to remember them. Your task will be to write a function which will generate an easy to remember random 1 password. Such password will consist of short fragments of text which are easy to pronounce. Function to sample such fragments is in file fragments.py (download it from ILIAS) and is called get_random_text. The function can return fragments only of length 2, 3, or 4. An example usage of this function looks like this: from fragments import get_random_text i = 0 while i < 3: print( ' Random text: ' + get_random_text()) i += 1

    file, not the fragments.py). The function should accept one integer parameter length (assume that length > 1) and generate a password with exactly length characters. An example usage of this function: • easy_password(10) can return ’getbacuson’ • easy_password(10) can return ’piaftromer’ • easy_password(15) can return ’spresedparmonset’ • easy_password(2) can return ’en’ Remember, that the password has to be built from full fragments given by get_random_text .

    fragments.py 如下,

    from random import choice

    txts = """tive la lo ies li tain to ti ly get de mon fac day tri tro dif eve mo dis el set tem ten ed num sion sen ter es er est sub for ry per re pen ra ble rec ro ri ings be lec ba men ple mer ket ern on of ty ob tle ture op ci co ence pos son cy en cu pr tor pa fer pi po pres gen ward ers car der up cal ber tion my pre ac ad af vi pro it an ap as ar im in tal ic ing ni par min na ny mis out nu mar ness fa ties lar man sy land no so daq""".split()

    def get_random_text(): return choice(txts)

    16 条回复    2019-11-02 20:25:34 +08:00
    HHH01
        1
    HHH01  
    OP
       2019-11-01 22:10:31 +08:00
    尽量只用 if, while 和 def 其他还没学到,连 for 跟 range 都没有教
    hxse
        2
    hxse  
       2019-11-01 22:51:58 +08:00
    def get_random_text():
    return choice(txts)
    slert
        3
    slert  
       2019-11-01 22:51:59 +08:00
    大于 n 的情况 没有 return 呗
    顺着你的代码去改的话 最后加个 else 截取到需要的长度呗
    hxse
        4
    hxse  
       2019-11-01 23:05:06 +08:00
    def get_random_text():
    text=''
    number=0
    while number<choice([2,3,4]):
    text+=choice(txts)
    number+=1
    return text
    1024G
        5
    1024G  
       2019-11-01 23:11:58 +08:00
    可能分组下更好点。随机的 txts 可以分成不同的长度组,然后计算组合的可能性,然后随机分组,再组内随机。
    Hconk
        6
    Hconk  
       2019-11-01 23:23:50 +08:00   ❤️ 1
    benjix
        7
    benjix  
       2019-11-02 00:03:51 +08:00   ❤️ 1
    def easy_password(n):
    i = get_random_text()
    j = ''
    while n - len(i) > 4:
    i = i+get_random_text()
    while len(i) + len(j) != n:
    j = get_random_text()
    else:
    return i+j
    print(easy_password(8))
    676529483
        8
    676529483  
       2019-11-02 00:12:18 +08:00
    @benjix 有个 bug,当 len(i) + len(j) ==9 的时候,就无限循环了。需要单独判断
    676529483
        9
    676529483  
       2019-11-02 00:25:45 +08:00   ❤️ 1
    7l 大哥的算法已经很好了,加上差值为 1 的时候,重算就行了。
    while len(i) + len(j) != n:
    if len(i) == n - 1:
    print("重算")
    return easy_password(n)
    j = get_random_text()
    benjix
        10
    benjix  
       2019-11-02 00:28:28 +08:00   ❤️ 1
    @676529483 是的,再加个判断:
    def easy_password(n):
    i = get_random_text()
    j = ''
    while n - len(i) > 4:
    i = i+get_random_text()
    if n - len(i) == 1:
    i = get_random_text()
    while len(i) + len(j) != n:
    j = get_random_text()
    else:
    return i+j
    print(easy_password(8))
    HHH01
        11
    HHH01  
    OP
       2019-11-02 10:12:59 +08:00
    最后又请教了一下朋友的代码,我感觉这个思路妙,用临时变量暂时保存,这样简洁好多


    from fragments import get_random_text

    def easy_password(n):
    result = ""
    if n<2:
    return result
    while len(result) != n:
    tmp = result
    result += get_random_text()
    if n < len(result) or len(result)+1 ==n:
    result = tmp
    return result
    farverfull
        12
    farverfull  
       2019-11-02 10:13:32 +08:00
    def random_passwd(num=None):
    if not num or not isinstance(num, int):
    num = random.randint(1, 4)
    return ''.join(random.sample(string.hexdigits, num))
    HHH01
        13
    HHH01  
    OP
       2019-11-02 10:13:43 +08:00
    感谢各位大拿提供的思路,都一一看看了,谢谢了
    necomancer
        14
    necomancer  
       2019-11-02 20:15:23 +08:00
    def gen_pass(num):
    .... if num <= 5:
    ........ raise ValueError('Too short!')
    .... res = ''
    .... if num % 2 == 0:
    ........ qs = (num/2, 0, 0)
    .... else:
    ........ good_qs = False
    ........ while not good_qs:
    ............ a = random.randint(0, num//2)
    ............ lo, hi = round((num-6*a)/4), round((num-5*a)/3)
    ............ if lo >= hi:
    ................ continue
    ............ b = random.randint(lo, hi)
    ............ qs = (a, 6*a+4*b-num, num-(5*a+3*b))
    ............ for q in qs:
    ................ if q < 0:
    .................... break
    ............ else:
    ................ good_qs = True
    .... for q, l in zip(qs, [2,3,4]):
    ........ ct = 0
    ........ while ct < q:
    ............ tmp = choice(txts)
    ............ if len(tmp) == l:
    ................ res += tmp
    ................ ct += 1
    .... return res
    necomancer
        15
    necomancer  
       2019-11-02 20:24:12 +08:00
    先解丢番图,再去生成。如果你们允许使用正则表达式的话,那么:
    import re
    def gen_pass(num):
    ....if num <= 5:
    ........raise ValueError('Too short!')
    ....res = ''
    ....qs = qs = [ len(_) for _ in re.match(r'^(.*)\1{1}(.*)\2{2}(.*)\3{3}$', '1'*num).groups() ]
    ....for q, l in zip(qs, [2,3,4]):
    ........ct = 0
    ........while ct < q:
    ............tmp = choice(txts)
    ............if len(tmp) == l:
    ................res += tmp
    ................ct += 1
    ....return res
    necomancer
        16
    necomancer  
       2019-11-02 20:25:34 +08:00
    tmp = choice(txts) 换成 tmp = get_random_text()
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1033 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 20:00 · PVG 04:00 · LAX 12:00 · JFK 15:00
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.