将C ++ std :: string转换为UTF-16-LE编码的字符串

时间:2018-10-08 13:40:59

标签: c++ utf-8 character-encoding utf-16 stdstring

今天我已经搜索了几个小时,但找不到适合我的任何东西。我刚刚看过的一个没有运气的是“ How to convert UTF-8 encoded std::string to UTF-16 std::string ”。

我的问题是,有一个简短的解释:

我想在std C ++中创建有效的NTLM哈希,并且我正在使用OpenSSL的库通过其MD4例程创建哈希。我知道该怎么做,所以有人知道如何将std::string转换为UTF-16 LE编码的字符串,然后将其传递给MD4函数以获取正确的摘要吗?

因此,我可以拥有一个std::string类型的char并将其转换为UTF16-LE编码的可变长度std :: string_type吗?是std::u16string还是std::wstring

我会使用s.c_str()还是s.data(),并且length()函数在两种情况下都能正确报告吗?

2 个答案:

答案 0 :(得分:1)

我认为这种方法应该可以解决问题

std::string utf16_to_utf8(std::u16string const& s)
{
    std::wstring_convert<std::codecvt_utf8_utf16<char16_t, 0x10ffff,
        std::codecvt_mode::little_endian>, char16_t> cnv;
    std::string utf8 = cnv.to_bytes(s);
    if(cnv.converted() < s.size())
        throw std::runtime_error("incomplete conversion");
    return utf8;
}

std::u16string utf8_to_utf16(std::string const& utf8)
{
    std::wstring_convert<std::codecvt_utf8_utf16<char16_t, 0x10ffff,
        std::codecvt_mode::little_endian>, char16_t> cnv;
    std::u16string s = cnv.from_bytes(utf8);
    if(cnv.converted() < utf8.size())
        throw std::runtime_error("incomplete conversion");
    return s;
}

注意std::wstring_convertC++17中已被 弃用 ,但我仍然喜欢使用它,而不是非标准库,因为它是可移植的,没有依赖关系,并且无疑会保留到替换。

而且,如果其他所有方法均失败,则可以使用备用代码重新实现这些相同的功能,而无需更改应用程序的任何其他部分。

答案 1 :(得分:0)

道歉,第一手……这将是一个很丑陋的答复,带有一些长代码。我最终使用了以下功能,同时将char* conver(const char* in, size_t in_len, size_t* used_len) { const int CC_MUL = 2; // 16 bit setlocale(LC_ALL, ""); char* t1 = setlocale(LC_CTYPE, ""); char* locn = (char*)calloc(strlen(t1) + 1, sizeof(char)); if(locn == NULL) { return 0; } strcpy(locn, t1); const char* enc = strchr(locn, '.') + 1; #if _WINDOWS std::string win = "WINDOWS-"; win += enc; enc = win.c_str(); #endif iconv_t foo = iconv_open("UTF-16LE", enc); if(foo == (void*)-1) { if (errno == EINVAL) { fprintf(stderr, "Conversion from %s is not supported\n", enc); } else { fprintf(stderr, "Initialization failure:\n"); } free(locn); return 0; } size_t out_len = CC_MUL * in_len; size_t saved_in_len = in_len; iconv(foo, NULL, NULL, NULL, NULL); char* converted = (char*)calloc(out_len, sizeof(char)); char *converted_start = converted; char* t = const_cast<char*>(in); int ret = iconv(foo, &t, &in_len, &converted, &out_len); iconv_close(foo); *used_len = CC_MUL * saved_in_len - out_len; if(ret == -1) { switch(errno) { case EILSEQ: fprintf(stderr, "EILSEQ\n"); break; case EINVAL: fprintf(stderr, "EINVAL\n"); break; } perror("iconv"); free(locn); return 0; } else { free(locn); return converted_start; } } 有效地按文件编译到Windows应用程序文件中:)

希望这会有所帮助。

SharedModule