Regulární výraz bezpečné heslo, aneb jak testovat silná hesla
RegExp strong password je celkem běžnou záležitostí, ale přesto si s tím řada programátorů nedokáže poradit. Tady je jeden návrh mého řešení jak testovat heslo s jedním velkým písmenem, jedním číslem a minimálně 8 znaky. A také způsob jak takové heslo vytvořit.
Na tento článek mne přivedl jeden kolega a způsob jakým tento problém řešil. Jeho řešení ukazuji v následujícím příkladě.
Stanovené podmínky:
- minimálně 8 znaků
- minimálně jedno velké písmeno
- minimálně jedno číslo
- function checkPwd($pwd) {
- if (strlen($pwd)<8) return false;
- if (!preg_match("~[a-z]+~", $pwd)) return false;
- if (!preg_match("~[A-Z]+~", $pwd)) return false;
- if (!preg_match("~[0-9]+~", $pwd)) return false;
- return true;
- }
Bohužel nechtěl mi věřit, že to lze zapsat jedním regexpem a tak musel vzniknout tento článek.
Moje Řešení
- $password=array("SuperSilneHeslo2009", "supersilneheslo2009", "supersilneheslo", "Supersilneheslo2009", "su2009", "Su2009");
- function checkPass($p) {
- $regexp="/^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(.){8,}$/";
- if (preg_match($regexp, $p)) return true;
- else return false;
- }
- foreach($password as $p) {
- if (checkPass($p)) echo $p." ...OK";
- else echo $p." ...BAD";
- echo "<br/>";
- }
Vyzkoušejte funkčnost sami.
A jak takové heslo automaticky vytvořit?
- function createPassword($length) {
- $chars="234567890abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
- $i=0;
- $password="";
- while ($i <= $length) {
- $password.=$chars{mt_rand(0,strlen($chars))};
- $i++;
- }
- return $password;
- }
- $password = createPassword(8);
- echo "Your 8 character password is: $password";
Pro další informace doporučuji seriál na intervalu, zejména tyto články Perl-compatible regulární výrazy v PHP - tvrzení v praxi, podmíněné subvýrazy, Perl-compatible regulární výrazy v PHP - lokální modifikátory, tvrzení a manuál php preg_match.
UPDATE 22.1.2009
Cílem tohoto článku nebylo vytvořit generátor bezpečných hesel a nebyl na něj kladen důraz, avšak na základě příspěvků v diskusi je potřeba původní kód přehodnotit.
Výsledek generátoru nezaručuje splnění všech daných podmínek a je tedy nutné výsledné heslo ještě doplnit o tři dané podmínky.
- // funkce vytvoří pole o unikátních náhodných číslech v rozsahu $count
- function uniqueRand($min, $max, $count) {
- // nutno doplnit ochrany typu min>max, count>(max-min) apod. to neni v prikladu reseno
- $arr=array();
- for ($i=0;$i<$count;$i++) {
- do {
- $r=mt_rand($min, $max);
- } while(in_array($r, $arr));
- $arr[$i]=$r;
- }
- return $arr;
- }
- function createPassword($length) {
- $chars="1234567890abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
- $i=0;
- $password="";
- while ($i <= $length) {
- $password.=$chars{mt_rand(0,strlen($chars))};
- $i++;
- }
- // a ještě náhodně nahradíme malé, velké písmeno a číslo v řetězci
- $arr=uniqueRand(0, $length, 3);
- $password{$arr[0]}=chr(mt_rand(48, 57));
- $password{$arr[1]}=chr(mt_rand(65, 90));
- $password{$arr[2]}=chr(mt_rand(97, 122));
- return $password;
- }
- $password = createPassword(8);
- echo "Your 8 character password is: $password";
komentáře
RSS Komentáře



Není mi jasný význam proč v $chars chybí číslice jedna. Má to nějaký význam nebo jde o překlep? Díky