Recently tuned Linux certificate verification problem, because to the client sent over the certificate on the server and root certificate authentication, so in the reading certificate, authentication certificate design to the problem of coding conversion. Under Windows, there is no problem with MultiByteToWideChar and WideCharToMultiByte, but under Linux, there are no two functions, so we think of two functions with wcstombs and mbstowcs, but experimentally, Can not get the correct result, later, after analysis, get, under Windows wchar_t to 2 bytes, while in Linux wchar_t 4 bytes, we extracted the certificate encoded as a 2-byte wide character, so can not be correctly converted. You have to, you can only use Libiconv for conversion.
The header file of the Iconv function family is iconv.h.
#include <iconv.h>
The Iconv function family has three functions, and the prototype is as follows:
(1) iconv_t iconv_open (const char *tocode, const char *fromcode);
This function describes what two encodings will be converted, Tocode is the target encoding, Fromcode is the original encoding, which returns a conversion handle for use by the following two functions.
(2) size_t iconv (iconv_t cd,char **inbuf,size_t *inbytesleft,char);
This function reads characters from INBUF, converts them to Outbuf, Inbytesleft records the number of characters that have not yet been converted, outbytesleft the remaining space to record the output buffer. (3) int iconv_close (iconv_t CD);
This function closes the conversion handle and frees the resource.
After testing, the following points need to be noted for using this transformation function:
1, wide byte exists Big-endian and Little-endian, that use wide character encoding when the encoding name is not the same, for example, we use the UCS-2 code, that has "UCS-2" and "ucs-2-internal" of the points;
2, the length of the two in the Iconv after the function, respectively, the allocation of cache remaining bytes size;
3, and two pointers to the end of the converted string, so before making the conversion, you should keep the cached original pointer, after conversion, with these two pointers minus the original pointer, that is the length of the converted bytes and the length of the converted bytes.
The following is my test code, the program is not very elegant, hehe.
#include <iconv.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <locale.h>
#define BUFLEN 200
Char Outbuf[buflen];
Char inbuf[buflen]= "CN";
Char inbuf[buflen]= "/x43/x00/x4e/x00/x00/x00";
Char inbuf[buflen]= "/x7a/x7a/x51/x9b/x00/x00";
int main () {
char *pin = inbuf;
char *pout = outbuf;
iconv_t cd;
int inlen = 4, Outlen = Buflen;
int retsize = 0;
cd = Iconv_open ("UTF-8", "ucs-2-internal");
cd = Iconv_open ("ucs-2-internal", "UTF-8");
if ((iconv_t)-1 = = CD) {
printf ("Donot support this convert.") /n ");
return-1;
}
if ((size_t)-1 = = (retsize= iconv (CD, &pin, (size_t *) &inlen, &pout, (size_t *) &outlen)) {
if (E2big = = errno)
printf ("E2big errno%d/n", errno);
if (eilseq = = errno)
printf ("Eilseq errno%d/n", errno);
if (einval = = errno)
printf ("Einval errno%d/n", errno);
printf ("Convert WCHAR to multi error/n");
return-1;
}
if (Outlen > 0) {
printf ("/n/n outbuf:");
int i = 0;
for (i = 0; i < i++) {
printf ("%02x", Outbuf[i]);
}
printf ("/n/n inbuf:");
for (i = 0; i < i++) {
printf ("%02x", Inbuf[i]);
}
printf ("/n/n");
}
printf ("Out buf:%s Outlen:%d retsize:%d Inlen:%d/n", pout, Outlen, Retsize, Inlen);
printf ("Pinbuf:%s/n", pIn);
Iconv_close (CD);
return 0;
}