본문 바로가기
PROGRAM/PHP

욕 필터링

by 반화넬 2008. 1. 24.
반응형
20071211일 업그레이드(?) 내용
1. 영문 욕 처리 기능 추가...  (본문의 영어 욕은 대소문자 상관없음)
2. 알파벳+ 한글 섞인 욕도 처리 가능


<?
# 특징: 본문 중에 나타난 모든 욕들을 한꺼번에 콤마로 구분하여 리턴

# 방법: 속도를 고려하여 전진방식의 매칭으로 처리
# 매칭할 단어들을 배열A에 저장해 놓는다.
# 함수로 위 단어의 첫글자를 따로 배열B로 만든다.
# 본문을 한글자씩 전진하면서 그 글자랑 매칭되는 문자가 있는지 B배열을 채크한다.
# B배열은 A배열에서 그 문자로 시작하는 첫 단어의 index를 가지고 있으며
# A배열의 그 위치부터 현재 문서 위치의 문자열이랑 비교를 하는데,
# 문자열 비교를 위하여 문서로부터 단어 최대길이만큼 짤라서 비교를 한다.
# 저작권: 니맘 대로 하세요.

# 필터링할 단어들. 정렬되어 있어야 한다. (영문 단어는 소문자만 허용됨)
$words= array('10새','10새기','10새리','10세리','10쉐이','10쉑','10스','10쌔',
'10쌔기','10쎄','10알','10창','10탱','18것','18넘','18년','18노','18놈',
'18뇬','18럼','18롬','18새','18새끼','18색','18세끼','18세리','18섹','18쉑','18스','18아',
'c파','c팔','fuck',
'ㄱㅐ','ㄲㅏ','ㄲㅑ','ㄲㅣ','ㅅㅂㄹㅁ','ㅅㅐ','ㅆㅂㄹㅁ','ㅆㅍ','ㅆㅣ','ㅆ앙','ㅍㅏ','凸',
'갈보','갈보년','강아지','같은년','같은뇬','개같은','개구라','개년','개놈',
'개뇬','개대중','개독','개돼중','개랄','개보지','개뻥','개뿔','개새','개새기','개새끼',
'개새키','개색기','개색끼','개색키','개색히','개섀끼','개세','개세끼','개세이','개소리','개쑈',
'개쇳기','개수작','개쉐','개쉐리','개쉐이','개쉑','개쉽','개스끼','개시키','개십새기',
'개십새끼','개�','개씹','개아들','개자슥','개자지','개접','개좆','개좌식','개허접','걔새',
'걔수작','걔시끼','걔시키','걔�','걸레','게색기','게색끼','광뇬','구녕','구라','구멍',
'그년','그새끼','냄비','놈현','뇬','눈깔','뉘미럴','니귀미','니기미','니미','니미랄','니미럴',
'니미씹','니아배','니아베','니아비','니어매','니어메','니어미','닝기리','닝기미','대가리',
'뎡신','도라이','돈놈','돌아이','돌은놈','되질래','뒈져','뒈져라','뒈진','뒈진다','뒈질',
'뒤질래','등신','디져라','디진다','디질래','딩시','따식','때놈','또라이','똘아이','똘아이',
'뙈놈','뙤놈','뙨넘','뙨놈','뚜쟁','띠바','띠발','띠불','띠팔','메친넘','메친놈','미췬',
'미췬','미친','미친넘','미친년','미친놈','미친새끼','미친스까이','미틴','미틴넘','미틴년',
'미틴놈','바랄년','병자','뱅마','뱅신','벼엉신','병쉰','병신','부랄','부럴','불알','불할','붕가',
'붙어먹','뷰웅','븅','븅신','빌어먹','빙시','빙신','빠가','빠구리','빠굴','빠큐','뻐큐',
'뻑큐','뽁큐','상넘이','상놈을','상놈의','상놈이','새갸','새꺄','새끼','새새끼','새키',
'색끼','생쑈','세갸','세꺄','세끼','섹스','쇼하네','쉐','쉐기','쉐끼','쉐리','쉐에기',
'쉐키','쉑','�','�','쉬발','쉬밸','쉬벌','쉬뻘','쉬펄','쉽알','스패킹','스팽','시궁창','시끼',
'시댕','시뎅','시랄','시발','시벌','시부랄','시부럴','시부리','시불','시브랄','시팍',
'시팔','시펄','신발끈','심발끈','심탱','십8','십라','십새','십새끼','십세','십쉐','십쉐이','십스키',
'십쌔','십창','십탱','싶알','싸가지','싹아지','쌉년','쌍넘','쌍년','쌍놈','쌍뇬','쌔끼',
'쌕','쌩쑈','�년','썅','썅년','썅놈','�쇼','써벌','썩을년','썩을놈','쎄꺄','쎄엑',
'쒸벌','쒸뻘','쒸팔','쒸펄','쓰바','쓰박','쓰발','쓰벌','쓰팔','씁새','씁얼','씌파','씨8',
'씨끼','씨댕','씨뎅','씨바','씨바랄','씨박','씨발','씨방','씨방새','씨방세','씨밸','씨뱅',
'씨벌','씨벨','씨봉','씨봉알','씨부랄','씨부럴','씨부렁','씨부리','씨불','씨붕','씨브랄',
'씨빠','씨빨','씨뽀랄','씨앙','씨파','씨팍','씨팔','씨펄','씸년','씸뇬','씸새끼','씹같','씹년',
'씹뇬','씹보지','씹새','씹새기','씹새끼','씹새리','씹세','씹쉐','씹스키','씹쌔','씹이','씹자지',
'씹질','씹창','씹탱','씹�','씹팔','씹할','씹헐','아가리','아갈','아갈이','아갈통',
'아구창','아구통','아굴','얌마','양넘','양년','양놈','엄창','엠병','여물통','염병','엿같','옘병',
'옘빙','오입','왜년','왜놈','욤병','육갑','은년','을년','이년','이새끼','이새키','이스끼',
'이스키','임마','자슥','잡것','잡넘','잡년','잡놈','저년','저새끼','접년','젖밥','조까',
'조까치','조낸','조또','조랭','조빠','조쟁이','조지냐','조진다','조찐','조질래','존나','존나게','존니','존만',
'존만한','좀물','좁년','좁밥','좃까','좃또','좃만','좃밥','좃이','좃찐','좆같','좆까','좆나',
'좆또','좆만','좆밥','좆이','좆찐','좇같','좇이','좌식','주글','주글래','주데이','주뎅',
'주뎅이','주둥아리','주둥이','주접','주접떨','죽고잡','죽을래','죽통','쥐랄','쥐롤',
'쥬디','지랄','지럴','지롤','지미랄','짜식','짜아식','쪼다','쫍빱','찌랄','창녀','캐년',
'캐놈','캐스끼','캐스키','캐시키','탱구','팔럼','퍽큐','호로','호로놈','호로새끼',
'호로색','호로쉑','호로스까이','호로스키','후라들','후래자식','후레','후뢰');

# [수집된 단어의 첫 2바이트] => 그 글자가 처음 나오는 단어의 인덱스
#
function get_indexOfWords(&$words)
{
  $arr= array();
  $ch_old=0;
  foreach($words as $k=>$v){
    $ch= $v{0}.$v{1};
    if ($ch_old==$ch) continue;

    $ch_old=$ch;
    $arr[$ch]= $k;
  }
  return $arr;
}

# 상수
# 배열값 중에서 가장 긴 길이와 같거나 더 길면 됨. 정확하지 않아도 무방..
# 왜냐면, 본문 중에서 비교할 문자열을 적당히 짜를 용도이므로
define('MEX_WORD_LEN', 10);

function fuck_match (&$words, $str)
{
  $RET_WORDS= array();
  $char2idx= array();

  $char2idx= get_indexOfWords($words);
  $num_words= sizeof($words);
  $len_str= strlen($str);

  $han_flag=0;
  for ($i=0; $i<$len_str; $i++){
    if ($han_flag){      # 한글의 두번째 바이트 차례는 건너뜀
      $han_flag=0;
      continue;
    }
    $ch= $str{$i};
    if ($ch<'0')
      continue;

    if (127 < ord($ch))
      $han_flag=1;

    $ch= strtolower($ch. $str{$i+1});  # 2바이트를 1단위로 처리

    if (! isset($char2idx[$ch]))  # 첫글자가 일치하는 단어의 인덱스가 없으면
      continue;

    $str_part= strtolower(substr($str, $i, MEX_WORD_LEN));  # 본문 중에 비교할 부분 문자열

    // echo "@$i@ 단어의 첫글자 일치의 경우  ($str_part == {$words[$char2idx[$ch]]})<br>";

    $match_word= '';
    for($j=$char2idx[$ch]; $j< $num_words; $j++){
      if (strpos($str_part, $words[$j])===0) # 단어가 완전히 포함되면
        $match_word= $words[$j];            # 임시저장
      if ($str_part<= $words[$j]){    # 단어가 비교 문자열보다 커지는 순간에 탈출
        if ($match_word!='')
          $RET_WORDS[]= $match_word;  # 그 순간의  임시 단어 수집
        break;
      }
    }
    if ($match_word && $j==$num_words){
      // echo "@$i@ 정렬에 문제가 있어서 저장 못하고 지나왔다면? ($match_word)<br>";
      $RET_WORDS[]= $match_word;
    }
  }
  if(0==sizeof($RET_WORDS))    return '';

  return implode(', ', array_unique($RET_WORDS));  # 중복 제거하고 리턴
}


#--------------- 요 밑으로는 테스트 --------------------------#

function __get_microtime(){
  list($usec, $sec)=  explode(" ",microtime());
  return (float)$usec + (float)$sec;
}


$time_start= __get_microtime();

$test_str= <<<TEST
여기는  별의별 헛소리를 다 넣어도 된다 무조껀 뻐큐
테스트용 문자열이므로 아무 의미가 없습니다 자세히 읽어 보지 말기를 바랍니다.
하하 호호 히히 쉽 스까이
내가 생각하는 아이템 사이트에서는 10새리
사실은 자유게시판이 아니라 회원제에서는 욕이 나오기는 힘들고 관리하기도 쉽다.
따라서 무단광고, 성인광고 처리에 집중하자.
일부러 표기법을 어기거나 특수분자랑 뒤섞는 등의 "정해지지 않는" 단어 처리에 대해서는
쉽게 생각하면 새로운 광고 단어 유형을 그때그때 수동으로 수집처리하면 된다.

자동으로 처리하려면?
광고 단어의 글자 사이에 특수문자들을 끼워 넣은 경우를 매칭하기 위하여
공백을 포한한 특수문자는 모두 제거하고 매칭할까. C팔 FUcK ㅆㅍ ㅆㅣ앙
3글자 이상의 길이면 가능하겠는데. 이런 좁밥 c파

2글자 이하의 매칭은 특수문자 제거하고 매칭시 엉뚱한 문자열이 걸릴 수 있다. ㅅㅂㄹㅁ','凸','갈보
그러므로 2자 이하의 단어 매칭시 바로 광고라고 확정하지 말고 가중 점수로써 처리하자.
시발 새새끼 개새끼
호홋
TEST;

$result= fuck_match ($words, $test_str);

echo "결과= ($result)<hr>실행에 걸린 시간=". (__get_microtime()- $time_start);
?>
반응형