鱼C论坛

 找回密码
 立即注册
查看: 3807|回复: 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:


我又修改了,你再试试看
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([isLengthEnough(s), isNumIn(s), isLowIn(s), isCapIn(s), isNotRepeat3(s)])
    if r == 5:
        result = 0
    elif sum([isLengthEnough(s), isNotRepeat3(s)]) == 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[0])
                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))
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

乍看很简单,其实很难 输入数据无限制吗?提的问题没有漏什么东西把
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-10-16 19:57:49 | 显示全部楼层
我的代码仅供参考,你的题目相当有水准,我喜欢
def isRepeating(password: str) -> int:
        res = 0
        a = password[0]
        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([digit, bigCap, smallCap]) else\
                1 if all([digit, bigCap]) or\
                        all([bigCap, smallCap]) or\
                                all([digit, smallCap]) 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
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 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([isLengthEnough(s), isNumIn(s), isLowIn(s), isCapIn(s), isNotRepeat3(s)])
    if r == 5:
        result = 0
    elif sum([isLengthEnough(s), isNotRepeat3(s)]) == 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[0])
                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))
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

我测试楼主代码,发现一些BUG,提供案例如下
另外希望楼主从你的角度看下我代码是否还有BUG
我已经修改七八次了,仍然感觉可能会有BUG,但是没找出,希望楼主看看
如果发现BUG请提供下案例
输入密码:aaaaa
密码变强所需的最少步骤:6
输入密码:aaaa
密码变强所需的最少步骤:6
输入密码:aaa
密码变强所需的最少步骤:4
输入密码:aaabbbbbb111111
密码变强所需的最少步骤:10
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

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

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

貌似,修改密码的步骤不止10步,因为除了删除10个多余字符,还要改变成数字,大写。
望层主能解答。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

谢谢这位层主的解答
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

对啊,乍一看不难,但是细想下有很多条件要考虑。题上给的条件就这么多。。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 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([isLengthEnough(s), isNumIn(s), isLowIn(s), isCapIn(s), isNotRepeat3(s)])
    if r == 5:
        result = 0
    elif sum([isLengthEnough(s), isNotRepeat3(s)]) == 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[0])
                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))
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

使用道具 举报

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

辛苦了哥们儿,这个题目是我一个老师给的习题集里面的。
想知道小甲鱼最近在做啥?请访问 -> 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)处理后,可以得到两个列表
a = [2, 20, 5, 7, 4, 5, 4]
b = [0, 6, 0, 2, 0, 1, 1]

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


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

从我们看来,这个字符串最短步骤应该是,进行3次替换,即取 5+ 7 + 4 +5,可以获取足够合适的密码长度,其他的字符都可以删减。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

应该是替换6个,以及删除10个,总计16步骤
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-1-12 22:55

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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