作者:Mintimate
Mintimate's Blog,只为与你分享
如今,用户在网络上越来越重视个人隐私和信息安全,抛开服务提供商的问题,我们用户端,设置一个好的用户名和密码很重要。
这个时候,就需要设置一个强密码,用于避免非法用户”撞库“。同时,应该尽可能设置不同的密码。
那么?如何生成随机的强密码呢?如何系统检测用户的密码是否强呢?
首先,我们明确强密码的组成??:
之后,我们要考虑如何生成随机字符:
接下来,我们就使用代码实现上述需求: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!!
这样的密码出现,我们需要对生成的密码进行进一步的逻辑判断。这些判断,上文的正则判断无法直接处理,需要我们用逻辑代码进行进一步的生成和处理。
连续字符判断,其实是很简单的。主要有两个思路:
在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)
其中,考虑到一些网站会对密码格式有所限制,所以这边进行选择处理:
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
Mintimate's Blog,只为与你分享
TIOBE 公布了 2021 年 3 月的编程语言排行榜。 本月 TIOBE 指数没有什么有趣的变...
在Python开发过程中,我们难免会遇到多重条件判断的情况的情况,此时除了用很多...
想了解更多内容,请访问: 51CTO和华为官方战略合作共建的鸿蒙技术社区 https://...
本文转载自微信公众号「bugstack虫洞栈」,作者小傅哥 。转载本文请联系bugstack...
前言 统计科学家使用交互式的统计工具(比如R)来回答数据中的问题,获得全景的认...
近几年,互联网行业蓬勃发展,在互联网浪潮的冲击下,互联网创业已成为一种比较...
溢价 域名 的续费价格如何?通常来说,因为溢价域名的价值高于普通域名,所以溢...
背景 我们知道 如果在Kubernetes中支持GPU设备调度 需要做如下的工作 节点上安装...
基本介绍 给定 n 个权值作为 n 个叶子节点,构造一颗二叉树,若该树的带权路径长...
本文转载自公众号读芯术(ID:AI_Discovery)。 这一刻你正在应对什么挑战?这位前...