[PHP] 비밀번호 체크
사용자가 입력한 비밀번호가 비밀번호 정책에 적합한지 테스트 한다. 비밀번호는 8자 이상으로, 영문/숫자/특수문자를 1개 이상 포함되어야 하며 동일한 문자가 반복되면 안된다. 그리고 연속되는 문자가 있어서도 안된다.
<?php
function check_password($password)
{
// 8자 이상, 영문/숫자/특수문자 1개 이상 포함
$pattern = "/^(?=.*[a-z])(?=.*\d)(?=.*[`~!@#$%^&*|\\\'\";:\.\,\/?=+\-_()<>{}])[a-z\d`~!@#$%^&*|\\\'\";:\.\,\/?=+\-_(){}<>]{8,}$/i";
if (!preg_match($pattern, $password)) {
return '비밀번호는 8자 이상으로 영문/숫자/특수문자 1개 이상 포함되어야 합니다.';
}
// 동일한 문자 반복 체크
if (preg_match('/([a-z0-9])\1+/i', $password)) {
return '비밀번호에 동일한 문자가 반복됩니다.';
}
// 연속된 문자 체크
$arr_char = str_split($password);
$old_char_code = 0;
$is_consecutive = false;
foreach ($arr_char as $char) {
$new_char_code = ord($char);
if (abs($old_char_code - $new_char_code) == 1) {
$is_consecutive = true;
break;
}
$old_char_code = $new_char_code;
}
if ($is_consecutive) {
return '비밀번호에 연속된 문자가 존재합니다.';
}
return '';
}
정책을 좀 과하게 잡은 것 같기도 한데.. 동일한 문자가 한번만 반복되도 문제가 되고.. 연속된 문자 역시 chic
라는 단어는 일단 hi
가 연속이 되기 때문에 융통성이 없긴 한데.. 과하다 싶은 정도로 하면 이렇게도 할 수 있을 것 같다.
2022년 1월 27일 추가.. 위 함수를 아래처럼 조금 수정했다. 2번 연속되는 건 너무 과하다 싶기도 하고.. 연속되는 문자의 개수를 지정할 수도 있음 좋겠다 싶어서 말이다.
<?php
function check_password($password)
{
// 8자 이상, 영문/숫자/특수문자 1개 이상 포함
$pattern = "/^(?=.*[a-z])(?=.*\d)(?=.*[`~!@#$%^&*|\\\'\";:\.\,\/?=+\-_()<>{}])[a-z\d`~!@#$%^&*|\\\'\";:\.\,\/?=+\-_(){}<>]{8,}$/i";
if (!preg_match($pattern, $password)) {
return '비밀번호는 8자 이상으로 영문/숫자/특수문자 1개 이상 포함되어야 합니다.';
}
// 동일한 문자 반복 체크
if (preg_match('/([a-z0-9])\1+/i', $password)) {
return '비밀번호에 동일한 문자가 반복됩니다.';
}
// 연속된 문자 체크
$min_consecutive = 2;
$cnt_consecutive = 0;
$is_consecutive = false;
if ($min_consecutive > 1) {
$arr_char = str_split($password);
$old_char_code = 0;
foreach ($arr_char as $key => $char) {
$new_char_code = ord($char);
if (abs($old_char_code - $new_char_code) == 1) {
$cnt_consecutive++;
if ($cnt_consecutive >= $min_consecutive) {
$is_consecutive = true;
break;
}
} else {
$cnt_consecutive = 0;
}
$old_char_code = $new_char_code;
}
if ($is_consecutive) {
return '비밀번호에 연속된 문자가 존재합니다.';
}
}
return '';
}