코드 스니핏 – urlencode, urldecode 샘플

갑자기 필요해졌는데 –_-, 괜찮은 소스코드가 없었다.

그렇다고 내가 만든건 아니고 qDecoder 에서 decode 부분을 –_-( qDecoder에서는 한글이 인코딩이 안되네) 또 어디에서(어디더라, ) encode 부분을 가져와서 간단하게 인터페이스만 살짝 바꾼 버전이다.

고로 –_- 아무것도 내가 한건 없다라고 보면 될듯

MAC에서는 NSString 이 기본적으로 해주는데, c 쪽은 다 직접 해줘야 한다라는 –_-

#include <stdio.h>
#include <string.h>
#include <memory.h>
static const unsigned char hexchars[] = “0123456789ABCDEF”;

char *url_encode(char const *s, int len, int *new_length)
{
    register unsigned char c;
    unsigned char *to, *start;
    unsigned char const *from, *end;

    from = s;
    end = s + len;
    start = to = (unsigned char *) malloc(3 * len + 1);

    while (from < end) {
        c = *from++;
        if (c == ‘ ‘) {
            *to++ = ‘+’;
#ifndef CHARSET_EBCDIC
        } else if ((c < ‘0’ && c != ‘-‘ && c != ‘.’) ||
            (c < ‘A’ && c > ‘9’) ||
            (c > ‘Z’ && c < ‘a’ && c != ‘_’) ||
            (c > ‘z’)) {
                to[0] = ‘%’;
                to[1] = hexchars[c >> 4];
                to[2] = hexchars[c & 15];
                to += 3;
#else /*CHARSET_EBCDIC*/
        } else if (!isalnum(c) && strchr(“_-.”, c) == NULL) {
            /* Allow only alphanumeric chars and ‘_’, ‘-‘, ‘.’; escape the rest */
            to[0] = ‘%’;
            to[1] = hexchars[os_toascii[c] >> 4];
            to[2] = hexchars[os_toascii[c] & 15];
            to += 3;

#endif /*CHARSET_EBCDIC*/
        } else {
            *to++ = c;
        }
    }

    *to = 0;
    if (new_length) {
        *new_length = to – start;
    }

    return (char *) start;
}

/**
* Decode URL encoded string.
*
* @param str    a pointer of URL encoded string.
*
* @return    the length of bytes stored in str in case of successful, otherwise returns NULL
*
* @note
* This modify str directly. And the ‘str’ is always terminated by NULL character.
*/
static char _x2c(char hex_up, char hex_low)
{
    char digit;

    digit = 16 * (hex_up >= ‘A’
        ? ((hex_up & 0xdf) – ‘A’) + 10 : (hex_up – ‘0’));
    digit += (hex_low >= ‘A’
        ? ((hex_low & 0xdf) – ‘A’) + 10 : (hex_low – ‘0’));
    return (digit);
}

int url_decode(char *str, char *target, int size) {
    char *pEncPt, *pBinPt, *pTarPt;

    if (str == NULL || target == NULL || size == 0 ) {
        return 0;
    }

    pBinPt = str;
    pTarPt = target;

    for(pEncPt = str; *pEncPt != ”; pEncPt++) {
        if( (pTarPt – target) >= size )
        {
            pTarPt–;
            break;
        }

        switch (*pEncPt) {
            case ‘+’: {
                *pTarPt++ = ‘ ‘;
                break;
            }
            case ‘%’: {
                *pTarPt++ = _x2c(*(pEncPt + 1), *(pEncPt + 2));
                pEncPt += 2;
                break;
            }
            default: {
                *pTarPt++ = *pEncPt;
                break;
            }
        }
    }
    *pTarPt = ”;

    return (pTarPt – target);
}

int main()
{
    int i, n;
    unsigned char dest[256] = {0x00,};
    unsigned char test[256] = {0x00,};
    char *pTarget;
    unsigned char *str[] = {
        “안녕하세요”,
        “hello world 안녕하세요n”,
         “hello%20world%20%be%c8”,
        “A B C D E F G”,
        NULL
    };

    int count = 0;
    char *pDest = str[count];
    while( NULL != pDest){
        printf(“Original : %d %srn”, strlen(pDest), pDest);
        pTarget = url_encode(pDest, strlen(pDest), NULL);
        printf(“encode   : %d %sn”, strlen(pTarget), pTarget);

        n = url_decode(pTarget, test, 256);
        test[n] = 0;
        printf(“decode   : %d %sn”, n, test);

        free(pTarget);
        count++;
        pDest = str[count];
    }

    return 0;
}