我想出了:
re.findall("([a-fA-F\d]*)", data)
但这不是很简单,有没有更好的方法来获取所有 MD5 哈希码?
好吧,因为 md5 只是一个 32 位十六进制数字的字符串,所以您可以添加到表达式中的只是检查“32 位数字”,也许是这样的?
re.findall(r"([a-fA-F\d]{32})", data)
在 Python 中使用正则表达式时,您应该几乎总是使用原始字符串语法r"..."
:
re.findall(r"([a-fA-F\d]{32})", data)
这将确保字符串中的反斜杠不会被正常的 Python 转义解释,而是传递给re.findall
函数,以便它可以\d
逐字查看。在这种情况下,您很幸运\d
没有被 Python 转义解释,而是类似的东西\b
(在 Python 转义和正则表达式中具有完全不同的含义)。
有关更多信息,请参阅re
模块文档。
这是比其他一些解决方案更好的方法:
re.findall(r'(?i)(?<![a-z0-9])[a-f0-9]{32}(?![a-z0-9])', data)
这确保匹配必须是 32 个十六进制数字字符的字符串,但不包含在更大的其他字母数字字符字符串中。对于所有其他解决方案,如果有一个由 37 个连续十六进制组成的字符串,则该模式将匹配前 32 个并将其称为匹配,或者如果有一个由 64 个十六进制组成的字符串,它将把它分成两半并将每一半作为独立的匹配匹配。排除这些是通过lookahead 和lookbehind 断言完成的,它们是非捕获的,不会影响匹配的内容。
还要注意 (?i) 标志,这将使模式不区分大小写,从而节省一点打字,并且将整个模式包装在括号中是多余的。
这是一个相当迂腐的表达:
r"\b([a-f\d]{32}|[A-F\d]{32})\b"
但是,如果这还不够好,因为您知道获得全数字 MD5 校验和的机会只有 3402823 分之一,而获得全字母数字 MD5 校验和的机会只有 42 万亿分之一,那么您知道我们可能应该对那些有效的总和说 FU,也不接受任何不是字母数字的东西:
r"\b(?!^[\d]*$)(?!^[a-fA-F]*$)([a-f\d]{32}|[A-F\d]{32})\b"
00000000000000000000000000000000 # not MD5
01110101001110011101011010101001 # not MD5
ffffffffffffffffffffffffffffffff # not MD5
A32efC32c79823a2123AA8cbDDd3231c # not MD5
affa687a87f8abe90d9b9eba09bdbacb # is MD5
C787AFE9D9E86A6A6C78ACE99CA778EE # is MD5
please like and subscribe to my # not MD5
是的,我在工作中非常无聊。
由于 MD5 正好由 32 个十六进制字符组成,并且有时哈希使用小写字母表示,因此也应该考虑它们。
下面的示例针对四个不同的字符串进行了测试:
900e3f2dd4efc9892793222d7a1cee4a
AC905DD4AB2038E5F7EABEAE792AC41B
900e3f2dd4efc9892793222d7a1cee4a900e3f2dd4efc9892793222d7a1cee4a
900e3f2dd4efc9892793222d7a1cee4a4a4a4
validHash = re.finditer(r'(?=(\b[A-Fa-f0-9]{32}\b))', datahere)
result = [match.group(1) for match in validHash]
if result:
print "Valid MD5"
else:
print "NOT a Valid MD5"
“([a-fA-F\d]{32})” 要求它的长度为 32 个字符怎么样?