한글영타를 한글로…

기술적인 거…에 특별한게 저한테 있을리는 없구요… ^^;;
늘 그렇듯이 막코딩의 산물입니다.

“안녕하세요?” 를 “dkssudgktpdy?” 로 쳤을때 그걸 출력해주는거죠;;
현재 윈도우즈에서 쓰는 CP949 혹은 UHC라 불리는 확장완성형으로는 자모분리를 할 수 없어서 유니코드를 이용했습니다. UTF-8은 아니고, UCS-2 라 불리는 Unicode 2.0 체계입니다.

원리부터 간단히 설명을 드리면…

유니코드에 쓰이는 한글 초성은 순서대로…
ㄱㄲㄴㄷㄸㄹㅁㅂㅃㅅㅆㅇㅈㅉㅊㅋㅌㅍㅎ

중성은…
ㅏㅐㅑㅒㅓㅔㅕㅖㅗㅘㅙㅚㅛㅜㅝㅞㅟㅠㅡㅢㅣ

종성은…
없음 ㄱㄲㄳㄴㄵㄶㄷㄹㄺㄻㄼㄽㄾㄿㅀㅁㅂㅄㅅㅆㅇㅈㅊㅋㅌㅍㅎ

의 순서입니다.
이제 글자를 조합해서 코드를 만들면…
코드 = 0xAC00 + 초성순서번호(0번부터)*중성갯수*종성갯수 + 중성순서번호*종성갯수 + 종성순서번호
가 됩니다. 뭐… 이 정도의 정보만 있으면 누구나 만드실 수 있겠지만… 의외로 유니코드에 대한 정보가 명확하게 정의된 걸 찾기가 힘들어서(방대해서 그럴수도) 저 나름대로는 꽤 고생하며 만들었습니다. 기능 구현이 우선이라 함수가 깔끔하지 못하네요. 조금 더 깔끔하게 해주시면 감사하겠습니다. 🙂

아… 다들 아시겠지만… 마지막의 iconv 함수부분에서 UTF-8 대신에 CP949를 적으시면 확장완성형 형태의 결과물또한 얻으실 수 있습니다. (EUC-KR은 글자수가 조합형 및 유니코드의 절반도 안됩니다. -_-)

function eng2han ($str)
{
static $convTable = null;
if (is_null($convTable))
{
// 초성
$convTable[] = array(‘r’=>0, ‘R’=>1, ‘s’=>2, ‘e’=>3, ‘E’=>4, ‘f’=>5, ‘a’=>6, ‘q’=>7, ‘Q’=>8, ‘t’=>9, ‘T’=>10, ‘d’=>11, ‘w’=>12, ‘W’=>13, ‘c’=>14, ‘z’=>15, ‘x’=>16, ‘v’=>17, ‘g’=>18);

// 중성
$convTable[] = array(‘k’=>0, ‘o’=>1, ‘i’=>2, ‘O’=>3, ‘j’=>4, ‘p’=>5, ‘u’=>6, ‘P’=>7, ‘h’=>8, ‘hk’=>9, ‘ho’=>10, ‘hl’=>11, ‘y’=>12, ‘n’=>13, ‘nj’=>14, ‘np’=>15, ‘nl’=>16, ‘b’=>17, ‘m’=> 18, ‘ml’=>19, ‘l’=>20);

// 종성
$convTable[] = array(‘r’=>1, ‘R’=>2, ‘rt’=>3, ‘s’=>4, ‘sw’=>5, ‘sg’=>6, ‘e’=>7, ‘f’=>8, ‘fr’=>9, ‘fa’=>10, ‘fq’=>11, ‘ft’=>12, ‘fx’=>13, ‘fv’=>14, ‘fg’=>15, ‘a’=>16, ‘q’=>17, ‘qt’=>18, ‘t’=>19, ‘T’=>20, ‘d’=>21, ‘w’=>22, ‘c’=>23, ‘z’=>24, ‘x’=>25, ‘v’=>26, ‘g’=>27);
}

$retText = array(); $hanChar = ”;
$len = strlen($str);
for ($idx = 0; $idx < $len; $idx++)
{
if ( is_numeric($convTable[0][$str[$idx]]) )
{
// 초성
$hanChar = 0xAC00 + $convTable[0][$str[$idx]]*21*28;
$idx++;

// 중성
if ( $convTable[1][$str[$idx].$str[$idx+1]] ) {
$hanChar += $convTable[1][$str[$idx].$str[$idx+1]]*28;
$idx+=2;
} elseif ( is_numeric($convTable[1][$str[$idx]]) ) {
$hanChar += $convTable[1][$str[$idx]]*28;
$idx++;
}

// 종성
if ( $convTable[2][$str[$idx].$str[$idx+1]] && (!is_numeric($convTable[1][$str[$idx+2]]) || $idx+2 >= $len) ) {
$hanChar += $convTable[2][$str[$idx].$str[$idx+1]];
$idx++;
} elseif ( $convTable[2][$str[$idx]] && (!is_numeric($convTable[1][$str[$idx+1]]) || $idx+1 >= $len) ) {
$hanChar += $convTable[2][$str[$idx]];
} else {
$idx–;
}

$hanChar = dechex($hanChar);
$hanChar = iconv(“UCS-2”, “UTF-8”, chr(hexdec(substr($hanChar, 0, 2))).chr(hexdec(substr($hanChar, -2))));

$retText[] = $hanChar;
}
else
{
$retText[] = $str[$idx];
continue;
}
}

return implode(”, $retText);
}

테스트
echo eng2han(‘dkssudgktpdy?’);

결과
안녕하세요?