Last active
December 13, 2022 06:40
-
-
Save HeiSir2014/cce209e35a89d67acf3ec04238418c6c to your computer and use it in GitHub Desktop.
C++ String Windows下操作 UNICODE <-> Ansi GBK <->UTF8
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "stdafx.h" | |
#include <Windows.h> | |
#include "StringCode.h" | |
using namespace std; | |
CStringCode::CStringCode() | |
{ | |
} | |
CStringCode::~CStringCode() | |
{ | |
} | |
std::string CStringCode::UTF8ToGBK(const std::string & str) | |
{ | |
wchar_t* pElementText; | |
int iTextLen; | |
// wide char to multi char | |
iTextLen = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.size(), NULL, NULL); | |
pElementText = new wchar_t[iTextLen + 1]; | |
memset((void*)pElementText, 0, sizeof(wchar_t) * (iTextLen + 1)); | |
::MultiByteToWideChar(CP_UTF8, | |
0, | |
str.c_str(), | |
str.size(), | |
pElementText, | |
iTextLen); | |
wstring strText; | |
strText = pElementText; | |
delete[] pElementText; | |
return UnicodeToANSI(strText); | |
} | |
std::string CStringCode::UnicodeToUTF8(const std::wstring & str) | |
{ | |
char* pElementText; | |
int iTextLen; | |
// wide char to multi char | |
iTextLen = WideCharToMultiByte(CP_UTF8, | |
0, | |
str.c_str(), | |
-1, | |
NULL, | |
0, | |
NULL, | |
NULL); | |
pElementText = new char[iTextLen + 1]; | |
memset((void*)pElementText, 0, sizeof(char) * (iTextLen + 1)); | |
::WideCharToMultiByte(CP_UTF8, | |
0, | |
str.c_str(), | |
-1, | |
pElementText, | |
iTextLen, | |
NULL, | |
NULL); | |
string strText; | |
strText = pElementText; | |
delete[] pElementText; | |
return strText; | |
} | |
std::wstring CStringCode::UTF8ToUnicode(const std::string & str) | |
{ | |
wchar_t* pElementText; | |
int iTextLen; | |
// wide char to multi char | |
iTextLen = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.size(), NULL, NULL); | |
pElementText = new wchar_t[iTextLen + 1]; | |
memset((void*)pElementText, 0, sizeof(wchar_t) * (iTextLen + 1)); | |
::MultiByteToWideChar(CP_UTF8, | |
0, | |
str.c_str(), | |
str.size(), | |
pElementText, | |
iTextLen); | |
wstring strText; | |
strText = pElementText; | |
delete[] pElementText; | |
return strText; | |
} | |
std::string CStringCode::UnicodeToANSI(const std::wstring & str) | |
{ | |
char* pElementText; | |
int iTextLen; | |
// wide char to multi char | |
iTextLen = WideCharToMultiByte(CP_ACP, | |
0, | |
str.c_str(), | |
-1, | |
NULL, | |
0, | |
NULL, | |
NULL); | |
pElementText = new char[iTextLen + 1]; | |
memset((void*)pElementText, 0, sizeof(char) * (iTextLen + 1)); | |
::WideCharToMultiByte(CP_ACP, | |
0, | |
str.c_str(), | |
-1, | |
pElementText, | |
iTextLen, | |
NULL, | |
NULL); | |
string strText; | |
strText = pElementText; | |
delete[] pElementText; | |
return strText; | |
} | |
std::wstring CStringCode::GBKToUNICODE(const std::string & str) | |
{ | |
wstring strTo; | |
int iTextLen; | |
// wide char to multi char | |
iTextLen = MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.size(), NULL, NULL); | |
if (iTextLen > 0) | |
{ | |
strTo.resize(iTextLen); | |
::MultiByteToWideChar(CP_ACP, | |
0, | |
str.c_str(), | |
str.size(), | |
(wchar_t*)strTo.c_str(), | |
strTo.size()); | |
} | |
return strTo; | |
} | |
std::string CStringCode::GBKToUTF8(const std::string & str) | |
{ | |
return UnicodeToUTF8(GBKToUNICODE(str)); | |
} | |
std::string CStringCode::Base64Encode(const std::string & in) | |
{ | |
string sOut; | |
Base64::Encode(in, &sOut); | |
return sOut; | |
} | |
std::string CStringCode::Base64Decode(const std::string & in) | |
{ | |
string sOut; | |
Base64::Decode(in, &sOut); | |
return sOut; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include <string> | |
class CStringCode | |
{ | |
public: | |
CStringCode(); | |
~CStringCode(); | |
static std::string UTF8ToGBK(const std::string& str); | |
static std::string UnicodeToUTF8(const std::wstring& str); | |
static std::wstring UTF8ToUnicode(const std::string & str); | |
static std::string UnicodeToANSI(const std::wstring& str); | |
static std::wstring GBKToUNICODE(const std::string& str); | |
static std::string GBKToUTF8(const std::string& str); | |
static std::string Base64Encode(const std::string &in); | |
static std::string Base64Decode(const std::string &in); | |
}; | |
#ifndef BASE64_H | |
#define BASE64_H | |
const char kBase64Alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" | |
"abcdefghijklmnopqrstuvwxyz" | |
"0123456789+/"; | |
class Base64 { | |
public: | |
static bool Encode(const std::string &in, std::string *out) { | |
int i = 0, j = 0; | |
size_t enc_len = 0; | |
unsigned char a3[3]; | |
unsigned char a4[4]; | |
out->resize(EncodedLength(in)); | |
int input_len = in.size(); | |
std::string::const_iterator input = in.begin(); | |
while (input_len--) { | |
a3[i++] = *(input++); | |
if (i == 3) { | |
a3_to_a4(a4, a3); | |
for (i = 0; i < 4; i++) { | |
(*out)[enc_len++] = kBase64Alphabet[a4[i]]; | |
} | |
i = 0; | |
} | |
} | |
if (i) { | |
for (j = i; j < 3; j++) { | |
a3[j] = '\0'; | |
} | |
a3_to_a4(a4, a3); | |
for (j = 0; j < i + 1; j++) { | |
(*out)[enc_len++] = kBase64Alphabet[a4[j]]; | |
} | |
while ((i++ < 3)) { | |
(*out)[enc_len++] = '='; | |
} | |
} | |
return (enc_len == out->size()); | |
} | |
static bool Encode(const char *input, size_t input_length, char *out, size_t out_length) { | |
int i = 0, j = 0; | |
char *out_begin = out; | |
unsigned char a3[3]; | |
unsigned char a4[4]; | |
size_t encoded_length = EncodedLength(input_length); | |
if (out_length < encoded_length) return false; | |
while (input_length--) { | |
a3[i++] = *input++; | |
if (i == 3) { | |
a3_to_a4(a4, a3); | |
for (i = 0; i < 4; i++) { | |
*out++ = kBase64Alphabet[a4[i]]; | |
} | |
i = 0; | |
} | |
} | |
if (i) { | |
for (j = i; j < 3; j++) { | |
a3[j] = '\0'; | |
} | |
a3_to_a4(a4, a3); | |
for (j = 0; j < i + 1; j++) { | |
*out++ = kBase64Alphabet[a4[j]]; | |
} | |
while ((i++ < 3)) { | |
*out++ = '='; | |
} | |
} | |
return (out == (out_begin + encoded_length)); | |
} | |
static bool Decode(const std::string &in, std::string *out) { | |
int i = 0, j = 0; | |
size_t dec_len = 0; | |
unsigned char a3[3]; | |
unsigned char a4[4]; | |
int input_len = in.size(); | |
std::string::const_iterator input = in.begin(); | |
out->resize(DecodedLength(in)); | |
while (input_len--) { | |
if (*input == '=') { | |
break; | |
} | |
a4[i++] = *(input++); | |
if (i == 4) { | |
for (i = 0; i <4; i++) { | |
a4[i] = b64_lookup(a4[i]); | |
} | |
a4_to_a3(a3, a4); | |
for (i = 0; i < 3; i++) { | |
(*out)[dec_len++] = a3[i]; | |
} | |
i = 0; | |
} | |
} | |
if (i) { | |
for (j = i; j < 4; j++) { | |
a4[j] = '\0'; | |
} | |
for (j = 0; j < 4; j++) { | |
a4[j] = b64_lookup(a4[j]); | |
} | |
a4_to_a3(a3, a4); | |
for (j = 0; j < i - 1; j++) { | |
(*out)[dec_len++] = a3[j]; | |
} | |
} | |
return (dec_len == out->size()); | |
} | |
static bool Decode(const char *input, size_t input_length, char *out, size_t out_length) { | |
int i = 0, j = 0; | |
char *out_begin = out; | |
unsigned char a3[3]; | |
unsigned char a4[4]; | |
size_t decoded_length = DecodedLength(input, input_length); | |
if (out_length < decoded_length) return false; | |
while (input_length--) { | |
if (*input == '=') { | |
break; | |
} | |
a4[i++] = *(input++); | |
if (i == 4) { | |
for (i = 0; i <4; i++) { | |
a4[i] = b64_lookup(a4[i]); | |
} | |
a4_to_a3(a3, a4); | |
for (i = 0; i < 3; i++) { | |
*out++ = a3[i]; | |
} | |
i = 0; | |
} | |
} | |
if (i) { | |
for (j = i; j < 4; j++) { | |
a4[j] = '\0'; | |
} | |
for (j = 0; j < 4; j++) { | |
a4[j] = b64_lookup(a4[j]); | |
} | |
a4_to_a3(a3, a4); | |
for (j = 0; j < i - 1; j++) { | |
*out++ = a3[j]; | |
} | |
} | |
return (out == (out_begin + decoded_length)); | |
} | |
static int DecodedLength(const char *in, size_t in_length) { | |
int numEq = 0; | |
const char *in_end = in + in_length; | |
while (*--in_end == '=') ++numEq; | |
return ((6 * in_length) / 8) - numEq; | |
} | |
static int DecodedLength(const std::string &in) { | |
int numEq = 0; | |
int n = in.size(); | |
for (std::string::const_reverse_iterator it = in.rbegin(); *it == '='; ++it) { | |
++numEq; | |
} | |
return ((6 * n) / 8) - numEq; | |
} | |
inline static int EncodedLength(size_t length) { | |
return (length + 2 - ((length + 2) % 3)) / 3 * 4; | |
} | |
inline static int EncodedLength(const std::string &in) { | |
return EncodedLength(in.length()); | |
} | |
inline static void StripPadding(std::string *in) { | |
while (!in->empty() && *(in->rbegin()) == '=') in->resize(in->size() - 1); | |
} | |
private: | |
static inline void a3_to_a4(unsigned char * a4, unsigned char * a3) { | |
a4[0] = (a3[0] & 0xfc) >> 2; | |
a4[1] = ((a3[0] & 0x03) << 4) + ((a3[1] & 0xf0) >> 4); | |
a4[2] = ((a3[1] & 0x0f) << 2) + ((a3[2] & 0xc0) >> 6); | |
a4[3] = (a3[2] & 0x3f); | |
} | |
static inline void a4_to_a3(unsigned char * a3, unsigned char * a4) { | |
a3[0] = (a4[0] << 2) + ((a4[1] & 0x30) >> 4); | |
a3[1] = ((a4[1] & 0xf) << 4) + ((a4[2] & 0x3c) >> 2); | |
a3[2] = ((a4[2] & 0x3) << 6) + a4[3]; | |
} | |
static inline unsigned char b64_lookup(unsigned char c) { | |
if (c >= 'A' && c <= 'Z') return c - 'A'; | |
if (c >= 'a' && c <= 'z') return c - 71; | |
if (c >= '0' && c <= '9') return c + 4; | |
if (c == '+') return 62; | |
if (c == '/') return 63; | |
return 255; | |
} | |
}; | |
#endif // BASE64_H |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment