C언어로 작성한 URL인코딩

Ilhoon·2022년 2월 21일
1

C언어 활용하기

목록 보기
1/1

실무에서 직접사용했던 C언어 URL인코딩 코드를 소개한다.


URL인코딩을 해야하는 이유?

  • 오로지 ASCII문자만 인터넷을 통해 전송할 수 있다.
  • ASCII문자라 하더라도 예약어는 따로 처리가 필요하다. (/, &, = 등등)



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

  • 현재 문자 값을 비트연산으로 4비트 오른쪽 시프트
  • context->cryp_ctt[i] 앞의 4비트 부분은 뒤에 4비트가 된다.
  • context->cryp_ctt[i] // 16 (몫을 반환)
  • 이 값은 무조건 0~15중 하나기 때문에 hex문자열에서 문자 하나로 반드시 할당 가능하다
  • context->cryp_ctt[i]의 앞에 4비트를 저장하고 있는 역할
  • ex) 11110001(241) ->00001111(15) -> hex[15] -> f

context->cryp_ctt[i] & 15
  • 15의 비트패턴은 00001111
  • &연산자는 둘다 1일 경우만 1반환
  • 따라서 context->cryp_ctt[i] 연산 결과 앞에 4자리는 무조건 0 , 뒤에 4자리는 context->cryp_ctt[i]문자열과 동일
  • ex) 11110001(241) -> 00000001(1) -> hex[1] -> 1

즉 인코딩 전 문자의 비트패턴을 각각 4자리씩 분리해서 2개의 문자로 저장하는 것이다

-> 11110001(241) 은 아스키 코드로 ±

-> ± url인코딩 결과값은 %f1

복호화도 똑같은 방식으로 반대로 해주면 쉽게 가능하다.

profile
꾸준하게!

0개의 댓글