C语言实现encode和decode

来源:互联网 发布:腾讯程序员工资 编辑:程序博客网 时间:2024/05/20 15:39
此文章出处:http://www.cppblog.com/izualzhy/archive/2012/07/09/182456.html

Technorati 标签: urlencode,urldecode

先看个例子:

汉字 一 的UTF-8编码为0xE4 0xb8 0x 80

我们在google里搜索一下“一”,地址栏显示为:

image

可以看到url的字符串里有一个%E4%B8%80

这就是encode之后的值。因此,encode的处理过程也很明显了。

特别是传中文参数时,如果没有encode,很容易出错。

至于为什么要这么传,就不知道了,今天,现来看下C语言如何实现url encode函数.

首先是urlencode的编码规则,可以看这里,搜到一篇文章没有仔细研究,可能有不全的地方:

http://hi.baidu.com/leejun_2005/item/9e0f4e4ba62cde0bc11613b5
解码:

/* * ===================================================================================== *       Filename:  url_decode.cpp *    Description:  url decode * *        Created:  07/06/2012 07:35:14 PM *         Author:  zhy (), izualzhy@163.com * ===================================================================================== */#include <stdio.h>#include <string.h>#define NON_NUM '0'int hex2num(char c){    if (c>='0' && c<='9') return c - '0';    if (c>='a' && c<='z') return c - 'a' + 10;//这里+10的原因是:比如16进制的a值为10    if (c>='A' && c<='Z') return c - 'A' + 10;        printf("unexpected char: %c", c);    return NON_NUM;}/** * @brief URLDecode 对字符串URL解码,编码的逆过程 * * @param str 原字符串 * @param strSize 原字符串大小(不包括最后的\0) * @param result 结果字符串缓存区 * @param resultSize 结果地址的缓冲区大小(包括最后的\0) * * @return: >0 result 里实际有效的字符串长度 *            0 解码失败 */int URLDecode(const char* str, const int strSize, char* result, const int resultSize){    char ch,ch1,ch2;    int i;    int j = 0;//record result index    if ((str==NULL) || (result==NULL) || (strSize<=0) || (resultSize<=0)) {        return 0;    }    for ( i=0; (i<strSize) && (j<resultSize); ++i) {        ch = str[i];        switch (ch) {            case '+':                result[j++] = ' ';                break;            case '%':                if (i+2<strSize) {                    ch1 = hex2num(str[i+1]);//高4位                    ch2 = hex2num(str[i+2]);//低4位                    if ((ch1!=NON_NUM) && (ch2!=NON_NUM))                        result[j++] = (char)((ch1<<4) | ch2);                    i += 2;                    break;                } else {                    break;                }            default:                result[j++] = ch;                break;        }    }        result[j] = 0;    return j;}int main(int argc, char* argv[]){    char* src = argv[1];    char obj[100] = {0};    unsigned int len = strlen(src);    int resultSize = URLDecode(src, len, obj, 100);    printf("result: %d, %s\n", resultSize, obj);    return 0;}

编码:

/* * ===================================================================================== *       Filename:  url_encode.cpp *    Description:  url encode * *        Created:  07/04/2012 08:32:24 PM * *         Author:  zhy (), izualzhy@163.com * ===================================================================================== */#include <stdio.h>#include <string.h>/** * @brief URLEncode 对字符串URL编码 * * @param str 原字符串 * @param strSize 原字符串长度(不包括最后的\0) * @param result 结果缓冲区的地址 * @param resultSize 结果缓冲区的大小(包括最后的\0) * * @return: >0:resultstring 里实际有效的长度 *            0: 解码失败. */int URLEncode(const char* str, const int strSize, char* result, const int resultSize){    int i;    int j = 0;//for result index    char ch;    if ((str==NULL) || (result==NULL) || (strSize<=0) || (resultSize<=0)) {        return 0;    }    for ( i=0; (i<strSize)&&(j<resultSize); ++i) {        ch = str[i];        if (((ch>='A') && (ch<'Z')) ||            ((ch>='a') && (ch<'z')) ||            ((ch>='0') && (ch<'9'))) {            result[j++] = ch;        } else if (ch == ' ') {            result[j++] = '+';        } else if (ch == '.' || ch == '-' || ch == '_' || ch == '*') {            result[j++] = ch;        } else {            if (j+3 < resultSize) {                sprintf(result+j, "%%%02X", (unsigned char)ch);                j += 3;            } else {                return 0;            }        }    }    result[j] = '\0';    return j;}int main(int argc, char* argv[]){    char* src = argv[1];    unsigned int srclength = strlen(src);    printf("src length: %d\n", strlen(src));        char obj[100] = {0};    URLEncode(src, srclength, obj, 100);    printf("obj: %s\n", obj);    printf("obj: %d\n", strlen(obj));    return 0;}

输出:

y@y-VirtualBox:/mnt/Documents/Training$ ./url_encode 一^abc_二
src length: 11
obj: %E4%B8%80%5Eabc_%E4%BA%8C
obj: 25
y@y-VirtualBox:/mnt/Documents/Training$ ./url_decode %E4%B8%80%5Eabc_%E4%BA%8C
result: 11, 一^abc_二

使用google搜索下:

image

注:

1.AA –> “%AA”,使用sprintf。

2.”%AA” –> AA, 使用位移。

参考:

http://hi.baidu.com/zkheartboy/blog/item/5813a28fa0d224ebf11f363d.html

http://hi.baidu.com/leejun_2005/item/9e0f4e4ba62cde0bc11613b5

原创粉丝点击