icecocotea 发表于 2021-10-16 15:26:38

Python判断密码强度问题

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

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


刚学一个月,就遇到这样的难题,希望大佬们的帮助。

Stubborn 发表于 2021-10-16 18:30:02

本帖最后由 Stubborn 于 2021-10-16 18:40 编辑

乍看很简单,其实很难{:5_99:} 输入数据无限制吗?提的问题没有漏什么东西把

傻眼貓咪 发表于 2021-10-16 19:57:49

我的代码仅供参考,你的题目相当有水准,我喜欢
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-16 21:56:30

本帖最后由 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))

qq1151985918 发表于 2021-10-16 23:14:16

傻眼貓咪 发表于 2021-10-16 19:57
我的代码仅供参考,你的题目相当有水准,我喜欢

我测试楼主代码,发现一些BUG,提供案例如下
另外希望楼主从你的角度看下我代码是否还有BUG
我已经修改七八次了,仍然感觉可能会有BUG,但是没找出,希望楼主看看
如果发现BUG请提供下案例
输入密码:aaaaa
密码变强所需的最少步骤:6
输入密码:aaaa
密码变强所需的最少步骤:6
输入密码:aaa
密码变强所需的最少步骤:4
输入密码:aaabbbbbb111111
密码变强所需的最少步骤:10

icecocotea 发表于 2021-10-17 07:40:06

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

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

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

貌似,修改密码的步骤不止10步,因为除了删除10个多余字符,还要改变成数字,大写。
望层主能解答。

icecocotea 发表于 2021-10-17 07:40:47

傻眼貓咪 发表于 2021-10-16 19:57
我的代码仅供参考,你的题目相当有水准,我喜欢

谢谢这位层主的解答

icecocotea 发表于 2021-10-17 07:42:52

Stubborn 发表于 2021-10-16 18:30
乍看很简单,其实很难 输入数据无限制吗?提的问题没有漏什么东西把

对啊,乍一看不难,但是细想下有很多条件要考虑。题上给的条件就这么多。。。{:5_99:}

qq1151985918 发表于 2021-10-17 17:52:06

本帖最后由 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))

qq1151985918 发表于 2021-10-17 18:28:49

抱歉,上边的代码我又修改了四五次,仍然发现有BUG,待我再考虑一下,这是哪里的题目?

icecocotea 发表于 2021-10-19 04:30:03

qq1151985918 发表于 2021-10-17 18:28
抱歉,上边的代码我又修改了四五次,仍然发现有BUG,待我再考虑一下,这是哪里的题目?

辛苦了哥们儿,这个题目是我一个老师给的习题集里面的。

Stubborn 发表于 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,可以不用考虑种类问题),删减


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

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

a =
b =


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


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

从我们看来,这个字符串最短步骤应该是,进行3次替换,即取 5+ 7 + 4 +5,可以获取足够合适的密码长度,其他的字符都可以删减。

Stubborn 发表于 2021-10-21 15:45:18

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



应该是替换6个,以及删除10个,总计16步骤
页: [1]
查看完整版本: Python判断密码强度问题