뭔가 새로 만들어 볼 것을 찾다가 문득 떠올랐다.
콜옵 같은 게임을 하다보면 바이두 번역기로 한국어로 번역해서 잡소리를 하는 중화대협들을 많이 볼 수 있다.
내가 한장 플레이하던 때는 바이두 번역기의 중>한 번역의 성능이 그리 좋지 못했기 때문에, 저 이미지처럼 띄어쓰기가 제대로 안되는 문제가 있었고 그게 재밌는 점이었다.
그런 생각이 들어서 "저걸 웹에 가서 수작업 하긴 귀찮으니 원버튼으로 만들어야지." 하고 만들기로 했다.
처음엔 웹 번역기에 사용되는 요청들을 모방하려고 했는데 뭔가 이상하게 잘 안됐다. 파파고는 잘 됐는데....
그래서 그냥 바이두에서 제공하는 API를 이용하기로 했다.
예전에 쓸 일이 있어서 만들어 둔 아이디가 있었기 때문에 그 아이디를 사용해서 개발자로 등록했...으면 좋았을텐데...
계정 가입엔 외국 전화번호도 받으면서 개발자 등록은 무조건 중국 전화번호만 받는다.
구글에 검색하면 나오는 가상 전화번호를 제공하는 곳들은 「단 하나」도 동작하지 않았다.
그렇게 이걸 어찌해야 할지 구글과 바이두를 전전하던 중 어떤 좋은 분을 만나서 키를 얻을 수 있었다. 무한한 감사.
제목에 쓴 대로 WPF로 만들긴 했는데 윈폼만 써본 나에게 첫 접근은 뭔가 불편한 느낌이 했지만 조금 만져보니 윈폼보다 훨씬 낫다는 게 느껴지더라. 윈폼보다 할 수 있는게 많고 훨씬 재밌었다.
먼저 JSON을 받을 준비를 했다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
public class Result
{
public string from { get; set; }
public List<TransResult> trans_result { get; set; }
public string to { get; set; }
}
public class Root
{
public Result result { get; set; }
public long log_id { get; set; }
}
public class TransResult
{
public string dst { get; set; }
public string src { get; set; }
}
|
cs |
응답을 보고 내가 일일이 클래스를 만들긴 너무 귀찮으니 아래의 사이트를 이용했다.
깔끔하게 잘 뽑아주더라. 굳이 내가 일일이 할 필요는 없지.
다음으로 POST를 쏴줄 친구와 실제로 번역 요청을 보낼 함수를 하나 만든다.
POST 요청을 보낼 물건은 굳이 소개 안해도 많으니 넘기고
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
public string Point(string input)
{
try
{
// Get Token:Details https://ai.baidu.com/ai-doc/REFERENCE/Ck3dwjhhu
string TokenJson = getAccessToken();
if (!string.IsNullOrEmpty(TokenJson))
{
AccessToken TokenEntity = JsonConvert.DeserializeObject<AccessToken>(TokenJson);
if (!string.IsNullOrEmpty(TokenEntity.error))
{
if (TokenEntity.error == "invalid_client" && TokenEntity.error_description == "unknown client id")
Console.WriteLine("Wrong API Key");
else if (TokenEntity.error == "invalid_client" && TokenEntity.error_description == "Client authentication failed")
Console.WriteLine("Wron Secret Key");
else
Console.WriteLine("Unknown Error:Failed to get token");
}
string output = Worker(TokenEntity, input);
return output;
}
return "Failed";
}
catch (Exception ex)
{
Console.WriteLine("Translation Failed:" + ex.Message);
return "Failed";
}
}
|
cs |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
public static string Worker(AccessToken TokenEntity, string src)
{
string URL = "https://aip.baidubce.com/rpc/2.0/mt/texttrans/v1?access_token=" + TokenEntity.access_token;
string parms = "{ \"q\":\"" + src + "\",\"from\":\"kor\",\"to\":\"zh\"}";
HttpTool httppost = new HttpTool();
var strJson = httppost.HttpPost(URL, parms, "", "application/json;charset=utf-8");
var res = JsonConvert.DeserializeObject<Root>(strJson);
parms = "{ \"q\":\"" + res.result.trans_result[0].dst + "\",\"from\":\"zh\",\"to\":\"kor\"}";
strJson = httppost.HttpPost(URL, parms, "", "application/json;charset=utf-8");
res = JsonConvert.DeserializeObject<Root>(strJson);
return res.result.trans_result[0].dst;
}
|
cs |
좀 더럽지만 이런 형태로로 잘 작동은 한다.
중국 개발자 커뮤니티도 나름 규모가 있어서 그런지 좋은 공부가 됐다.
src와 dst는 굳이 변수로 하지 않고 문자 그대로 넣었다.
어차피 한>중>한 번역만 수행할 것이기 때문에 필요를 느끼지 못했다.
사실 저 Point()는 원래 콘솔에서 Main()이었는데 WPF 프로젝트로 오면서 그냥 적당히 문자열을 리턴하게끔 바꿔만 놨다.
1
2
3
4
5
6
7
|
private void bTrans_Click(object sender, RoutedEventArgs e)
{
Translator translator = new Translator();
string res = translator.Point(tbInput.Text);
tbOutput.Text = res;
}
|
cs |
MainWindow.xaml.cs에서 Translator 클래스의 인스턴스를 생성한 후 텍스트 박스에 입력된 문자열을 Point()에 보내서 결과를 받고 출력용 테스트 박스에 출력하게 된다.
아래는 대충 결과물이다.
왜 Korean dogs냐면...
그쪽동네 말로 개라고 하는건 꽤 심한 욕인 것 같다. 어딜가든 보인다. "한국인은 미국의 개" 라는 표현이 굉장히 많이 보이기 때문에 그렇게 정했다. 정작 듣는 쪽에선 dog 정도로 아무 생각이 들진 않지만 여하튼 그런 것 같다.
다시 돌아오자면 1년 정도 전과 다르게 띄어쓰기가 현저히 개선되어 예전과 같은 재미를 볼 수가 없게 되었다.
아마 다른 중국 번역기들도 비슷할 것이기 때문에 궁리를 했다.
그럼 랜덤한 주기로 공백을 넣으면 되지 않나?
원래 내가 기대하던 그 번역도 공백의 위치를 예상할 수 없으니 괜찮은 아이디어라고 생각했다.
Worker()에 아래와 같이 랜덤한 간격을 두고 문자열에 공백을 삽입하는 코드를 추가했다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
if (chkd == true)
{
Random rnd = new Random();
int rndVal;
int tmp = 1;
int leng = output.Length;
while(tmp < leng)
{
rndVal = rnd.Next(1, 5);
if (output.ElementAt(tmp).Equals(" "))
{
output = output.Insert(tmp + 1, " ");
tmp++;
}
else
output = output.Insert(tmp, " ");
tmp += rndVal;
}
}
|
cs |

그냥 있긴 심심하니 토글 스위치도 추가했다.
기본적으로 True인 상태고 False일 경우 공백을 삽입하지 않는다.
이정도면 실전에서 써먹을 수 있는 정도는 된 것 같다.
중화대협들의 강력한 무공에 지쳐 요즘 총질은 안하지만 언젠가 쓸 일이 있지 않을까 싶다.
그동안 왜 계속 윈폼을 써왔는지 모를 정도로 WPF는 확실히 강력하고 만지는 재미도 있었다.
역시 사람들이 툴 하면 C# 이라고 하는게 좀 다가온 것 같은 느낌이다.
C++도 이렇게 편해지면 좋을텐데 아쉬운 일이다.
'Study > C++ & C#' 카테고리의 다른 글
[C++] 스마트 포인터 (0) | 2023.02.04 |
---|---|
[C++] 다중 포인터 (0) | 2023.01.27 |
[C++] 포인터 기초 (0) | 2023.01.26 |
[C#, Python] C# 라이브러리를 이용한 discord.py 봇 개발 (2/2) (0) | 2023.01.15 |
[C#, Python] C# 라이브러리를 이용한 discord.py 봇 개발 (1/2) (0) | 2023.01.15 |