Python判断密码强度问题
如果满足以下条件,一个密码被认为是强大的。它至少有6个字符,最多有20个字符。
它至少包含一个小写字母,至少一个大写字母,以及至少一个数字。
它不包含三个连续的重复字符(例如,"...aaa... "是弱的,但"...aa...a... "是强的,假设其他条件都满足)。
给定一个字符串密码,返回使密码变强所需的最少步骤。如果密码已经很强,返回0。
在一个步骤中,你可以
在密码中插入一个字符。
从密码中删除一个字符,
或用另一个字符替换密码中的一个字符。
例1:
输入:密码 = "a"
输出。5
例2:
输入:密码 = "aA1"
输出。3
例子3:
输入:密码 = "1337C0d3"
输出。0
刚学一个月,就遇到这样的难题,希望大佬们的帮助。 本帖最后由 Stubborn 于 2021-10-16 18:40 编辑
乍看很简单,其实很难{:5_99:} 输入数据无限制吗?提的问题没有漏什么东西把
我的代码仅供参考,你的题目相当有水准,我喜欢
def isRepeating(password: str) -> int:
res = 0
a = password
temp = -1
for n, p in enumerate(password):
if n:
if a == p:
temp += 1
elif temp > 0:
res += temp
temp = -1
a = p
else:
temp = -1
a = p
return res if temp < 1 else res+temp
def isInsufficient(password: str) -> int:
res = 0
return res if len(password) >= 6 and len(password) <= 20 else 6-len(password) if len(password) < 6 else len(password)-20
def isConditional(password: str) -> int:
if len(password) < 4: return 0
digit = False
bigCap = False
smallCap = False
for i in password:
if i.isdigit():
digit = True
elif i.islower():
smallCap = True
elif i.isupper():
bigCap = True
return 0 if all() else\
1 if all() or\
all() or\
all() else\
2 if digit or bigCap or smallCap else 3
def main():
password = input("输入密码:")
res = isRepeating(password) + isInsufficient(password) + isConditional(password)
print(f"密码变强所需的最少步骤:{res}")
if __name__ == "__main__":
main()输入密码:a
密码变强所需的最少步骤:5
输入密码:aA1
密码变强所需的最少步骤:3
输入密码:1337C0d3
密码变强所需的最少步骤:0
本帖最后由 qq1151985918 于 2021-10-17 18:21 编辑
这题目非常弯弯绕,即使我几经修改仍然认为可能存在BUG,如果错误请提供案例
def isLengthEnough(s):
if 6 <= len(s) <= 20:
return True
else:
return False
def isNumIn(s):
for i in s:
if i.isdigit():
return True
else:
return False
def isLowIn(s):
for i in s:
if i.islower():
return True
else:
return False
def isCapIn(s):
for i in s:
if i.isupper():
return True
else:
return False
def isNotRepeat3(s):
for i in set(s):
if i * 3 in s:
return False
else:
return True
def allRepeat3(s):
r = []
while not isNotRepeat3(s):
for i in s:
for j in range(len(s), 2, -1):
if i * j in s:
for k in range(s.count(i * j)):
r.append(i * j)
s = s.replace(i * j, "")
break
return sorted(r, key=lambda x:len(x), reverse=True)
def run(s):
r = sum()
if r == 5:
result = 0
elif sum() == 0:
res1 = 6 - len(s) if len(s) < 6 else len(s) - 20
t, flg, allR = 0, False, allRepeat3(s)
for i in allR:
if flg:
t += len(s) - len(allR)
break
elif not flg and len(i) > 20:
flg = True
t += len(i) - 20 + (20 // 3)
else:
t += len(i) // 3
res2 = t if t > 3 - r else 3 - r
result = res1 if res1 > res2 else res2
elif not isLengthEnough(s):
t = 6 - len(s) if len(s) < 6 else len(s) - 20
result = t if t > 4 - r else 4 - r
elif not isNotRepeat3(s):
t = 0
for i in allRepeat3(s):
t += len(i) // 3
result = t if t > 4 - r else 4 - r
else:
result = 5 - r
return result
if __name__ == "__main__":
password = input("输入密码:")
print("密码变强所需的最少步骤:", run(password))
傻眼貓咪 发表于 2021-10-16 19:57
我的代码仅供参考,你的题目相当有水准,我喜欢
我测试楼主代码,发现一些BUG,提供案例如下
另外希望楼主从你的角度看下我代码是否还有BUG
我已经修改七八次了,仍然感觉可能会有BUG,但是没找出,希望楼主看看
如果发现BUG请提供下案例
输入密码:aaaaa
密码变强所需的最少步骤:6
输入密码:aaaa
密码变强所需的最少步骤:6
输入密码:aaa
密码变强所需的最少步骤:4
输入密码:aaabbbbbb111111
密码变强所需的最少步骤:10 qq1151985918 发表于 2021-10-16 23:14
我测试楼主代码,发现一些BUG,提供案例如下
另外希望楼主从你的角度看下我代码是否还有BUG
我已经修改 ...
十分感谢层主的回答,您的代码我测试过,已经十分完美了。但好像还是有BUG。
比如我输入30个字母a:
输入密码:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
密码变强所需的最少步骤: 10
貌似,修改密码的步骤不止10步,因为除了删除10个多余字符,还要改变成数字,大写。
望层主能解答。 傻眼貓咪 发表于 2021-10-16 19:57
我的代码仅供参考,你的题目相当有水准,我喜欢
谢谢这位层主的解答 Stubborn 发表于 2021-10-16 18:30
乍看很简单,其实很难 输入数据无限制吗?提的问题没有漏什么东西把
对啊,乍一看不难,但是细想下有很多条件要考虑。题上给的条件就这么多。。。{:5_99:} 本帖最后由 qq1151985918 于 2021-10-17 18:22 编辑
icecocotea 发表于 2021-10-17 07:40
十分感谢层主的回答,您的代码我测试过,已经十分完美了。但好像还是有BUG。
比如我输入30个字母a:
我又修改了,你再试试看
def isLengthEnough(s):
if 6 <= len(s) <= 20:
return True
else:
return False
def isNumIn(s):
for i in s:
if i.isdigit():
return True
else:
return False
def isLowIn(s):
for i in s:
if i.islower():
return True
else:
return False
def isCapIn(s):
for i in s:
if i.isupper():
return True
else:
return False
def isNotRepeat3(s):
for i in set(s):
if i * 3 in s:
return False
else:
return True
def allRepeat3(s):
r = []
while not isNotRepeat3(s):
for i in s:
for j in range(len(s), 2, -1):
if i * j in s:
for k in range(s.count(i * j)):
r.append(i * j)
s = s.replace(i * j, "")
break
return sorted(r, key=lambda x:len(x), reverse=True)
def run(s):
r = sum()
if r == 5:
result = 0
elif sum() == 0:
res1 = 6 - len(s) if len(s) < 6 else len(s) - 20
t, flg, allR = 0, False, allRepeat3(s)
for i in allR:
if flg:
t += len(s) - len(allR)
break
elif not flg and len(i) > 20:
flg = True
t += len(i) - 20 + (20 // 3)
else:
t += len(i) // 3
res2 = t if t > 3 - r else 3 - r
result = res1 if res1 > res2 else res2
elif not isLengthEnough(s):
t = 6 - len(s) if len(s) < 6 else len(s) - 20
result = t if t > 4 - r else 4 - r
elif not isNotRepeat3(s):
t = 0
for i in allRepeat3(s):
t += len(i) // 3
result = t if t > 4 - r else 4 - r
else:
result = 5 - r
return result
if __name__ == "__main__":
password = input("输入密码:")
print("密码变强所需的最少步骤:", run(password))
抱歉,上边的代码我又修改了四五次,仍然发现有BUG,待我再考虑一下,这是哪里的题目? qq1151985918 发表于 2021-10-17 18:28
抱歉,上边的代码我又修改了四五次,仍然发现有BUG,待我再考虑一下,这是哪里的题目?
辛苦了哥们儿,这个题目是我一个老师给的习题集里面的。 本帖最后由 Stubborn 于 2021-10-21 16:07 编辑
icecocotea 发表于 2021-10-17 07:42
对啊,乍一看不难,但是细想下有很多条件要考虑。题上给的条件就这么多。。。
越想越复杂,如 aa + c*20 + bbd 和 bbd + c*20 + a,这种情况,就面临一个问题,程序应该如何判断通过最少步骤 去“操作”一段适合的密码,从前面,后面,还是中间“操作”一部分呢?
我觉得,这边问题,首先要解决的是种类的检查,其次最重要的是如何处理重复问题
并且我们对密码的操作优先度,应该是替换(替换步骤大于2,可以不用考虑种类问题),删减
其次需要检查密码的有效最大长度。根据密码有效的最大长度已经种类的检查的结果进行操作{:10_327:}
假如,我有的程序对一串字符串(aaccccccccccccccccccccbbdaacccccccvbcdeeeeeffff)处理后,可以得到两个列表
a =
b =
第一列,有效和无效长度,aa ,ccccccc, vbcd, eeee, ffff
第二列,如果是有效长度则不需要操作,如果是无效长度,需要操作多少步才能变为有效长度。
这样一来,问题转化成了,寻找一个连续数组,什么样的连续数组是我们的想要的?
从我们看来,这个字符串最短步骤应该是,进行3次替换,即取 5+ 7 + 4 +5,可以获取足够合适的密码长度,其他的字符都可以删减。 icecocotea 发表于 2021-10-17 07:40
十分感谢层主的回答,您的代码我测试过,已经十分完美了。但好像还是有BUG。
比如我输入30个字母a:
应该是替换6个,以及删除10个,总计16步骤
页:
[1]