7L2U65Sp67Cw7Jqw64qUIO2VmeyDnQ==
'코딩배우는 학생'의 Base64로 인코딩한 문자열의 예시이다.
Base64 는 Binary 데이터를 아스키 코드 일부와 일대일로 매칭되는 문자열로 단순 치환되는 인코딩 방식이다.
Base64는 6bit당 2bit의 OverHead의 발생으로 기존 데이터보다 30%이상 길어지게 되며 여기에 Encoding, Decoding의 로직까지 추가되므로 성능에도 영향을 끼칠 수 있다. 이러한 단점에도 Base64를 사용하는 이유는 무엇일까.
📮Base64를 사용하는 이유
Base64를 사용하는 가장 큰 이유는 Binary 데이터를 텍스트 기반 규격으로 다룰 수 있기 때문이다. JSON과 같은 문자열 기반 데이터 안에 이미지 파일등을 Web에서 필요로 할때 Base64로 인코딩하면 UTF-8과 호환 가능한 문자열을 얻을 수 있다. 끝에 '='과 같은 패딩 기호가 있다면 이는 구분자로써 사용되므로 대부분 Base64로 생각할 수 있다.
기존 ASCII 코드는 시스템간 데이터를 전달하기에 안전하지 않다. 모든 Binary 데이터가 ASCII 코드에 포함되지 않으므로 제대로 읽지 못한다. 반면 Base64는 ASCII 중 제어문자와 일부 특수문자를 제외한 53개의 안전한 출력 문자만 이용하므로 데이터 전달에 더 적합하다.
📮Base 64 인코딩
Base64는 Binary 데이터를 문자로 변환하는데 영향을 받지 않는 공통 ASCII 코드 영역의 문자로만 이루어진 문자열로 바꾸는 Encoding이다. 문자 그대로 64진법(2^6)을 사용하며 Binary 데이터를 6bit 씩 나누고 해당하는 문자를 위의 색인표에서 맞게 치환하는 과정을 거친다. 6bit cut을 진행함에 있어서 모든 문자열이 3개씩 이쁘게 떨어지면 좋겠지만, 아닌 경우도 왕왕 존재하기 마련이다. 그런 경우를 대비해 padding을 하는데 남는자리에 = 기호를 통해서 채워주는 개념이다.
예를들어 '코딩배우는 학생'을 Base64로 인코딩 하면 '7L2U65Sp67Cw7Jqw64qUIO2VmeyDnQ==' 로 2자리의 빈공간을 알려주게 된다.
padding 문자가 반드시 필요한 것은 아닙니다. JSON이나 HTTP 메세지를 통해 데이터 길이를 명시적으로 구분할 수 있다면 더욱 그렇습니다. 하지만 TCP처럼 Stream형태로 데이터를 주고받는 형태에서는 padding이 유용합니다.
📮Base 64 디코딩
복원한 데이터를 다룰 때 주의할 점은 복원한 데이터만 보면 타입을 특정지을 수 없다는 점입니다. 따라서 데이터 형태와 함께 명시하는 경우가 많습니다.
{
"type":"image",
"data":"df123sdzx03=="
}
📮끝으로
Base64는 XML, JSON, REST API등 문자열 기반 데이터를 주고받는 환경에서 multi-form을 다룰경우 함께 사용된다.
필자의 주 언어인 C#으로 모듈을 구현하면 다음과 같다.
public class Base64Test{
//인코딩
public static string Base64Encoding(string data) //UTF-8 string
{
try{
byte[] byteTemp = new byte[data.length];
byteTemp = System.Text.Encoding.UTF8.GetBytes(data);
string encodedData = Convert.ToBase64String(byteTemp);
return byteTemp;
}
catch(Exception){
Console.WriteLine("Error");
}
}
//디코딩
public static string Base64Decoding(string data) //UTF-8 string
{
try
{
System.Text.UTF8Encoding encoder = new System.Text.UTF8Encoding();
System.Text.Decoder utf8Decode = encoder.GetDecoder();
byte[] decodeToByte = Convert.FromBase64String(data);
int charCnt = utf8Decode.GetCharCount(decodeToByte, 0, decodeToByte.Length);
char[] decodedChar = new char[charCnt];
utf8Decode.GetChars(decodeToByte, 0, decodeToByte.Length, decodedChar, 0);
string result = new String(decodedChar);
return result;
}
catch(Exception)
{
Console.WriteLine("Error");
}
}
}
'Web > Web지식' 카테고리의 다른 글
[모듈번들링] Module Bundler: Webpack 도입 적용 경험 #1,2 (0) | 2021.08.05 |
---|---|
[ASP .NET C#] 개인정보 암호화 적용 사례 (0) | 2021.02.25 |
Web Protocol 정리 (0) | 2021.02.17 |