Check if string is an MD5 Hash
52,562
Solution 1
You can check using the following function:
function isValidMd5($md5 ='')
{
return preg_match('/^[a-f0-9]{32}$/', $md5);
}
echo isValidMd5('5d41402abc4b2a76b9719d911017c592');
The MD5 (Message-digest algorithm) Hash is typically expressed in text format as a 32 digit hexadecimal number.
This function checks that:
- It contains only letters and digits (a-f, 0-9).
- It's 32 characters long.
Solution 2
Maybe a bit faster one:
function isValidMd5($md5 ='') {
return strlen($md5) == 32 && ctype_xdigit($md5);
}
Comments
-
kmoney12 almost 2 years
I accidentally stopped hashing passwords before they were stored, so now my database has a mix of MD5 Passwords and unhashed passwords.
I want to loop through and hash the ones that are not MD5. Is it possible to check if a string is an MD5 hash?
-
Gromski over 11 yearsThe
!empty
check is entirely superfluous there. -
inhan over 11 yearsWhy do you need to check if it's empty? Won't it already return false if
preg_match()
does not match? -
kmoney12 over 11 yearsWhat's the accuracy on this? Can I trust it completely? Sorry don't know too much about regular expressions.
-
tsujp over 11 yearsIt will return 0 if it doesn't match, synonymous with
false
. +vote @inhan -
inhan over 11 years@hellohellosharp yeah, documentation reads
Returns the hash as a 32-character hexadecimal number.
which means the value should consist of0-9
anda-f
characters only and it should be 32 characters long. -
tsujp over 11 years@hellohellosharp I only started regular expressions yesterday but this
preg_match('/^[a-f0-9]{32}$/'
is stating thata string of 32 characters long can only contain letters a-f (hex) and numbers 0-9. There are a few reasons why you can trust this, and cannot. 1. MD5 is 32 characters long, 2. MD5 contains only lowercase alpha characters a through f. Anyone can fake an MD5 hash, there is no surefire method to detect if text, information, is from a certain source unless you go into things like secure login cookies etc..., which is a completely different subject. -
tsujp over 11 years@hellohellosharp Long story short, this method is fine for analyzing the format of the string you are checking.
-
inhan over 11 years@hellohellosharp something important is, make sure your
MD5()
call does not include the second parameter that can be converted intotrue
otherwise this function will not help you. Check theraw_output
(2nd) parameter inMD5()
documentation. -
Jan Doggen over 10 years@hellohellosharp Nobody seems to have answered your 'accuracy' comment yet: this function verifies that a string is in the format of an MD5 hash, it does not validate that it is an actual hashed password - that cannot be determined. It will also return true if one of your unhashed passwords meets the format requirements - but that is unlikely.
-
kyle about 10 yearsThanks! I used it like so: if (!preg_match('/^[a-f0-9]{32}$/', $md5)) {return false;} (not for a password, lol!)
-
laurent about 10 years+1, probably faster, and also more readable than the regex. It might do an early exit on the strlen call for most invalid strings, then I suspect the ctype_xdigit call is faster than running a regex engine.
-
l00k about 10 yearsNote that you can't be 100% sure that string which pass this test is md5 or plain text password. Unlikely, but someone may have a password similar to the md5 format.
-
RaphaelH about 10 years@non: I do not agree with you. You can be 100% sure that the string is a valid md5 hash. Whether the string was intended to be a valid md5 hash is a whole another point..
-
l00k almost 10 years@RaphaelH you didnt understand me.. "e4bfb280c702635cf71d46a0c8c33b96" it may be hashed (md5) password or just plain password. You can't be sure :)
-
RaphaelH almost 10 years@non: Once again, "e4bfb280c702635cf71d46a0c8c33b96" is for 100 percent a valid md5 hash, you can't be sure if it was intended to be one. If it's your password, then it's both valid md5 and your plain password.
-
Jack over 9 yearsWhy are you using an empty string as default parameter?
-
VeeeneX about 9 yearsYes, you can't be 100% sure, that it is md5 string in order to that, you need to use:
!ctype_digit($md5) && ctype_lower($md5) && ctype_alpha($md5)
-
Cliff Burton almost 8 years@NullPoiиteя you have a typo: "Its contain only letter and digit (a-z,0-9)" should be "(a-f,0-9)"
-
RaphaelH about 7 years@VeeeneX Answer might be a little late, but what you suggest is just complete bs and I want to clarify that. I am assuming the representation of the md5 hash as hex string as everyone else here does. It can and mostly does contain digits, so !ctype_digit is wrong. It does not have to be lowercase, so ctype_lower is wrong, nothing wrong with uppercase hashes. It can't have characters beyond f, so ctype_alpha is wrong.
-
xZero about 6 yearsFaster only and only if character is shorter than 32. if not, then involves unnecessary function call overhead, in this case strlen
-
xZero about 6 yearsWorth noting is that preg_match might not return boolean but int, therefore your function will not work in eg (if(isValidMd5($hash) === true)). Here is faster version, which also overcomes mentioned problem: sandbox.onlinephpfunctions.com/code/…
-
RaphaelH about 6 years@xZero This is not about 2 function calls versus 1 function call, it's about running a regex engine versus 2 rather lightweight function calls. On my machine the non regex version runs about 75% faster, of course this depends on the input, in my test case random generated, see pastebin.com/BhpPpGyw to try yourself
-
xZero about 6 years@RaphaelH I completely agree with you. I was not trying to say that your approach is slower, although it sounded like that. I just thought it's worth noting circumstances it is faster with.