/** * @file cf_codec.c * @author myusgun */ #include "cf_codec.h" #include "cf_error.h" #include #include #define ASSERT_ARGS(x) \ if ((x)) \ return CF_ERROR_CODEC_INVALID_ARGS #define IS_NUMBER(x) (x >= '0' && x <= '9') #define IS_LOWERCASE(x) (x >= 'a' && x <= 'f') #define IS_UPPERCASE(x) (x >= 'A' && x <= 'F') /** * 바이너리 데이터를 16진수 문자열로 변환 * * @return 성공 시, CF_OK; 실패 시, 오류 코드 * * @param bin 바이너리 데이터 * @param len 바이너리 데이터 길이 * @param hex 16진수 문자열을 저장할 주소 * * @remark 16진수 문자열을 저장할 메모리가 미리 할당되어야 하며, 크기는 len * 2 + 1 */ int CF_Codec_BinaryToHex (const unsigned char * bin, const size_t len, char * hex) { size_t iter = 0; size_t count = len * 2 + 1; char hexchar[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; const unsigned char * ptr = bin; ASSERT_ARGS (bin == NULL); ASSERT_ARGS (hex == NULL); for (iter = 0 ; iter < count ; iter += 2, ptr++) { hex[iter ] = hexchar[((*(ptr)) >> 4) & 0x0f]; hex[iter + 1] = hexchar[((*(ptr)) ) & 0x0f]; } hex[count] = '\0'; return CF_OK; } /** * 16진수 문자열을 바이너리 데이터로 변환 * * @return 성공 시, CF_OK; 실패 시, 오류 코드 * * @param hex 16진수 문자열 * @param bin 바이너리 데이터를 저장할 주소 * @param len 바이너리 데이터의 길이를 저장할 주소 * * @remark 바이너리 데이터를 저장할 메모리가 미리 할당되어야 하며, 크기는 strlen (hex) / 2 */ int CF_Codec_HexToBinary (const char * hex, unsigned char * bin, size_t * len) { typedef unsigned char __uchar; int result = 0; size_t length = strlen (hex); /* absolutely even-number */ size_t iter = 0; size_t count = length / 2; int twochar = 0; const char * ptr = hex; char buf = 0; __uchar val = 0; ASSERT_ARGS (hex == NULL); ASSERT_ARGS (bin == NULL); ASSERT_ARGS (len == NULL); for (iter = 0 ; iter < count ; iter++) { for (twochar = 2, val = 0 ; twochar ; ptr++, twochar--) { buf = *ptr; val = (__uchar)(val << 4); if (IS_NUMBER (buf)) val |= (__uchar)(buf - '0' + 0); else if (IS_LOWERCASE (buf)) val |= (__uchar)(buf - 'a' + 10); else if (IS_UPPERCASE (buf)) val |= (__uchar)(buf - 'A' + 10); else { result = CF_ERROR_CODEC_NOT_HEXSTRING; break; } } bin[iter] = val; } if (result == 0) *len = count; return result; }