用vc做了一个邮件解读的程序,但是在编码问题上出现了乱码,具体问题是:如在解析邮件头部内容时,如主题“Subject: =?utf-8?B?5qyi6L+O5L2/55SoIOKAnOS5kOmaj+S6q+KAnQ==?=”,采用base64编码进行解码,出现乱码。
将这个主题中的“5qyi6L+O5L2/55SoIOKAnOS5kOmaj+S6q+KAnQ”在在线解码中用base64解码能够正确显示,但在程序中用base64解码就乱了,主要原因应该是前面有一个“utf-8”,表示是utf-8字符集,而不是“gb2312”。
请教高手,这种问题如何解决?谢谢!

解决方案 »

  1.   

    UTF-8 转 Unicode static wstring UTF8ToUnicode2( const string& str )
    {
    int  len = 0;
    len = (int)str.length();
    int  unicodeLen = ::MultiByteToWideChar( CP_UTF8,
    0,
    str.c_str(),
    -1,
    NULL,
    0 );  
    wchar_t *  pUnicode;  
    pUnicode = new  wchar_t[unicodeLen+1];  
    memset(pUnicode,0,(unicodeLen+1)*sizeof(wchar_t));  
    ::MultiByteToWideChar( CP_UTF8,
    0,
    str.c_str(),
    -1,
    (LPWSTR)pUnicode,
    unicodeLen );  
    wstring  rt;  
    rt = ( wchar_t* )pUnicode;
    delete  pUnicode;  return  rt;  
    }
      

  2.   

    这个UTF8ToUnicode2()函数我用过,实现utf8到unicode的转换,然后再转换为gb2312就可以把utf8转换为中文,但这个不能完成我上面的解码转换,因为主题“Subject: =?utf-8?B?5qyi6L+O5L2/55SoIOKAnOS5kOmaj+S6q+KAnQ==?=”中的“5qyi6L+O5L2/55SoIOKAnOS5kOmaj+S6q+KAnQ”实际上是base64编码的。
      

  3.   


    “Subject: =?utf-8?B?5qyi6L+O5L2/55SoIOKAnOS5kOmaj+S6q+KAnQ==?=”
    你的subject制定为Utf-8字符集, 加密方式为base64, 乱码可能是你传入的字符集不是utf-8的, 客户端解释时按默认解释就错了。 你试着把utf-8改为gb2312看下效果, 如果正确, 你要把你传入的字符串用MultiCharToWideChar转为uft-8.
      

  4.   

    我是采用vc自己编程来解析,不是采用foxmail等邮件工具,我的程序能够对=?gb2132?B?这种类型的base64编码正确解码,但对于=?utf-8?B?这种就乱码了,把utf-8改为gb2312还是乱码,我也用过网上的一些对于utf-8的编码解码进行解码,如上面的UTF8ToUnicode()函数,实现utf8到unicode的转换,然后再转换为gb2312,都不行,因为这种主题中的具体内容实际上是base64编码
      

  5.   

    你理解错了, 字符集是字符集, 加密是加密。还是乱码只能说明你程序的email协议没有写对。 utf-8,指定后, 你传入的字符串必须是这个字符集。base64这个要看你指定的范围到底包含不subject。 这个其实很简单的。 你 一步一步分析, 首先确定你的字符集一致, 然后确定加密方式一致。以前对email的研究blog
    http://blog.csdn.net/muzizongheng/archive/2009/10/15/4675651.aspx
      

  6.   

    你先确定你的工程字符集, 然后把工程的字符串转为email协议要的字符集, 这样保持字符集一致。
      

  7.   

    确实对字符集这个问题没有搞清楚。
    下面是需要解析的邮件头部部分信息(邮件被导出被保存在一个文本文件中),其中显示字符集是utf-8,编码是base64:
    Message-Id: <[email protected]>
    MIME-Version: 1.0
    From: [email protected]
    Date: 19 Aug 2010 12:51:51 +0100
    Subject: =?utf-8?B?5qyi6L+O5L2/55SoIOKAnOS5kOmaj+S6q+KAnQ==?=
    Content-Type: text/html; charset=utf-8
    Content-Transfer-Encoding: base64
    X-Nokia-AV: Clean
    我在程序中,需要读取被保存在文本文件中的邮件文件,分别提取邮件的头部信息,对被编码过的头部信息要解码,如对这个subject中的编码要解码掉。我有一个base64的解码函数base64_decode(),完成对base64编码的解码。在提取这个subject后,分析其被编码,并将“=?utf-8?B?”部分去掉,并去掉subject尾部的“=?=”,再调用base64_decode()函数对“5qyi6L+O5L2/55SoIOKAnOS5kOmaj+S6q+KAnQ=”部分解码,程序如下:
    startPos = Subject.Find("?B?");
    if (startPos < 0)
    {
    startPos = Subject.Find("?b?");
    } if (startPos > 0)
    {
    while (startPos > 0)
    {
    //编码结束的位置
    endPos = Subject.Find("?=",startPos);
    //提取编码过的字符串
    Subject.Delete(0,startPos + 3);
    temp_Name = Subject.Left(endPos - startPos - 3);
    temp_Name.Replace("\r\n","");
    int Name_len = temp_Name.GetLength();
    temp_Name.Format("%s",base64.base64_decode(temp_Name.GetBuffer(Name_len),Name_len));

    AfxMessageBox("temp name:"+temp_Name); Name = Name+temp_Name; startPos = Subject.Find("?B?");
    if (startPos < 0)
    {
    startPos = Subject.Find("?b?");
    }
    }
    }
    最终的结果AfxMessageBox显示出的信息是乱码,如果charset为gb2312的话,解码是没有问题的,但这里面要处理的是utf-8,所以乱码了,这个字符集需要怎么处理,还没搞清楚。请指教,谢谢。
      

  8.   

    base64.base64_decode(temp_Name.GetBuffer(Name_len),Name_len)这个语句调用要改下。猜测你的工程为多字节字符, 即非unicode, 因此gb2312是对的。你要做如下处理:
    你把temp_Name转换为多字节, 
    char szTemp1[8096] = {NULL};
    WideCharToMultiByte(CP_ACP, 0, temp_Name.GetBuffer(0), -1, szTemp1, 8095, NULL, NULL );
    temp_Name = CString(szTemp1);然后再调用AfxMessageBox(base64.base64_decode(temp_Name.GetBuffer(Name_len),Name_len)); 看看。
      

  9.   

    sorry, char szTemp1[8096] = {NULL};
    WideCharToMultiByte(CP_ACP, 0, temp_Name.GetBuffer(0), -1, szTemp1, 8095, NULL, NULL );
    temp_Name = CString(szTemp1);上面处理后Name_len要重新获取。
      

  10.   

    这个知道,谢谢,但temp_Name.GetBuffer(0)这个在编译时出错,“error C2664: 'WideCharToMultiByte' : cannot convert parameter 3 from 'char *' to 'const unsigned short *'
            Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast”,类型转换的问题,用强制转换好像也不行
      

  11.   

    kao, 那你的工程就是unicode的, 你没看你的工程属性??????????那你半天转什么啊?注意你的base64解密不用改, 这些都是转换字符集,转换正确后传给base 你确定下, 是不是unicode, 如果是
    USES_CONVERSION; 
    LPSTR strFrom = W2A(temp_Name.GetBuffer(0)); 
    char szTemp[8096] = {NULL}; 
    WideCharToMultiByte(CP_UTF8, 0, temp_Name.GetBuffer(0),  -1, szTemp, 8095, NULL, NULL ); 本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/muzizongheng/archive/2009/10/15/4675651.aspx
      

  12.   

    唉,工程不是unicode的,没有加这个定义,看工程属性中也没有unicode定义的,
    鼠标点击WideCharToMultiByte(CP_UTF8, 0, temp_Name.GetBuffer(0), -1, szTemp, 8095, NULL, NULL )的temp_Name.GetBuffer(0)上面,显示是unsigned short *类型,但就是编译通不过
      

  13.   

    不会啊, 不是unicode, CString怎么会事unsigned short*。 你看看是不是有_UNICODE 或者UNICODE的定义在工程属性了。