Changeset 151 in libcf for trunk/src/cf_codec.c
- Timestamp:
- 10/31/13 10:17:24 (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/cf_codec.c
r129 r151 13 13 #include <stdio.h> 14 14 15 #define BASE64_PADDING_CHAR_INDEX 64 16 15 17 #define ASSERT_ARGS(x) \ 16 18 if ((x)) \ 17 19 return CF_ERROR_CODEC_INVALID_ARGS 18 20 19 const static cf_byte g_ascii_HexDecode[] = {20 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00 - 15 */21 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 16 - 31 */22 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 32 - 47 */23 '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',0x00,0x00,0x00,0x00,0x00,0x00, /* 48 - 63 */24 0x00, 'A', 'A', 'A', 'A', 'A', 'A',0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 64 - 79 */25 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 80 - 95 */26 0x00, 'a', 'a', 'a', 'a', 'a', 'a',0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 96 - 111 */27 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 112 - 127 */28 /* end of ascii character */29 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 128 - 143 */30 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 144 - 159 */31 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 160 - 175 */32 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 176 - 191 */33 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 192 - 207 */34 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 208 - 223 */35 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 224 - 239 */36 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 240 - 255 */37 };38 39 const static char g_table_Base64Encode[] = {40 #define BASE64_PADDING_CHAR_INDEX 6441 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', /* 00 - 07 */42 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', /* 08 - 15 */43 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', /* 16 - 23 */44 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', /* 24 - 31 */45 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', /* 32 - 39 */46 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', /* 40 - 47 */47 'w', 'x', 'y', 'z', '0', '1', '2', '3', /* 48 - 55 */48 '4', '5', '6', '7', '8', '9', '+', '/', /* 56 - 63 */49 '=' /* padding */50 };51 52 const static cf_byte g_ascii_Base64Decode[] = {53 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 00 - 15 */54 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 16 - 31 */55 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 62,0xff,0xff,0xff, 63, /* 32 - 47 */56 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,0xff,0xff,0xff, 64,0xff,0xff, /* 48 - 63 */57 0xff, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, /* 64 - 79 */58 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,0xff,0xff,0xff,0xff,0xff, /* 80 - 95 */59 0xff, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, /* 96 - 111 */60 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,0xff,0xff,0xff,0xff,0xff, /* 112 - 127 */61 /* end of ascii character */62 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 128 - 143 */63 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 144 - 159 */64 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 160 - 175 */65 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 176 - 191 */66 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 192 - 207 */67 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 208 - 223 */68 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 224 - 239 */69 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 240 - 255 */70 };71 72 73 21 /** 74 22 * hex-encode … … 88 36 char * hex) 89 37 { 90 size_t iter = 0; 91 size_t hexlen = len * 2 + 1; 92 93 const cf_byte * ptr = bin; 94 95 const static char hexchar[] = {'0', '1', '2', '3', 96 '4', '5', '6', '7', 97 '8', '9', 'a', 'b', 98 'c', 'd', 'e', 'f'}; 38 const cf_byte * src = bin; 39 char * dst = hex; 40 41 const static char hexenc[] = { 42 '0', '1', '2', '3', '4', '5', '6', '7', 43 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' 44 }; 99 45 100 46 ASSERT_ARGS (bin == NULL); 101 47 ASSERT_ARGS (hex == NULL); 102 48 103 for ( iter = 0 ; iter < hexlen ; iter += 2, ptr++)104 { 105 hex[iter ] = hexchar[((*(ptr)) >> 4) & 0x0f];106 hex[iter + 1] = hexchar[((*(ptr)) ) & 0x0f];107 } 108 hex[hexlen - 1]= '\0';49 for ( ; *src ; src++) 50 { 51 *dst++ = hexenc[((*src) >> 4) & 0x0f]; 52 *dst++ = hexenc[((*src) ) & 0x0f]; 53 } 54 *dst = '\0'; 109 55 110 56 return CF_OK; … … 114 60 * hex-decode 115 61 * 116 * \return 성공 시, 디코딩된 바이너리 데이터의 길이; 실패 시, 오류 코드62 * \return 성공 시, CF_OK; 실패 시, 오류 코드 117 63 * 118 64 * \param hex 16진수 문자열 … … 129 75 { 130 76 size_t length = 0; /* absolutely even-number */ 131 size_t iter = 0; 132 size_t binlen = 0; 133 134 const char * ptr = hex; 77 78 const char * src = hex; 79 cf_byte * dst = bin; 135 80 char buf = 0; 136 81 cf_byte val = 0; 137 82 cf_byte asciiHex = 0; 138 83 84 const static cf_byte hexdec[] = { 85 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00 - 07 */ 86 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 08 - 15 */ 87 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 16 - 23 */ 88 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24 - 31 */ 89 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 32 - 39 */ 90 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 40 - 47 */ 91 '0', '0', '0', '0', '0', '0', '0', '0', /* 48 - 55 */ 92 '0', '0',0x00,0x00,0x00,0x00,0x00,0x00, /* 56 - 63 */ 93 0x00, 'A', 'A', 'A', 'A', 'A', 'A',0x00, /* 64 - 71 */ 94 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 71 - 79 */ 95 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 80 - 87 */ 96 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 88 - 95 */ 97 0x00, 'a', 'a', 'a', 'a', 'a', 'a',0x00, /* 96 - 103 */ 98 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 104 - 111 */ 99 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 112 - 119 */ 100 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 /* 120 - 127 */ 101 }; 102 139 103 ASSERT_ARGS (hex == NULL); 140 104 ASSERT_ARGS (bin == NULL); 141 105 ASSERT_ARGS (len == NULL); 142 106 143 *len = 0; 144 145 for ( ; g_ascii_HexDecode[(int)*ptr] && *ptr ; ptr++, length++); 146 147 if (*ptr) 107 for ( ; hexdec[(int)*src] && *src ; src++, length++); 108 109 if (*src) 148 110 return CF_ERROR_CODEC_NOT_HEXSTRING; 149 111 150 binlen = length / 2; 151 152 for (iter = 0, ptr = hex ; *ptr ; iter++) 112 for (src = hex ; *src ; ) 153 113 { 154 114 val = 0; /* init/re-init docoding-buffer */ 155 115 156 116 /* decode one character */ 157 #define DECODE_HEX(x) 158 do { 159 buf = *(x); 160 val = (cf_byte)(val << 4); 161 asciiHex = g_ascii_HexDecode[(int)buf];\162 163 val |= (cf_byte) 117 #define DECODE_HEX(x) \ 118 do { \ 119 buf = *(x); \ 120 val = (cf_byte)(val << 4); \ 121 asciiHex = hexdec[(int)buf]; \ 122 \ 123 val |= (cf_byte) \ 164 124 (buf - asciiHex + (asciiHex == '0' ? 0 : 10)); \ 165 125 } while (0) 166 126 167 127 /* decode one byte by decode two character */ 168 DECODE_HEX (ptr++); 169 DECODE_HEX (ptr++); 170 171 bin[iter] = val; 172 } 173 174 * len = binlen; 128 DECODE_HEX (src++); 129 DECODE_HEX (src++); 130 131 *dst++ = val; 132 } 133 *len = length / 2; 175 134 176 135 return CF_OK; … … 196 155 const cf_byte * src = bin; 197 156 char * dst = base64; 157 158 const static char base64enc[] = { 159 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', /* 00 - 07 */ 160 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', /* 08 - 15 */ 161 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', /* 16 - 23 */ 162 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', /* 24 - 31 */ 163 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', /* 32 - 39 */ 164 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', /* 40 - 47 */ 165 'w', 'x', 'y', 'z', '0', '1', '2', '3', /* 48 - 55 */ 166 '4', '5', '6', '7', '8', '9', '+', '/', /* 56 - 63 */ 167 '=' /* padding */ 168 }; 198 169 199 170 ASSERT_ARGS (src == NULL); … … 207 178 #define SEXTUPLE_E_6(__x) (((__x[2]) ) & 0x3f) 208 179 209 for ( ; src - bin < len - 2 ; src += 3) 210 { 211 *dst++ = g_table_Base64Encode[SEXTUPLE_E_1 (src)]; 212 *dst++ = g_table_Base64Encode[SEXTUPLE_E_2 (src)| 213 SEXTUPLE_E_3 (src)]; 214 *dst++ = g_table_Base64Encode[SEXTUPLE_E_4 (src)| 215 SEXTUPLE_E_5 (src)]; 216 *dst++ = g_table_Base64Encode[SEXTUPLE_E_6 (src)]; 217 } 218 219 if (src - bin < len) 220 { 221 *dst++ = g_table_Base64Encode[SEXTUPLE_E_1 (src)]; 180 for ( ; (size_t)(src - bin) < len - 2 ; src += 3) 181 { 182 *dst++ = base64enc[SEXTUPLE_E_1 (src)]; 183 *dst++ = base64enc[SEXTUPLE_E_2 (src) | SEXTUPLE_E_3 (src)]; 184 *dst++ = base64enc[SEXTUPLE_E_4 (src) | SEXTUPLE_E_5 (src)]; 185 *dst++ = base64enc[SEXTUPLE_E_6 (src)]; 186 } 187 188 if ((size_t)(src - bin) < len) 189 { 190 *dst++ = base64enc[SEXTUPLE_E_1 (src)]; 222 191 223 192 if (src - bin == len - 1) 224 193 { 225 *dst++ = g_table_Base64Encode[SEXTUPLE_E_2 (src)];226 *dst++ = g_table_Base64Encode[BASE64_PADDING_CHAR_INDEX];194 *dst++ = base64enc[SEXTUPLE_E_2 (src)]; 195 *dst++ = base64enc[BASE64_PADDING_CHAR_INDEX]; 227 196 } 228 197 else 229 198 { 230 *dst++ = g_table_Base64Encode[SEXTUPLE_E_2 (src)| 231 SEXTUPLE_E_3 (src)]; 232 *dst++ = g_table_Base64Encode[SEXTUPLE_E_4 (src)]; 199 *dst++ = base64enc[SEXTUPLE_E_2 (src) | SEXTUPLE_E_3 (src)]; 200 *dst++ = base64enc[SEXTUPLE_E_4 (src)]; 233 201 } 234 202 235 *dst++ = g_table_Base64Encode[BASE64_PADDING_CHAR_INDEX];203 *dst++ = base64enc[BASE64_PADDING_CHAR_INDEX]; 236 204 } 237 205 *dst = '\0'; … … 243 211 * Base64-decode 244 212 * 245 * \return 성공 시, 디코딩된 바이너리 데이터의 길이; 실패 시, 오류 코드213 * \return 성공 시, CF_OK; 실패 시, 오류 코드 246 214 * 247 215 * \param base64 base64 문자열 … … 259 227 const char * src = base64; 260 228 cf_byte * dst = bin; 261 int remain = 0; 262 int binlen = 0; 229 size_t remain = 0; 230 size_t binlen = 0; 231 232 const static cf_byte base64dec[] = { 233 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 00 - 07 */ 234 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 08 - 15 */ 235 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 16 - 23 */ 236 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 24 - 31 */ 237 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 32 - 39 */ 238 0xff,0xff,0xff, 62,0xff,0xff,0xff, 63, /* 40 - 47 */ 239 52, 53, 54, 55, 56, 57, 58, 59, /* 48 - 55 */ 240 60, 61,0xff,0xff,0xff, 64,0xff,0xff, /* 56 - 63 */ 241 0xff, 0, 1, 2, 3, 4, 5, 6, /* 64 - 71 */ 242 7, 8, 9, 10, 11, 12, 13, 14, /* 71 - 79 */ 243 15, 16, 17, 18, 19, 20, 21, 22, /* 80 - 87 */ 244 23, 24, 25,0xff,0xff,0xff,0xff,0xff, /* 88 - 95 */ 245 0xff, 26, 27, 28, 29, 30, 31, 32, /* 96 - 103 */ 246 33, 34, 35, 36, 37, 38, 39, 40, /* 104 - 111 */ 247 41, 42, 43, 44, 45, 46, 47, 48, /* 112 - 119 */ 248 49, 50, 51,0xff,0xff,0xff,0xff,0xff /* 120 - 127 */ 249 }; 263 250 264 251 ASSERT_ARGS (src == NULL); … … 266 253 ASSERT_ARGS (len == NULL); 267 254 268 *len = 0; 269 270 while (g_ascii_Base64Decode[(int)*src] < BASE64_PADDING_CHAR_INDEX) src++; 255 while (base64dec[(int)*src] < BASE64_PADDING_CHAR_INDEX) src++; 271 256 272 257 if (*src == 0xff) 273 258 return CF_ERROR_CODEC_NOT_BASE64; 274 259 275 remain = ( int)(src - base64);260 remain = (size_t)(src - base64); 276 261 binlen = ((remain + 2/* max padding length */) / 4) * 3; 277 262 278 #define SEXTUPLE_D_1(src) ( g_ascii_Base64Decode[(int)src[0]] << 2)279 #define SEXTUPLE_D_2(src) ( g_ascii_Base64Decode[(int)src[1]] >> 4)280 #define SEXTUPLE_D_3(src) ( g_ascii_Base64Decode[(int)src[1]] << 4)281 #define SEXTUPLE_D_4(src) ( g_ascii_Base64Decode[(int)src[2]] >> 2)282 #define SEXTUPLE_D_5(src) ( g_ascii_Base64Decode[(int)src[2]] << 6)283 #define SEXTUPLE_D_6(src) ( g_ascii_Base64Decode[(int)src[3]] )263 #define SEXTUPLE_D_1(src) (base64dec[(int)src[0]] << 2) 264 #define SEXTUPLE_D_2(src) (base64dec[(int)src[1]] >> 4) 265 #define SEXTUPLE_D_3(src) (base64dec[(int)src[1]] << 4) 266 #define SEXTUPLE_D_4(src) (base64dec[(int)src[2]] >> 2) 267 #define SEXTUPLE_D_5(src) (base64dec[(int)src[2]] << 6) 268 #define SEXTUPLE_D_6(src) (base64dec[(int)src[3]] ) 284 269 285 270 for (src = base64 ; remain > 4 ; remain -= 4, src += 4) … … 297 282 *dst++ = (cf_byte)(SEXTUPLE_D_5 (src) | SEXTUPLE_D_6 (src)); 298 283 299 return binlen - (4 - remain); 300 } 284 *len = binlen - (4 - remain); 285 286 return CF_OK; 287 }
Note:
See TracChangeset
for help on using the changeset viewer.