실무에서 직접사용했던 C언어 URL인코딩 코드를 소개한다.
C언어로 구현한 URL 인코딩 코드
char encodedText[1500+1];
const char* hex = "0123456789abcdef";
int pos = 0;
int n = strlen(context->cryp_ctt);
for (int i = 0; i < n; i++){
if (('a' <= context->cryp_ctt[i] && context->cryp_ctt[i] <= 'z')
|| ('A' <= context->cryp_ctt[i] && context->cryp_ctt[i] <= 'Z')
|| ('0' <= context->cryp_ctt[i] && context->cryp_ctt[i] <= '9'))
{
encodedText[pos++] = context->cryp_ctt[i];
}
else {
encodedText[pos++] = '%';
encodedText[pos++] = hex[context->cryp_ctt[i] >> 4];
encodedText[pos++] = hex[context->cryp_ctt[i] & 15];
}
}
encodedText[pos] = '\0';
strcpy(context->url_enc_ctt, encodedText);
한 줄씩 뜯어보자
char encodedText[1500+1]; // 인코딩된 값을 저장할 지역변수
const char *hex = "0123456789abcdefg";
문자열 배열 포인터 : 읽기 전용 메모리에 할당되어 변경이 불가능하다!
16진수로 값을 변환하기 위한 참조용도의 문자열이기 때문에 값이 변하지 않는 것이 좋다.
/* for문 : 인코딩 대상 문자열 하나씩 보면서 */
if (('a' <= context->cryp_ctt[i] && context->cryp_ctt[i] <= 'z')
|| ('A' <= context->cryp_ctt[i] && context->cryp_ctt[i] <= 'Z')
|| ('0' <= context->cryp_ctt[i] && context->cryp_ctt[i] <= '9'))
{
encodedText[pos++] = context->cryp_ctt[i];
}
현재 문자값이 알파벳
혹은 숫자
라면
해당 문자를 그대로 저장하고 저장할 문자열의 인덱스를 증가시킨다.
그대로 저장하는 이유? 기존값 자체가 아스키 코드 값이기 때문에 변환할 필요가 없어서
/* for문 : 인코딩 대상 문자열 하나씩 보면서 */
else {
encodedText[pos++] = '%';
encodedText[pos++] = hex[context->cryp_ctt[i] >> 4];
encodedText[pos++] = hex[context->cryp_ctt[i] & 15];
}
context->cryp_ctt[i] >> 4
context->cryp_ctt[i]
앞의 4비트 부분은 뒤에 4비트가 된다.context->cryp_ctt[i]
// 16 (몫을 반환)context->cryp_ctt[i]
의 앞에 4비트를 저장하고 있는 역할11110001(241)
->00001111(15)
-> hex[15]
-> f
00001111
&
연산자는 둘다 1일 경우만 1반환context->cryp_ctt[i]
연산 결과 앞에 4자리는 무조건 0
, 뒤에 4자리는 context->cryp_ctt[i]
문자열과 동일11110001(241)
-> 00000001(1)
-> hex[1]
-> 1
-> 11110001(241)
은 아스키 코드로 ±
-> ±
url인코딩 결과값은 %f1
복호화도 똑같은 방식으로 반대로 해주면 쉽게 가능하다.