툴/유니티

OSC 한글 문자열(string) 전송, 텍스트 인코딩(Unicode,Base64)

스튜디오 오버그래픽스 2022. 12. 3. 19:14

모바일(Android) 태블릿에서 플레이어가 입력한 이름을 PC로 전송해야하는 로직 개발이 필요했다

그래서 유니티로 입력한 문자열(string) 데이터를 OSC로 전송하고자 함

 

https://github.com/keijiro/OscJack

 

GitHub - keijiro/OscJack: Lightweight C# implementation of OSC server/client

Lightweight C# implementation of OSC server/client - GitHub - keijiro/OscJack: Lightweight C# implementation of OSC server/client

github.com

케이지로의 OSCJack을 사용

OSC로 전송할수 있는 타입은 int, float, string이 있다

플레이어가 작성한 이름을 string으로 전송하면 되겠지만 영문이랑 숫자는 잘 전송되지만 한글은 깨짐

 

전송 전에 확인해보면 콘솔에서 한글 제대로 인식

수신한 쪽에서 확인해보면 글자가 깨진 상태로 인식하고

Unicode로 대체되었다?라고 하는걸 보면 인코딩 문제일거 같음

컴퓨터는 문자열을 그대로 인식하는게 아니라 컴퓨터가 인식하고 전송할 수 있게 코드화(텍스트 인코딩)하게 됌

 

전송전에는 한글까지 인식하는 인코딩 형태였지만 OSC로 전송하면서 string이 영문,숫자,기호만 표현하는 아스키코드(ASCII)로 전송되었거나 한글은 표현못하는 다른 인코딩 방식으로 전송된것 같음.

https://ko.wikipedia.org/wiki/ASCII

 

ASCII - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. 1972 프린터 사용 설명서에 개시된 아스키 코드 차트표 미국정보교환표준부호(영어: American Standard Code for Information Interchange), 또는 줄여서 ASCII( , 아스키)는 영문

ko.wikipedia.org

 

 

 

 

 

 

*해결 방법

한글 표현이 가능한 'Unicode'와 영문과 숫자로 변환가능한 64진법 인코딩 'Base64'를 사용

텍스트 -> Unicode로 변환(byte타입) -> Base64로 변환(string타입) -> OSC 전송

OSC 수신 -> Unicode로 변환(byte타입) -> 텍스트로 변환

 

 

 

 

 

 

*상세 과정

https://jjeong.tistory.com/696

 

유니코드(UTF-8) 한글 코드표, 한글코드 범위 {AC00-D7AF}

유니코드(UTF-8) 한글 코드표, 한글코드 범위 {AC00-D7AF} U+AC00 to U+AD00 0 1 2 3 4 5 6 7 8 9 A B C D E F UTF8: 234, 176, 128; UNICODE: AC0 가 각 갂 갃 간 갅 갆 갇 갈 갉 갊 갋 갌 갍 갎 갏 UTF8: 234, 176, 144; UNICODE: AC1 감

jjeong.tistory.com

https://devuna.tistory.com/41

 

[Base 64] Base64이란 무엇일까? / Base64 사용 이유와 인코딩과 디코딩

[Base 64] Base64이란 무엇일까? / Base64의 인코딩과 디코딩 인코딩(encoding)은 파일에 저장된 정보의 형태나 형식을 데이터 표준화, 보안, 처리 속도 향상, 저장 공간 절약 등을 위해서 다른 형태로 변

devuna.tistory.com

Unicode와 Base64 인코딩을 위해서 네임스페이스 추가

using System;
using System.Text;

 

먼저 전송할 텍스트를 Unicode로 변환

byte[] bytesToEncode = Encoding.Unicode.GetBytes(string 타입의 전송할 텍스트);

그러면 타입이 byte가 되어서 OSC로 전송할수 있는 타입아님.

그래서 Base64 인코딩을 사용해서 OSC로 전송할수 있는 타입인 string으로 한번더 변환

string Base64Text = Convert.ToBase64String(bytesToEncode);

Base64로 인코딩하면 영문 대소문자와 숫자로만 이루어진 문자열로 코드화된다

ex)'전송할문자열' -> 7KCE7Iah7ZWg66y47J6Q7Je0

그리고 Base64로 인코딩된 문자열을 OSC로 전송(OSC로 영문과 숫자는 문제없이 전송된다)

 

수신 후에 디코딩

바이트로 변환        

byte[] decodedBytes = Convert.FromBase64String(OSC로 전송받은 string 타입의 Base64 데이터);   

다시 Unicode로 읽어서 텍스트로 변환

string GetText = Encoding.Unicode.GetString(decodedBytes);

 

 

 

 

 

 

*코드

OSC 전송

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using OscJack;
using System;
using System.Text;

public class OSC_Send : MonoBehaviour
{
    public string IP;	//OSC 전송할 IP
    public int Port;	//OSC 전송할 포트
    public string InputText;	//전송할 텍스트
    string EncodingText;    //인코딩된 문자열


    public void OSC_Send_Func()
    {
        //텍스트를 Unicode로 변환
        byte[] bytesToEncode = Encoding.Unicode.GetBytes(InputText);
        
        //다시 Base64로 변환
        EncodingText = Convert.ToBase64String(bytesToEncode);
       
       	//OSC 전송
        StartCoroutine("OSC");
    }

    IEnumerator OSC()
    {
        // IP address, port number
        using (var client = new OscClient(IP, Port))
        {
            client.Send("/1", EncodingText);
        }

        yield return null;
    }
}

 

OSC 수신

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using System.Text;

public class OSC_Receive : MonoBehaviour
{
    string GetText;    //전송 받을 텍스트

    public void OSC_Receive_Func(string s)
    {
    	//받은 Base64문자열 바이트로 변환
        byte[] decodedBytes = Convert.FromBase64String(s);
        
        //다시 Unicode로 변환
        GetText = Encoding.Unicode.GetString(decodedBytes);
    }
}