C语言如何实现URL编码?

99ANYc3cd6
预计阅读时长 21 分钟
位置: 首页 C语言 正文

C语言实现URL编码

URL编码(也称为百分比编码)是一种将特殊字符转换为安全字符表示的方法,用于在URL中传输数据,下面我将提供一个完整的C语言实现。

c语言 urlencode
(图片来源网络,侵删)

基本实现

#include <stdio.h>
#include <string.h>
#include <ctype.h>
// 需要编码的字符集合
static const char *needs_encoding = " !\"#$%&'()*+,/:;<=>?@[\\]^`{|}~";
// URL编码函数
void url_encode(const char *src, char *dest, int max_len) {
    const unsigned char *p = (const unsigned char *)src;
    char *d = dest;
    int len = 0;
    while (*p && len < max_len - 1) {
        if (isalnum(*p) || *p == '-' || *p == '_' || *p == '.' || *p == '~') {
            // 这些字符不需要编码
            *d++ = *p;
            len++;
        } else if (strchr(needs_encoding, *p)) {
            // 特殊字符需要编码
            if (len >= max_len - 3) break; // 需要空间存储%XX
            sprintf(d, "%%%02X", *p);
            d += 3;
            len += 3;
        } else {
            // 其他字符(如非ASCII字符)也需要编码
            if (len >= max_len - 3) break;
            sprintf(d, "%%%02X", *p);
            d += 3;
            len += 3;
        }
        p++;
    }
    *d = '\0';
}
int main() {
    const char *test_str = "Hello World! 你好 123@#$%";
    char encoded[256];
    url_encode(test_str, encoded, sizeof(encoded));
    printf("原始字符串: %s\n", test_str);
    printf("编码后字符串: %s\n", encoded);
    return 0;
}

更完整的实现(处理非ASCII字符)

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <locale.h>
// URL编码函数(处理UTF-8字符)
void url_encode_utf8(const char *src, char *dest, size_t max_len) {
    const unsigned char *p = (const unsigned char *)src;
    char *d = dest;
    size_t len = 0;
    while (*p && len < max_len - 1) {
        if (isalnum(*p) || *p == '-' || *p == '_' || *p == '.' || *p == '~') {
            // 这些字符不需要编码
            *d++ = *p;
            len++;
        } else if (*p < 128) {
            // ASCII字符需要编码的特殊字符
            if (len >= max_len - 3) break;
            sprintf(d, "%%%02X", *p);
            d += 3;
            len += 3;
        } else {
            // 非ASCII字符(UTF-8多字节字符)
            int bytes = 0;
            unsigned int codepoint = 0;
            // 确定UTF-8字符的字节数
            if ((*p & 0xE0) == 0xC0) { bytes = 2; codepoint = *p & 0x1F; }
            else if ((*p & 0xF0) == 0xE0) { bytes = 3; codepoint = *p & 0x0F; }
            else if ((*p & 0xF8) == 0xF0) { bytes = 4; codepoint = *p & 0x07; }
            else { bytes = 1; codepoint = *p; } // 无效UTF-8,按单字节处理
            // 检查是否有足够空间
            if (len + bytes * 3 >= max_len) break;
            // 处理UTF-8字符的每个字节
            for (int i = 0; i < bytes; i++) {
                if (len >= max_len - 3) break;
                sprintf(d, "%%%02X", *p);
                d += 3;
                len += 3;
                p++;
            }
            continue; // 已经处理了p的移动
        }
        p++;
    }
    *d = '\0';
}
int main() {
    setlocale(LC_ALL, ""); // 设置本地化环境以支持宽字符
    const char *test_str = "Hello World! 你好 123@#$% 中文测试";
    char encoded[512];
    url_encode_utf8(test_str, encoded, sizeof(encoded));
    printf("原始字符串: %s\n", test_str);
    printf("编码后字符串: %s\n", encoded);
    return 0;
}

URL解码函数

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
// URL解码函数
void url_decode(const char *src, char *dest, size_t max_len) {
    const char *p = src;
    char *d = dest;
    size_t len = 0;
    while (*p && len < max_len - 1) {
        if (*p == '%' && *(p+1) && *(p+2)) {
            // 检查是否是有效的十六进制数字
            if (isxdigit(*(p+1)) && isxdigit(*(p+2))) {
                char hex[3] = {*(p+1), *(p+2), '\0'};
                *d++ = (char)strtol(hex, NULL, 16);
                len++;
                p += 3;
            } else {
                // 无效的编码,直接复制%
                *d++ = *p++;
                len++;
            }
        } else if (*p == '+') {
            // 空格在URL中有时被编码为+
            *d++ = ' ';
            len++;
            p++;
        } else {
            // 普通字符直接复制
            *d++ = *p++;
            len++;
        }
    }
    *d = '\0';
}
int main() {
    const char *encoded_str = "Hello%20World%21%20%E4%BD%A0%E5%A5%BD%20123%40%23%24%25";
    char decoded[256];
    url_decode(encoded_str, decoded, sizeof(decoded));
    printf("编码字符串: %s\n", encoded_str);
    printf("解码字符串: %s\n", decoded);
    return 0;
}

使用示例

#include <stdio.h>
#include "url_encode.h" // 假设上面的函数定义在这个头文件中
int main() {
    // 编码示例
    const char *to_encode = "参数值=测试&name=张三";
    char encoded[256];
    url_encode(to_encode, encoded, sizeof(encoded));
    printf("编码: %s -> %s\n", to_encode, encoded);
    // 解码示例
    const char *to_decode = "%%20%E6%B5%8B%E8%AF%95";
    char decoded[256];
    url_decode(to_decode, decoded, sizeof(decoded));
    printf("解码: %s -> %s\n", to_decode, decoded);
    return 0;
}

注意事项

  1. 编码函数需要确保目标缓冲区足够大,最坏情况下每个字符都会变成3个字符(%XX)
  2. 对于非ASCII字符(如中文),需要正确处理UTF-8编码
  3. 空格在URL中通常编码为%20,但有时也会用+表示
  4. 实际应用中可能需要根据具体需求调整需要编码的字符集
  5. 考虑添加错误处理,特别是对于无效的UTF-8序列

实现提供了基本的URL编码和解码功能,可以根据具体需求进行扩展和优化。

c语言 urlencode
(图片来源网络,侵删)
-- 展开阅读全文 --
头像
织梦CMS数据库操作有哪些核心方法?
« 上一篇 03-01
QtCreator如何高效编写C语言程序?
下一篇 » 03-01
取消
微信二维码
支付宝二维码

目录[+]