Skip to content

Instantly share code, notes, and snippets.

@seungwon0
Last active February 10, 2018 19:35
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save seungwon0/cbab86cef0ad33a40f18 to your computer and use it in GitHub Desktop.
Save seungwon0/cbab86cef0ad33a40f18 to your computer and use it in GitHub Desktop.
한글 초성, 중성, 종성 분해 및 결합
#!/usr/bin/env perl
#
# 한글.pl - 한글 초성, 중성, 종성 분해 및 결합
#
# 초성, 중성, 종성을 결하여 글자를 만들거나, 글자를 초성, 중성,
# 종성으로 분해합니다.
#
# Seungwon Jeong <seungwon0@gmail.com>
#
# Copyright (C) 2015 by Seungwon Jeong
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see
# <http://www.gnu.org/licenses/>.
use perl5i::2;
use Readonly;
use Encode qw< decode_utf8 >;
Readonly my $유니코드_한글_시작_번호 => ord '가'; # 0xAC00
Readonly my $유니코드_한글_끝_번호 => ord '힣'; # 0xD7AC
# 초성 : 19
# ㄱ, ㄲ, ㄴ, ㄷ, ㄸ, ㄹ, ㅁ, ㅂ, ㅃ, ㅅ,
# ㅆ, ㅇ, ㅈ, ㅉ, ㅊ, ㅋ, ㅌ, ㅍ, ㅎ
Readonly my @초성 => qw< ㄱ ㄲ ㄴ ㄷ ㄸ ㄹ ㅁ ㅂ ㅃ ㅅ
ㅆ ㅇ ㅈ ㅉ ㅊ ㅋ ㅌ ㅍ ㅎ >;
Readonly my %초성_번호 => map { $초성[$_] => $_ } 0 .. $#초성;
# 중성 : 21
# ㅏ, ㅐ, ㅑ, ㅒ, ㅓ, ㅔ, ㅕ, ㅖ, ㅗ, ㅘ,
# ㅙ, ㅚ, ㅛ, ㅜ, ㅝ, ㅞ, ㅟ, ㅠ, ㅡ, ㅢ,
# ㅣ
Readonly my @중성 => qw< ㅏ ㅐ ㅑ ㅒ ㅓ ㅔ ㅕ ㅖ ㅗ ㅘ
ㅙ ㅚ ㅛ ㅜ ㅝ ㅞ ㅟ ㅠ ㅡ ㅢ
ㅣ >;
Readonly my %중성_번호 => map { $중성[$_] => $_ } 0 .. $#중성;
# 종성 : 27 (종성없음 제외)
# ㄱ, ㄲ, ㄳ, ㄴ, ㄵ, ㄶ, ㄷ, ㄹ, ㄺ, ㄻ,
# ㄼ, ㄽ, ㄾ, ㄿ, ㅀ, ㅁ, ㅂ, ㅄ, ㅅ, ㅆ,
# ㅇ, ㅈ, ㅊ, ㅋ, ㅌ, ㅍ, ㅎ
Readonly my @종성 => qw< ㄱ ㄲ ㄳ ㄴ ㄵ ㄶ ㄷ ㄹ ㄺ ㄻ
ㄼ ㄽ ㄾ ㄿ ㅀ ㅁ ㅂ ㅄ ㅅ ㅆ
ㅇ ㅈ ㅊ ㅋ ㅌ ㅍ ㅎ >;
Readonly my %종성_번호 => map { $종성[$_] => $_ } 0 .. $#종성;
if (@ARGV < 1 || @ARGV > 3) {
my $프로그램_이름 = decode_utf8 $PROGRAM_NAME;
print <<"사용법_끝";
사용법 : $프로그램_이름 초성 중성 [종성] 이나 $프로그램_이름 글자
예 1) $프로그램_이름 ㄷ ㅏ ㄹ
ㄷ + ㅏ + ㄹ = 달
예 2) $프로그램_이름 별
ㅂ + ㅕ + ㄹ = 별
사용법_끝
exit 2;
}
my ($초성, $중성, $종성);
my $글자;
if (@ARGV == 1) {
$글자 = $ARGV[0];
die "잘못된 글자 : $글자\n" if length $글자 != 1;
my $유니코드_번호 = ord $글자;
if ($유니코드_번호 < $유니코드_한글_시작_번호
|| $유니코드_번호 > $유니코드_한글_끝_번호) {
die "잘못된 글자 : $글자\n";
}
my $초성_번호
= ($유니코드_번호 - $유니코드_한글_시작_번호) / (@중성 * (@종성 + 1));
my $중성_번호
= ($유니코드_번호 - $유니코드_한글_시작_번호) % (@중성 * (@종성 + 1))
/ (@종성 + 1);
my $종성_번호
= ($유니코드_번호 - $유니코드_한글_시작_번호) % (@중성 * (@종성 + 1))
% (@종성 + 1);
$초성 = $초성[$초성_번호];
$중성 = $중성[$중성_번호];
$종성 = $종성_번호 > 0 ? $종성[$종성_번호 - 1] : undef;
} else {
($초성, $중성, $종성) = @ARGV;
my ($초성_번호, $중성_번호, $종성_번호);
$초성_번호 = $초성_번호{$초성};
die "잘못된 초성 : $초성\n" if !defined $초성_번호;
$중성_번호 = $중성_번호{$중성};
die "잘못된 중성 : $중성\n" if !defined $중성_번호;
if (defined $종성) {
$종성_번호 = $종성_번호{$종성};
die "잘못된 종성 : $종성\n" if !defined $종성_번호;
}
my $유니코드_번호 = $유니코드_한글_시작_번호;
$유니코드_번호 += $초성_번호 * @중성 * (@종성 + 1);
$유니코드_번호 += $중성_번호 * (@종성 + 1);
if (defined $종성) {
$유니코드_번호 += $종성_번호 + 1;
}
$글자 = chr $유니코드_번호;
}
if (defined $종성) {
say "$초성 + $중성 + $종성 = $글자";
} else {
say "$초성 + $중성 = $글자";
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment