Python 问题求教

2019-11-01 22:04:30 +08:00
 HHH01

老师又布置了一道题,生成随机密码,就是要从一个生成随机密码的模块中获取密码,随机密码是 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)

3085 次点击
所在节点    Python
16 条回复
HHH01
2019-11-01 22:10:31 +08:00
尽量只用 if, while 和 def 其他还没学到,连 for 跟 range 都没有教
hxse
2019-11-01 22:51:58 +08:00
def get_random_text():
return choice(txts)
slert
2019-11-01 22:51:59 +08:00
大于 n 的情况 没有 return 呗
顺着你的代码去改的话 最后加个 else 截取到需要的长度呗
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
2019-11-01 23:11:58 +08:00
可能分组下更好点。随机的 txts 可以分成不同的长度组,然后计算组合的可能性,然后随机分组,再组内随机。
Hconk
2019-11-01 23:23:50 +08:00
benjix
2019-11-02 00:03:51 +08:00
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
2019-11-02 00:12:18 +08:00
@benjix 有个 bug,当 len(i) + len(j) ==9 的时候,就无限循环了。需要单独判断
676529483
2019-11-02 00:25:45 +08:00
7l 大哥的算法已经很好了,加上差值为 1 的时候,重算就行了。
while len(i) + len(j) != n:
if len(i) == n - 1:
print("重算")
return easy_password(n)
j = get_random_text()
benjix
2019-11-02 00:28:28 +08:00
@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
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
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
2019-11-02 10:13:43 +08:00
感谢各位大拿提供的思路,都一一看看了,谢谢了
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
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
2019-11-02 20:25:34 +08:00
tmp = choice(txts) 换成 tmp = get_random_text()

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/615422

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX