[C/C++ 언어 강좌 링크]
안녕하세요~. 블로그 주인장 양햄찌입니다.ㅎㅎㅎㅎ
오랜만에 소스코드 포스팅을 가져왔어요.
헥사 문자열과 아스키 문자열간의 변환 소스코드
오늘은 많이 사용하는
'문자열을 16진수인 헥사 값으로 전환'하거나 'hex값을 문자열로 변경'하는 코드를 작성해보려고 해요.
한 예로 obj 파일을 열어보면 위처럼 되어있는데
빨간색 네모박스에 있는 문자열은 hex 값이고 노란색 부분은 hex값을 문자열로 변경시켜놓은 문자열입니다.
이렇게 hex로 이뤄진 문자열을 받았을 때 이를 아스키코드 string값으로 변환하는 코드를 짜볼거예요.
[HEX STRING TO ASCII STRING 헥사 문자열에서 아스키 문자열로 변환하기]
먼저 알아야 할건, 1바이트는 8bit이고 8bit 최대 값은 1111 1111로 헥사로 FF이기 때문에 1바이트는 헥사로 두 글자에 해당이 됩니다. 즉 한 글자가 hex로는 두 글자에 해당된다는 점!
그러므로 헥사 문자열을 아스키 문자열로 변환하면 길이는 반띵이 되겠죠!
int hex_to_str(const char* in, char* out)
{
int val1 = -1, val2 = -1; int temp, j = 0;
for (int i = 0; i < strlen(in); i++)
{
if (isspace(in[i]))
continue;
else if (!isalpha(in[i]) && !isdigit(in[i]))
continue;
temp = isdigit(in[i]) ? in[i] - '0' : in[i] - 'A' + 10;
if (val1 == -1) val1 = temp;
else val2 = temp;
if (val1 != -1 && val2 != -1)
{
out[j++] = (val1 << 4) | val2;
val1 = val2 = -1;
}
}
return j;
}
먼저 헥사값에는 숫자랑 영문자만 와야해요. 따라서 whitespace문자가 오거나 이상한 기호문자가 오면 skip할 수 있도록 분기문으로 걸러줬습니다.
또 각 자리수에 있는 헥사문자열중 알파벳에 해당하는 A, B, C, D, E, F는 10, 11, 12, 13, 14, 15를 의미하니
알파벳이 나오면 A라는 값을 뺀뒤 10을 더해서, 숫자로 변환해줬어요.
위 문제는 만약 헥사값 00이 들어오면 문자열로 NULL이라 결과값을 확인할 수가 없죠!!
그래서 리턴값을 void가 아니라 결과길이에 해당하는 integer를 반환하였습니다.
[NULL없을 때]
어디 한 번 테스트를 해봅시다.
int main()
{
char in[100] = "--3136 ;; 3533 6F "; //공백이나 이상한 문자 잘 제거하는지
char out[100] = { 0x00, };
int len = hex_to_str(in, out);
cout << "변환 전 :" << in << endl;
cout << "변환 후 길이 :" << len << " 변환 후 :"<<out << endl;
return 0;
}
input 문자열은 이상한 문자를 다 걸러주는지 체크하기 위해 공백이랑 기호를 섞어봤어요.
그런데도 숫자&알파벳만 골라서 문자열 1653o으로 잘 변환시킨 것을 확인할 수 있습니다.
[NULL 있을 때]
int main()
{
char in[100] = "31003635336F"; //공백이나 이상한 문자 잘 제거하는지
char out[100] = { 0x00, };
int len = hex_to_str(in, out);
cout << "변환 전 :" << in << endl;
cout << "변환 후 :";
for (int i = 0; i < len; i++)
putc(out[i], stdout);
return 0;
}
이렇게 중간에 NULL에 해당하는 헥사값 0x00을 넣어줘도
리턴값 길이를 이용해서 잘리지 않고 다 출력해줬어요~
[STRING TO HEXSTRING 문자열을 hex문자열로 보여주기]
이번에는 반대로 해볼게요. 문자를 hex 문자열로 변환하는거죠!
void str_to_hex(const char* in, char* out, const char* offset)
{
int in_idx = 0, out_idx = 0;
while (in[in_idx] != '\0')
{
sprintf((out + out_idx), "%02x%s", in[in_idx], offset);
in_idx += 1; out_idx += (2 + strlen(offset));
}
}
문자열을 hex문자열로 변경하는건 더 간단하죠~! 문자열에 해당하는 값을 hex로 보여주게만 하면 되는거니까~~!
offset이라는 매개변수를 하나 더 줘서, 헥사값의 경계를 깔끔하게 보일 수 있도록 했어요.
int main()
{
char in[100] = "1653o";
char out[100] = { 0x00, };
str_to_hex(in, out, " ");
cout << "변환 전 :" << in << endl;
cout << "변환 후 :" << out << endl;
return 0;
}
테스트를 해봅시당. 위에서 "313635336F"의 결과가 1653o이였죠? 반대로 1653o을 대입해서 헥사값이 나오는지 확인해봅시다. 띄어쓰기 기준은 공백으로 할게요.
짠~ 잘 변환되는 것을 확인할 수 있어요.
위 소스는 제가 그냥 짠 것으로, 더 좋은 예시가 있다면 공유도 좋아요.
도움이 되었으면 공감 ! 큰 힘이 됩니다. 다음 포스팅에서 봐요 :)
최신 댓글