检查字符串是否为MD5哈希值

51

我不小心在密码存储前停止了哈希处理,所以现在我的数据库中有一些MD5密码和未经哈希处理的密码。

我想循环遍历并对那些不是MD5的密码进行哈希处理。是否可以检查字符串是否为MD5哈希值?


NullPointer的回答是你最好的选择,但除非你已经允许用户保存一个可以达到32个字符长度的密码,否则你仍然无法确定。 - inhan
7
离题了,但MD5算法因为可以轻松计算出所有可能的密钥而被认为在存储密码方面已经“破解”。请参考以下链接了解如何在PHP中使用bcrypt进行哈希处理以及如何安全地存储用户密码:https://dev59.com/4G445IYBdhLWcg3wkLLU 和 https://dev59.com/B3I-5IYBdhLWcg3w-92b 以及 http://www.openwall.com/phpass/。 - tsujp
2个回答

115
您可以使用以下函数进行检查:
function isValidMd5($md5 ='')
{
    return preg_match('/^[a-f0-9]{32}$/', $md5);
}

echo isValidMd5('5d41402abc4b2a76b9719d911017c592');

MD5(消息摘要算法)散列通常以32个十六进制数字的文本格式表示。

此函数检查以下内容:

  1. 它仅包含字母和数字(a-f,0-9)。
  2. 长度为32个字符。

6
为什么需要检查它是否为空?如果preg_match()没有匹配,它不会返回false吗? - inhan
2
@hellohellosharp,文档中写道“以32个十六进制数字的形式返回哈希值”,这意味着该值应仅由0-9a-f字符组成,并且长度应为32个字符。 - inhan
4
目前还没有人回答你关于“准确性”的评论:此函数验证字符串是否符合MD5哈希格式,但它并不能验证它是否是实际的哈希密码-这是无法确定的。如果您的未加密密码之一符合格式要求,它也将返回true-但这是不太可能的。 - Jan Doggen
1
你为什么要使用空字符串作为默认参数? - Jack
1
@NullPoiиteя,您打错了:"“Its contain only letter and digit (a-z,0-9)" 应该是 _“(a-f,0-9)”_。 - Cliff Burton
显示剩余8条评论

46

也许更快一些:

function isValidMd5($md5 ='') {
  return strlen($md5) == 32 && ctype_xdigit($md5);
}

2
+1,可能比正则表达式更快,也更易读。它可能会在大多数无效字符串的strlen调用上进行早期退出,然后我怀疑ctype_xdigit调用比运行正则表达式引擎更快。 - laurent
4
我不同意你的观点。你可以百分之百地确定该字符串是一个有效的 MD5 哈希值。但这个字符串是否本意成为一个有效的 MD5 哈希值是另一回事。 - RaphaelH
10
再次强调,“e4bfb280c702635cf71d46a0c8c33b96” 是一个完全有效的 MD5 哈希值,但您不能确定它是否是有意为之。如果它是您的密码,则既是有效的 MD5 值,也是您的明文密码。 - RaphaelH
1
是的,你不能百分之百确定它是md5字符串,为此,你需要使用:!ctype_digit($md5) && ctype_lower($md5) && ctype_alpha($md5) - VeeeneX
1
@xZero,这不是关于2个函数调用与1个函数调用的问题,而是关于运行正则表达式引擎与运行两个相当轻量级的函数调用之间的区别。在我的机器上,非正则表达式版本运行速度大约快了75%,当然这取决于输入,在我的测试案例中是随机生成的,请参见https://pastebin.com/BhpPpGyw以自行尝试。 - RaphaelH
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接