专栏首页Mintimate's Blog详解:Python代码实现强密码判断与生成
原创

详解:Python代码实现强密码判断与生成

封面嗷

作者:Mintimate

博客:https://www.mintimate.cn

Mintimate's Blog,只为与你分享

前言

如今,用户在网络上越来越重视个人隐私和信息安全,抛开服务提供商的问题,我们用户端,设置一个好的用户名和密码很重要。

这个时候,就需要设置一个强密码,用于避免非法用户”撞库“。同时,应该尽可能设置不同的密码。

那么?如何生成随机的强密码呢?如何系统检测用户的密码是否强呢?

强密码

首先,我们明确强密码的组成🤔:

  • 包含数字、大小写字母和特殊符号
  • 尽量减少重复字符
  • 尽量避免连续字符

之后,我们要考虑如何生成随机字符:

  • 使用random随机数

接下来,我们就使用代码实现上述需求:Python,使用的库函数为:

  • re:Python的标准库内容,使代码可以使用正则表达式
  • random:Python的标准库内容,使代码可以调用随机数相关的内容。

其他语言,如:Java、C++等均有类似库/外部包支持正则表达式和随机数,可以按本文思路覆写。

正则判断

如何判断字符串是否为强密码呢?第一步当然是判断是否包含数字和大小写字母以及特殊字符了,而判断这些内容,当时用正则表达式比较好。

为什么用正则

为什么我会引用正则表达式?主要原因:

  • 极大程度精简代码
  • 正则规则,很容易判断字符串是否符合密码规则

举个例子,我需要判断字符串内字符是否有数字,可能的Python代码为(不使用正则表达式):

def is_number(s):
    try:  # 如果能运行float(s)语句,返回True(字符串s是浮点数)
        float(s)
        return True
    except ValueError:  # ValueError为Python的一种标准异常,表示"传入无效的参数"
        pass  # 如果引发了ValueError这种异常,不做任何事情(pass:不做任何事情,一般用做占位语句)
    return False
    
def toWords(s):
    for i in s:
        if is_number(i):
            print("包含数字:"+i)

而使用正则表达式就很简单了:

import re
re.findall(r'\d',str)

可以看到,这精简程度,应该是有目共睹了。

源代码
效果

如果你之前没接触正则表达式,可以看我这篇文章:

匹配数字

所以,匹配数字:

# 判断是否包含数字
def hasNumber(pwd):
    if (re.search(r'\d', pwd)):
        return True
    else:
        return False

使用search方法,判断是否含有数字类型。

匹配英文

匹配英文,也很简单:

# 判断是否含有小写字母
def hasLowLetter(pwd):
    if (re.search(r'[a-z]', pwd)):
        return True
    else:
        return False

# 判断是否包含大写字母
def hasUpPLetter(pwd):
    if (re.search(r'[A-Z]', pwd)):
        return True
    else:
        return False

匹配特殊字符

匹配特殊字符,这边有一点点“脑筋急转弯”,首先,我们肯定知道\w是指代英文和数字,那么\W就是非英文和非数字,也就是特殊字符了。

# 判断是否包含特殊字符
def hasSpecial(pwd):
    if (re.search(r'\W', pwd)):
        return True
    else:
        return False

字符逻辑

正则判断,并不能判断字符逻辑,强密码的二三步:

  • 尽量减少重复字符
  • 尽量避免连续字符

进而避免出现:

aaBBcc@@
aaBBcc!!
ABCabc!!

这样的密码出现,我们需要对生成的密码进行进一步的逻辑判断。这些判断,上文的正则判断无法直接处理,需要我们用逻辑代码进行进一步的生成和处理。

连续字符判断

连续字符判断,其实是很简单的。主要有两个思路:

  • 使用字符的Unicode编码,判断是否为连续字符
  • 将字符转换为Ascii值,判断字符的Ascii值是否连续

在Python内,可以使用chr()和ord()函数方法来实现:

  • chr():将字符转码为ascii编码返回(Python3中,转码为十进制Unicode编码返回)
  • ord():将十进制编码编译为字符

比如:

# 编码“你”为十进制Unicode
print(ord("你"))
# 编码“你”为Unicode
print(hex(ord("你")))

输出结果:

20320
0x4f60

所以我们判断是否为连续字符:

if currentCharCode == chr(ord(prevCharCode) + 1)

进一步封装为方法:

# 判断密码是否连续
def isSeries(pwd):
    if pwd and (len(pwd) > 0):
        # 自身算起
        ascSeriesCount = 1
        descSeriesCount = 1
        # 存在顺序型的连续性的字符串
        for i in range(len(pwd)):
            currentCharCode = pwd[i]
            if i == 0:
                prevCharCode = ""
            else:
                prevCharCode = pwd[i - 1]
                if currentCharCode == chr(ord(prevCharCode) + 1):
                    ascSeriesCount = ascSeriesCount + 1
                    if ascSeriesCount == seriesCount:
                        return True
                else:
                    ascSeriesCount = 1

        # 存在逆序性的连续性的字符串*/
        for i in range(len(pwd) - 1):
            currentCharCode = pwd[i]
            if (i - 1) >= 0:
                prevCharCode = pwd[i - 1]
            else:
                prevCharCode = ""
            if chr(ord(currentCharCode) + 1) == prevCharCode:
                descSeriesCount = descSeriesCount + 1
                if descSeriesCount == seriesCount:
                    return True
            else:
                descSeriesCount = 1
    return False

重复字符判断

重复字符判断,就需要迭代器遍历和计数器统计了。不过效率有点低:

# 判断密码是否包含重复字段
def isRepeate(pwd):
    if pwd and (len(pwd) > 0):
        for i in range(len(pwd)):
            currentChar = pwd[i]
            if i == 0:
                prevChar = ""
            else:
                prevChar = pwd[i - 1]
            if currentChar == prevChar:
                return True
    return False

最终效果

在线演示

最终,我用JavaScript也通过本文思路,再现了本文Python实现的过程,大家如果觉得图文不形象,可以亲自体验:

在线演示

Tips:网站的强密码生成,使用的是JavaScript实现的,有机会出个JavaScript实现的教程嗷。

代码解析

上文的正则表达式集中解决判断问题,这边梳理如何生成问题。

首先,我们设置一个方法体:

def getPWD(enableNumber, enableLetter, enableSpecial,passwordLength)

其中,考虑到一些网站会对密码格式有所限制,所以这边进行选择处理

  • enableNumber:生成密码是否需要有数字
  • enableLetter:生成密码是否需要有数字
  • enableSpecial:生成密码是否需要特殊字符
  • passwordLength:生成密码长度

为了保证生产各个元素,有出场的机会,我们限定一下最短长度:

if passwordLength<3:
    return "错误!密码长度不得少于3位"

之后,创建字符集:

numeric = '0123456789'
stringLetter = string.ascii_letters
punctuation = '!@#$%^&*()_+~`|}{[]\:;?><,./-='
# 生成的密码
password = ""
# 用于插空
character = ""

配合随机数生成:

while len(password) < passwordLength:
    if enableNumber :
        entity0 = random.randint(0, len(numeric) - 1)
        character = numeric[entity0] + character
    if enableLetter:
        entity1 = random.randint(0, len(string.ascii_letters) - 1)
        character = stringLetter[entity1] + character
    if enableSpecial:
        entity2 = random.randint(0, len(punctuation) - 1)
        character = punctuation[entity2] + character

    password = password + character
    character = ""

因为random实际上是伪随机数,所以我们重新打乱字符并格式化为字符串:

# 生成的密码转换为list
password = list(password)
# 使用random重新打乱list集合
random.shuffle(password)
# 重新拼接为字符串
newPassword = "".join(password)

总结📝

强密码的生成和判断就到这里,揉的比较杂碎。如果需要复刻,可能需要一些时间。

本文着重处理:

  • 强密码判断(主要是正则匹配和逻辑代码的使用)
  • 强密码生成(随机数的使用)

作者:Mintimate

博客:https://www.mintimate.cn

Mintimate's Blog,只为与你分享

原创声明,本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

登录 后参与评论
0 条评论

相关文章

  • Python之Metaclass元类详解与实战:50行代码实现【智能属性】

    由于工作需要,最近学习Python元编程方面的东西。本文介绍了Metaclass的一个示例,是笔者在学习过程中编写的一个小例子,虽然只有50行代码,但其中涉及了...

    用户5410317
  • Python编程快速上手——强口令检测算法案例分析

    密码安全性在线检测: http://tools.zalou.cn/password/my_password_safe

    砸漏
  • PyQt的一个UI单元测试框架思路

    專 欄 ❈丁果,Python中文社区作者。对django、pyqt、opencv、tornado感兴趣。 GitHub:https://github.com/...

    Python中文社区
  • 灵魂追问 | 教程那么多,你……看完了吗?

    机器之心
  • Python3 jupyter notebook 服务器搭建过程

    以上所述是小编给大家介绍的Python3 jupyter notebook 服务器搭建,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。...

    砸漏
  • Python目录

            整个IT产业只是在共同做好一件事--------信息(数据)的处理,对有用信息提取,存、增、删、改、查,然后更好的呈现在客户面前。 本文主要涵括...

    py3study
  • Python后端技术栈(一)

    Happiness is a way of travel. Not a destination.

    小闫同学啊
  • [网络安全] 二十九.小白渗透之路及Web渗透简单总结(YOU老师)

    这是作者2月27日学习i春秋YOU老师直播分享的渗透技术知识,本次分享的主题是《小白的渗透技术成长之路》。主讲人YOU老师,干货满满,全面剖析了渗透测试的工作、...

    Eastmount
  • Python笔记·第一章——Python基础(一)

    Python的简介 1、Python的由来与版本 1.1 python的由来 python的创始人为吉多·范罗苏姆(Guido van Rossum)。1989...

    企鹅号小编
  • Python基础(一)

    一、Python的简介 1、Python的由来与版本 1.1 python的由来 python的创始人为吉多·范罗苏姆(Guido van Rossum)。1...

    人生不如戏
  • Python之路,Day1 - Python基础1

    python的创始人为吉多·范罗苏姆(Guido van Rossum)。1989年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时间,决心开发一个新的脚本解...

    超蛋lhy
  • webshell指纹-ssdeep

    最近一段时间的任务就是研究webshell的检测,感觉安全真是没有止境,尤其还是处于防御方,安全策略的制定 任重而道远。

    七夜安全博客
  • Pytest框架集成Allure定制测试报告详解(一)

    Allure是一款非常轻量级并且非常灵活的开源测试报告生成框架。它支持绝大多数测试框架, 例如TestNG、Pytest、JUint等。它简单易用,易于集成。下...

    王大力测试进阶之路
  • python实现密码强度校验

    本文实例为大家分享了python实现密码强度校验的具体代码,供大家参考,具体内容如下

    砸漏
  • 详解web缓存(转)

    缓存分为服务端侧(server side,比如 Nginx、Apache)和客户端侧(client side,比如 web browser)。常用的服务端缓存有...

    山河木马
  • 网络安全自学篇(十六)| Python攻防之弱口令、自定义字典生成及网站暴库防护

    免责声明:本公众号发布的文章均转载自互联网或经作者投稿授权的原创,文末已注明出处,其内容和图片版权归原网站或作者本人所有,并不代表安全+的观点,若有无意侵权或转...

    天钧

扫码关注腾讯云开发者

领取腾讯云代金券