urldecode && unicode2utf8 for c/c++

本文详细介绍了URL解码的实现方法,参考了openssl官方代码,并提供了具体的C语言实现示例。同时,文章还讲解了Unicode到UTF-8的转换过程,包括Unicode的表达方式、内存分布及具体的转换代码。

urldecode

可以参考 openssl 官方的实现: https://github.com/openssl/openssl/blob/0770c882150ea0159cc2b0a2cea2e8ed8442f36f/apps/ocsp.c
文中搜素 : urldecode 关键字

我把它摘录出来整理下,就是如下代码:

#include <ctype.h>
#include <stdio.h>
#include <string>
#include <string.h>
#include <stdlib.h>

#define _UC(c) ((unsigned char)(c))

int OPENSSL_hexchar2int(unsigned char c)
{
#ifdef CHARSET_EBCDIC
    c = os_toebcdic[c];
#endif

    switch (c) {
    case '0':
        return 0;
    case '1':
        return 1;
    case '2':
        return 2;
    case '3':
        return 3;
    case '4':
          return 4;
    case '5':
          return 5;
    case '6':
          return 6;
    case '7':
          return 7;
    case '8':
          return 8;
    case '9':
          return 9;
    case 'a': case 'A':
          return 0x0A;
    case 'b': case 'B':
          return 0x0B;
    case 'c': case 'C':
          return 0x0C;
    case 'd': case 'D':
          return 0x0D;
    case 'e': case 'E':
          return 0x0E;
    case 'f': case 'F':
          return 0x0F;
    }
    return -1;
}

static int urldecode(char *p)
{
    unsigned char *out = (unsigned char *)p;
    unsigned char *save = out;

    for (; *p; p++) {
        if (*p != '%')
            *out++ = *p;
        else if (isxdigit(_UC(p[1])) && isxdigit(_UC(p[2]))) {
            /* Don't check, can't fail because of ixdigit() call. */
            *out++ = (OPENSSL_hexchar2int(p[1]) << 4)
                   | OPENSSL_hexchar2int(p[2]);
            p += 2;
        }
        else
            return -1;
    }
    *out = '\0';
    return (int)(out - save);
}

unicode2utf8

unicode 的几种表达方式:

  • 字面值

    • 比如以下表示爱我中华
      \u5341\u4e8c\u795e\u5175\u5668
      
    • 这只是一种书写表达方式
    • 大多数语言,都在字符串中用这种表达方式,来表示这个字符是 unicode 编码来解析
  • 内存中

    • 按 unicode 编码规则,真实在内存中的分布情况
    • c/c++ 中字符串用比如 L"爱我中华" 来告知编译器,初始化变量时,需要按 unicode 编码规则,填充内存
    • c/c++ 中使用 std::wstring 、 wchar_t 、 wchar 等类型处理 unicode 编码

具体 unicode2utf8 的代码类似如下:

int htoi(char s[])
{
    return strtol(s, NULL, 16);
}

std::wstring decodeUnicode(const std::string &unicodeString)
{
    std::wstring out;
    char aChar;
    int len = (int)unicodeString.size();
    char *data = (char *)unicodeString.data();
    for (int x = 0; x < len;) {
        aChar = data[x++];
        if (aChar == '\\') {
            aChar = data[x++];
            if (aChar == 'u') {
                char tempChar[5] = { data[x++], data[x++], data[x++], data[x++], 0 };
                out += (wchar_t)htoi(tempChar);
            } else {
                printf("format error!\n");
                return L"";
            }
        } else
            out += (wchar_t)aChar;
    }
    return out;
}

int main()
{
    // 需要设置这行, 不然 wcstombs 会执行失败。 unicode 转 utf-8 必须要依赖系统字符集
    setlocale(LC_ALL, "");

    // 其他语言常见的字面值表达方式
    std::string data0 = "\\u5341\\u4e8c\\u795e\\u5175\\u5668";

    // 通过 decodeUnicode 转化为 c/c++ 可识别的 unicode 内存分布方式
    std::wstring data2 = decodeUnicode(data0);

    // 使用 wcstombs 函数把 unicode 编码转化为 utf-8 编码
    len = wcstombs(nullptr, (wchar_t*)data2.data(), 0);
    std::string data3;
    data3.resize(len);
    wcstombs((char*)data3.c_str(), (wchar_t*)data2.data(), data3.size());
    printf("data3:%s\n", data3.c_str());

    return 0;
}

unicode to utf8 也可以使用其他库,比如 https://github.com/breezechen/sconv

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

fananchong2

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值