鱼C论坛

 找回密码
 立即注册
查看: 4458|回复: 12

[已解决]Python判断密码强度问题

[复制链接]
发表于 2021-10-16 15:26:38 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
如果满足以下条件,一个密码被认为是强大的。
它至少有6个字符,最多有20个字符。
它至少包含一个小写字母,至少一个大写字母,以及至少一个数字。
它不包含三个连续的重复字符(例如,"...aaa... "是弱的,但"...aa...a... "是强的,假设其他条件都满足)。
给定一个字符串密码,返回使密码变强所需的最少步骤。如果密码已经很强,返回0。
在一个步骤中,你可以
在密码中插入一个字符。
从密码中删除一个字符,
或用另一个字符替换密码中的一个字符。

例1:
输入:密码 = "a"
输出。5
例2:
输入:密码 = "aA1"
输出。3
例子3:
输入:密码 = "1337C0d3"
输出。0


刚学一个月,就遇到这样的难题,希望大佬们的帮助。
最佳答案
2021-10-17 17:52:06
本帖最后由 qq1151985918 于 2021-10-17 18:22 编辑
icecocotea 发表于 2021-10-17 07:40
十分感谢层主的回答,您的代码我测试过,已经十分完美了。但好像还是有BUG。
比如我输入30个字母a:


我又修改了,你再试试看
  1. def isLengthEnough(s):
  2.     if 6 <= len(s) <= 20:
  3.         return True
  4.     else:
  5.         return False

  6. def isNumIn(s):
  7.     for i in s:
  8.         if i.isdigit():
  9.             return True
  10.     else:
  11.         return False
  12.    
  13. def isLowIn(s):
  14.     for i in s:
  15.         if i.islower():
  16.             return True
  17.     else:
  18.         return False

  19. def isCapIn(s):
  20.     for i in s:
  21.         if i.isupper():
  22.             return True
  23.     else:
  24.         return False

  25. def isNotRepeat3(s):
  26.     for i in set(s):
  27.         if i * 3 in s:
  28.             return False
  29.     else:
  30.         return True

  31. def allRepeat3(s):
  32.     r = []
  33.     while not isNotRepeat3(s):
  34.         for i in s:
  35.             for j in range(len(s), 2, -1):
  36.                 if i * j in s:
  37.                     for k in range(s.count(i * j)):
  38.                         r.append(i * j)
  39.                     s = s.replace(i * j, "")
  40.                     break
  41.     return sorted(r, key=lambda x:len(x), reverse=True)

  42. def run(s):
  43.     r = sum([isLengthEnough(s), isNumIn(s), isLowIn(s), isCapIn(s), isNotRepeat3(s)])
  44.     if r == 5:
  45.         result = 0
  46.     elif sum([isLengthEnough(s), isNotRepeat3(s)]) == 0:
  47.         res1 = 6 - len(s) if len(s) < 6 else len(s) - 20
  48.         t, flg, allR = 0, False, allRepeat3(s)
  49.         for i in allR:
  50.             if flg:
  51.                 t += len(s) - len(allR[0])
  52.                 break
  53.             elif not flg and len(i) > 20:
  54.                 flg = True
  55.                 t += len(i) - 20 + (20 // 3)
  56.             else:
  57.                 t += len(i) // 3
  58.         res2 = t if t > 3 - r else 3 - r
  59.         result = res1 if res1 > res2 else res2
  60.     elif not isLengthEnough(s):
  61.         t = 6 - len(s) if len(s) < 6 else len(s) - 20
  62.         result = t if t > 4 - r else 4 - r
  63.     elif not isNotRepeat3(s):
  64.         t = 0
  65.         for i in allRepeat3(s):
  66.             t += len(i) // 3
  67.         result = t if t > 4 - r else 4 - r
  68.     else:
  69.         result = 5 - r
  70.     return result

  71. if __name__ == "__main__":
  72.     password = input("输入密码:")
  73.     print("密码变强所需的最少步骤:", run(password))
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2021-10-16 18:30:02 | 显示全部楼层
本帖最后由 Stubborn 于 2021-10-16 18:40 编辑

乍看很简单,其实很难 输入数据无限制吗?提的问题没有漏什么东西把
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-10-16 19:57:49 | 显示全部楼层
我的代码仅供参考,你的题目相当有水准,我喜欢
  1. def isRepeating(password: str) -> int:
  2.         res = 0
  3.         a = password[0]
  4.         temp = -1
  5.         for n, p in enumerate(password):
  6.                 if n:
  7.                         if a == p:
  8.                                 temp += 1
  9.                         elif temp > 0:
  10.                                 res += temp
  11.                                 temp = -1
  12.                                 a = p
  13.                         else:
  14.                                 temp = -1
  15.                                 a = p
  16.         return res if temp < 1 else res+temp

  17. def isInsufficient(password: str) -> int:
  18.         res = 0
  19.         return res if len(password) >= 6 and len(password) <= 20 else 6-len(password) if len(password) < 6 else len(password)-20

  20. def isConditional(password: str) -> int:
  21.         if len(password) < 4: return 0
  22.         digit = False
  23.         bigCap = False
  24.         smallCap = False
  25.         for i in password:
  26.                 if i.isdigit():
  27.                         digit = True
  28.                 elif i.islower():
  29.                         smallCap = True
  30.                 elif i.isupper():
  31.                         bigCap = True
  32.         return 0 if all([digit, bigCap, smallCap]) else\
  33.                 1 if all([digit, bigCap]) or\
  34.                         all([bigCap, smallCap]) or\
  35.                                 all([digit, smallCap]) else\
  36.                                         2 if digit or bigCap or smallCap else 3

  37. def main():
  38.         password = input("输入密码:")
  39.         res = isRepeating(password) + isInsufficient(password) + isConditional(password)
  40.         print(f"密码变强所需的最少步骤:{res}")

  41. if __name__ == "__main__":
  42.         main()
复制代码
  1. 输入密码:a
  2. 密码变强所需的最少步骤:5

  3. 输入密码:aA1
  4. 密码变强所需的最少步骤:3

  5. 输入密码:1337C0d3
  6. 密码变强所需的最少步骤:0
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-10-16 21:56:30 | 显示全部楼层
本帖最后由 qq1151985918 于 2021-10-17 18:21 编辑

这题目非常弯弯绕,即使我几经修改仍然认为可能存在BUG,如果错误请提供案例
  1. def isLengthEnough(s):
  2.     if 6 <= len(s) <= 20:
  3.         return True
  4.     else:
  5.         return False

  6. def isNumIn(s):
  7.     for i in s:
  8.         if i.isdigit():
  9.             return True
  10.     else:
  11.         return False
  12.    
  13. def isLowIn(s):
  14.     for i in s:
  15.         if i.islower():
  16.             return True
  17.     else:
  18.         return False

  19. def isCapIn(s):
  20.     for i in s:
  21.         if i.isupper():
  22.             return True
  23.     else:
  24.         return False

  25. def isNotRepeat3(s):
  26.     for i in set(s):
  27.         if i * 3 in s:
  28.             return False
  29.     else:
  30.         return True

  31. def allRepeat3(s):
  32.     r = []
  33.     while not isNotRepeat3(s):
  34.         for i in s:
  35.             for j in range(len(s), 2, -1):
  36.                 if i * j in s:
  37.                     for k in range(s.count(i * j)):
  38.                         r.append(i * j)
  39.                     s = s.replace(i * j, "")
  40.                     break
  41.     return sorted(r, key=lambda x:len(x), reverse=True)

  42. def run(s):
  43.     r = sum([isLengthEnough(s), isNumIn(s), isLowIn(s), isCapIn(s), isNotRepeat3(s)])
  44.     if r == 5:
  45.         result = 0
  46.     elif sum([isLengthEnough(s), isNotRepeat3(s)]) == 0:
  47.         res1 = 6 - len(s) if len(s) < 6 else len(s) - 20
  48.         t, flg, allR = 0, False, allRepeat3(s)
  49.         for i in allR:
  50.             if flg:
  51.                 t += len(s) - len(allR[0])
  52.                 break
  53.             elif not flg and len(i) > 20:
  54.                 flg = True
  55.                 t += len(i) - 20 + (20 // 3)
  56.             else:
  57.                 t += len(i) // 3
  58.         res2 = t if t > 3 - r else 3 - r
  59.         result = res1 if res1 > res2 else res2
  60.     elif not isLengthEnough(s):
  61.         t = 6 - len(s) if len(s) < 6 else len(s) - 20
  62.         result = t if t > 4 - r else 4 - r
  63.     elif not isNotRepeat3(s):
  64.         t = 0
  65.         for i in allRepeat3(s):
  66.             t += len(i) // 3
  67.         result = t if t > 4 - r else 4 - r
  68.     else:
  69.         result = 5 - r
  70.     return result

  71. if __name__ == "__main__":
  72.     password = input("输入密码:")
  73.     print("密码变强所需的最少步骤:", run(password))
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-10-16 23:14:16 | 显示全部楼层
傻眼貓咪 发表于 2021-10-16 19:57
我的代码仅供参考,你的题目相当有水准,我喜欢

我测试楼主代码,发现一些BUG,提供案例如下
另外希望楼主从你的角度看下我代码是否还有BUG
我已经修改七八次了,仍然感觉可能会有BUG,但是没找出,希望楼主看看
如果发现BUG请提供下案例
  1. 输入密码:aaaaa
  2. 密码变强所需的最少步骤:6
  3. 输入密码:aaaa
  4. 密码变强所需的最少步骤:6
  5. 输入密码:aaa
  6. 密码变强所需的最少步骤:4
  7. 输入密码:aaabbbbbb111111
  8. 密码变强所需的最少步骤:10
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-10-17 07:40:06 | 显示全部楼层
qq1151985918 发表于 2021-10-16 23:14
我测试楼主代码,发现一些BUG,提供案例如下
另外希望楼主从你的角度看下我代码是否还有BUG
我已经修改 ...

十分感谢层主的回答,您的代码我测试过,已经十分完美了。但好像还是有BUG。
比如我输入30个字母a:

输入密码:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
密码变强所需的最少步骤: 10

貌似,修改密码的步骤不止10步,因为除了删除10个多余字符,还要改变成数字,大写。
望层主能解答。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-10-17 07:40:47 | 显示全部楼层
傻眼貓咪 发表于 2021-10-16 19:57
我的代码仅供参考,你的题目相当有水准,我喜欢

谢谢这位层主的解答
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-10-17 07:42:52 | 显示全部楼层
Stubborn 发表于 2021-10-16 18:30
乍看很简单,其实很难 输入数据无限制吗?提的问题没有漏什么东西把

对啊,乍一看不难,但是细想下有很多条件要考虑。题上给的条件就这么多。。。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-10-17 17:52:06 | 显示全部楼层    本楼为最佳答案   
本帖最后由 qq1151985918 于 2021-10-17 18:22 编辑
icecocotea 发表于 2021-10-17 07:40
十分感谢层主的回答,您的代码我测试过,已经十分完美了。但好像还是有BUG。
比如我输入30个字母a:


我又修改了,你再试试看
  1. def isLengthEnough(s):
  2.     if 6 <= len(s) <= 20:
  3.         return True
  4.     else:
  5.         return False

  6. def isNumIn(s):
  7.     for i in s:
  8.         if i.isdigit():
  9.             return True
  10.     else:
  11.         return False
  12.    
  13. def isLowIn(s):
  14.     for i in s:
  15.         if i.islower():
  16.             return True
  17.     else:
  18.         return False

  19. def isCapIn(s):
  20.     for i in s:
  21.         if i.isupper():
  22.             return True
  23.     else:
  24.         return False

  25. def isNotRepeat3(s):
  26.     for i in set(s):
  27.         if i * 3 in s:
  28.             return False
  29.     else:
  30.         return True

  31. def allRepeat3(s):
  32.     r = []
  33.     while not isNotRepeat3(s):
  34.         for i in s:
  35.             for j in range(len(s), 2, -1):
  36.                 if i * j in s:
  37.                     for k in range(s.count(i * j)):
  38.                         r.append(i * j)
  39.                     s = s.replace(i * j, "")
  40.                     break
  41.     return sorted(r, key=lambda x:len(x), reverse=True)

  42. def run(s):
  43.     r = sum([isLengthEnough(s), isNumIn(s), isLowIn(s), isCapIn(s), isNotRepeat3(s)])
  44.     if r == 5:
  45.         result = 0
  46.     elif sum([isLengthEnough(s), isNotRepeat3(s)]) == 0:
  47.         res1 = 6 - len(s) if len(s) < 6 else len(s) - 20
  48.         t, flg, allR = 0, False, allRepeat3(s)
  49.         for i in allR:
  50.             if flg:
  51.                 t += len(s) - len(allR[0])
  52.                 break
  53.             elif not flg and len(i) > 20:
  54.                 flg = True
  55.                 t += len(i) - 20 + (20 // 3)
  56.             else:
  57.                 t += len(i) // 3
  58.         res2 = t if t > 3 - r else 3 - r
  59.         result = res1 if res1 > res2 else res2
  60.     elif not isLengthEnough(s):
  61.         t = 6 - len(s) if len(s) < 6 else len(s) - 20
  62.         result = t if t > 4 - r else 4 - r
  63.     elif not isNotRepeat3(s):
  64.         t = 0
  65.         for i in allRepeat3(s):
  66.             t += len(i) // 3
  67.         result = t if t > 4 - r else 4 - r
  68.     else:
  69.         result = 5 - r
  70.     return result

  71. if __name__ == "__main__":
  72.     password = input("输入密码:")
  73.     print("密码变强所需的最少步骤:", run(password))
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-10-17 18:28:49 | 显示全部楼层
抱歉,上边的代码我又修改了四五次,仍然发现有BUG,待我再考虑一下,这是哪里的题目?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-10-19 04:30:03 | 显示全部楼层
qq1151985918 发表于 2021-10-17 18:28
抱歉,上边的代码我又修改了四五次,仍然发现有BUG,待我再考虑一下,这是哪里的题目?

辛苦了哥们儿,这个题目是我一个老师给的习题集里面的。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-10-20 17:54:36 | 显示全部楼层
本帖最后由 Stubborn 于 2021-10-21 16:07 编辑
icecocotea 发表于 2021-10-17 07:42
对啊,乍一看不难,但是细想下有很多条件要考虑。题上给的条件就这么多。。。


越想越复杂,如 aa + c*20 + bbd 和 bbd + c*20 + a,这种情况,就面临一个问题,程序应该如何判断通过最少步骤 去“操作”一段适合的密码,从前面,后面,还是中间“操作”一部分呢?


我觉得,这边问题,首先要解决的是种类的检查,其次最重要的是如何处理重复问题
并且我们对密码的操作优先度,应该是替换(替换步骤大于2,可以不用考虑种类问题),删减


其次需要检查密码的有效最大长度。根据密码有效的最大长度已经种类的检查的结果进行操作

假如,我有的程序对一串字符串(aaccccccccccccccccccccbbdaacccccccvbcdeeeeeffff)处理后,可以得到两个列表

  1. a = [2, 20, 5, 7, 4, 5, 4]
  2. b = [0, 6, 0, 2, 0, 1, 1]
复制代码


第一列,有效和无效长度,aa ,  ccccccc, vbcd, eeee, ffff
第二列,如果是有效长度则不需要操作,如果是无效长度,需要操作多少步才能变为有效长度。


这样一来,问题转化成了,寻找一个连续数组,什么样的连续数组是我们的想要的?

从我们看来,这个字符串最短步骤应该是,进行3次替换,即取 5+ 7 + 4 +5,可以获取足够合适的密码长度,其他的字符都可以删减。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-10-21 15:45:18 | 显示全部楼层
icecocotea 发表于 2021-10-17 07:40
十分感谢层主的回答,您的代码我测试过,已经十分完美了。但好像还是有BUG。
比如我输入30个字母a:

应该是替换6个,以及删除10个,总计16步骤
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-6-14 15:57

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表