使用TIdPOP3收邮件,如果是中文需要转码中文邮件标题为:'=?gb2312?B?xPrU2jUxam9iLmNvbcnPtqnUxLXEuaTX99PKvP4=?='我使用IdDecoderMIME控件IdDecoderMIME1.DecodeString('=?gb2312?B?xPrU2jUxam9iLmNvbcnPtqnUxLXEuaTX99PKvP4=?=');上面这句话报错:Uneven size in DecodeToStream请问是什么问题?我该如何解码呢???

解决方案 »

  1.   

    使用下面的函数进行解码:
    function Tfemail.Base64ToString(const Value: string): string;
    var
      x, y, n, l: Integer;
      d: array[0..3] of Byte;
      Table : string;
    begin
      Table :=
        #$40 +#$40 +#$40 +#$40 +#$40 +#$40 +#$40 +#$40 +#$40 +#$40 +#$3E +#$40
        +#$40 +#$40 +#$3F +#$34 +#$35 +#$36 +#$37 +#$38 +#$39 +#$3A +#$3B +#$3C
        +#$3D +#$40 +#$40 +#$40 +#$40 +#$40 +#$40 +#$40 +#$00 +#$01 +#$02 +#$03
        +#$04 +#$05 +#$06 +#$07 +#$08 +#$09 +#$0A +#$0B +#$0C +#$0D +#$0E +#$0F
        +#$10 +#$11 +#$12 +#$13 +#$14 +#$15 +#$16 +#$17 +#$18 +#$19 +#$40 +#$40
        +#$40 +#$40 +#$40 +#$40 +#$1A +#$1B +#$1C +#$1D +#$1E +#$1F +#$20 +#$21
        +#$22 +#$23 +#$24 +#$25 +#$26 +#$27 +#$28 +#$29 +#$2A +#$2B +#$2C +#$2D
        +#$2E +#$2F +#$30 +#$31 +#$32 +#$33 +#$40 +#$40 +#$40 +#$40 +#$40 +#$40;  SetLength(Result, Length(Value));
      x := 1;
      l := 1;
      while x < Length(Value) do
      begin
        for n := 0 to 3 do
        begin
          if x > Length(Value) then
            d[n] := 64
          else
          begin
            y := Ord(Value[x]);
            if (y < 33) or (y > 127) then
              d[n] := 64
            else
              d[n] := Ord(Table[y - 32]);
          end;
          Inc(x);
        end;
        Result[l] := Char((D[0] and $3F) shl 2 + (D[1] and $30) shr 4);
        Inc(l);
        if d[2] <> 64 then
        begin
          Result[l] := Char((D[1] and $0F) shl 4 + (D[2] and $3C) shr 2);
          Inc(l);
          if d[3] <> 64 then
          begin
            Result[l] := Char((D[2] and $03) shl 6 + (D[3] and $3F));
            Inc(l);
          end;
        end;
      end;
      Dec(l);
      SetLength(Result, l);
    end;
      

  2.   

    其实邮件的标题编码无非是同样的编码,只不过,还需要经过一下处理才能进行解码的。
    Function QuotedPrintableEncode(mSource: String): String;
    Var
      I, J: Integer;
    Begin
      Result := '';
      J := 0;
      For I := 1 To Length(mSource) Do Begin
          If mSource[I] In [#32..#127, #13, #10] - ['='] Then Begin
              Result := Result + mSource[I];
              Inc(J);
            End Else Begin
              Result := Result + '=' + IntToHex(Ord(mSource[I]), 2);
              Inc(J, 3);
            End;
          If mSource[I] In [#13, #10] Then J := 0;
          If J >= 70 Then Begin
              Result := Result + #13#10;
              J := 0;
            End;
        End;
    End; { QuotedPrintableEncode }Function QuotedPrintableDecode(mCode: String): String;
    Var
      I, J, L: Integer;
    Begin
      Result := '';
      J := 0;
      mCode := AdjustLineBreaks(mCode);
      L := Length(mCode);
      I := 1;
      While I <= L Do Begin
          If mCode[I] = '=' Then Begin
              Result := Result + Chr(StrToIntDef('$' + Copy(mCode, I + 1, 2), 0));
              Inc(J, 3);
              Inc(I, 3);
            End Else If mCode[I] In [#13, #10] Then Begin
              If J < 70 Then Result := Result + mCode[I];
              If mCode[I] = #10 Then J := 0;
              Inc(I);
            End Else Begin
              Result := Result + mCode[I];
              Inc(J);
              Inc(I);
            End;
        End;
    End; { QuotedPrintableDecode }
    Function Base64Encode(mSource: String; mAddLine: Boolean = True): String;
    Var
      I, J: Integer;
      S: String;
    Begin
      Result := '';
      J := 0;
      For I := 0 To Length(mSource) Div 3 - 1 Do Begin
          S := Copy(mSource, I * 3 + 1, 3);
          Result := Result + cBase64[Ord(S[1]) Shr 2 + 1];
          Result := Result + cBase64[((Ord(S[1]) And $03) Shl 4) + (Ord(S[2]) Shr 4) + 1];
          Result := Result + cBase64[((Ord(S[2]) And $0F) Shl 2) + (Ord(S[3]) Shr 6) + 1];
          Result := Result + cBase64[Ord(S[3]) And $3F + 1];
          If mAddLine Then Begin
              Inc(J, 4);
              If J >= 76 Then Begin
                  Result := Result + #13#10;
                  J := 0;
                End;
            End;
        End;
      I := Length(mSource) Div 3;
      S := Copy(mSource, I * 3 + 1, 3);
      Case Length(S) Of
        1: Begin
            Result := Result + cBase64[Ord(S[1]) Shr 2 + 1];
            Result := Result + cBase64[(Ord(S[1]) And $03) Shl 4 + 1];
            Result := Result + cBase64[65];
            Result := Result + cBase64[65];
          End;
        2: Begin
            Result := Result + cBase64[Ord(S[1]) Shr 2 + 1];
            Result := Result + cBase64[((Ord(S[1]) And $03) Shl 4) + (Ord(S[2]) Shr 4) + 1];
            Result := Result + cBase64[(Ord(S[2]) And $0F) Shl 2 + 1];
            Result := Result + cBase64[65];
          End;
      End;
    End; { Base64Encode }Function Base64Decode(mCode: String): String;
    Var
      I, L: Integer;
      S: String;
    Begin
      Result := '';
      L := Length(mCode);
      I := 1;
      While I <= L Do Begin
          If Pos(mCode[I], cBase64) > 0 Then Begin
              S := Copy(mCode, I, 4);
              If (Length(S) = 4) Then Begin
                  Result := Result + Chr((Pos(S[1], cBase64) - 1) Shl 2 +
                    (Pos(S[2], cBase64) - 1) Shr 4);
                  If S[3] <> cBase64[65] Then Begin
                      Result := Result + Chr(((Pos(S[2], cBase64) - 1) And $0F) Shl 4 +
                        (Pos(S[3], cBase64) - 1) Shr 2);
                      If S[4] <> cBase64[65] Then
                        Result := Result + Chr(((Pos(S[3], cBase64) - 1) And $03) Shl 6 +
                          (Pos(S[4], cBase64) - 1));
                    End;
                End;
              Inc(I, 4);
            End Else Inc(I);
        End;
    End; { Base64Decode }Function GetTitle(Const Value: String): String;
    Var
      iPos: integer;
    Begin
      Result := Value;
      If Copy(Value, 1, 2) <> '=?' Then
        Begin
          Result := Value;
          exit;
        End;
      //'?B?'前面的都要去掉
      iPos := Pos('?B?', Value);
      If iPos = 0 Then
        Begin
          iPos := Pos('?Q?', Value);
          If iPos = 0 Then
            Begin
              Result := Value;
              exit;
            End;
          Inc(iPos, 3);
      //最后的'?='也要去掉
          Result := Copy(Value, iPos, Length(Value) - iPos - 1);
          Result := QuotedPrintableDecode(Result);
        End
      Else
        Begin
          Inc(iPos, 3);
      //最后的'?='也要去掉
          Result := Copy(Value, iPos, Length(Value) - iPos - 1);
          Result := Base64Decode(Result);
        End;End;示例:
    ShowMessage(GetTitle('=?gb2312?B?xPrU2jUxam9iLmNvbcnPtqnUxLXEuaTX99PKvP4=?='));
      

  3.   

    顺便问一下,indy9的编码控件怎么不好用阿???
      

  4.   

    这个问题相信多数做邮件程序的人都碰到了,希望楼主加入FAQ,以供大家查看,呵呵
      

  5.   

    cBase64[]是什么?编码表吗??
      

  6.   

    Const
      cBase64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
      

  7.   

    我把编码写到一个unit里面了,下面是详细代码:unit Base64Code;interfaceuses
      Windows, SysUtils, StrUtils;  Function GetMailTitle(Const Value: String): String;
      Function GetMailSender(Const value: String):String;  const cBase64:string='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
    implementationFunction QuotedPrintableEncode(mSource: String): String;
    Var
      I, J: Integer;
    Begin
      Result := '';
      J := 0;
      For I := 1 To Length(mSource) Do Begin
          If mSource[I] In [#32..#127, #13, #10] - ['='] Then Begin
              Result := Result + mSource[I];
              Inc(J);
            End Else Begin
              Result := Result + '=' + IntToHex(Ord(mSource[I]), 2);
              Inc(J, 3);
            End;
          If mSource[I] In [#13, #10] Then J := 0;
          If J >= 70 Then Begin
              Result := Result + #13#10;
              J := 0;
            End;
        End;
    End; { QuotedPrintableEncode }Function QuotedPrintableDecode(mCode: String): String;
    Var
      I, J, L: Integer;
    Begin
      Result := '';
      J := 0;
      mCode := AdjustLineBreaks(mCode);
      L := Length(mCode);
      I := 1;
      While I <= L Do Begin
          If mCode[I] = '=' Then Begin
              Result := Result + Chr(StrToIntDef('$' + Copy(mCode, I + 1, 2), 0));
              Inc(J, 3);
              Inc(I, 3);
            End Else If mCode[I] In [#13, #10] Then Begin
              If J < 70 Then Result := Result + mCode[I];
              If mCode[I] = #10 Then J := 0;
              Inc(I);
            End Else Begin
              Result := Result + mCode[I];
              Inc(J);
              Inc(I);
            End;
        End;
    End; { QuotedPrintableDecode }Function Base64Encode(mSource: String; mAddLine: Boolean = True): String;
    Var
      I, J: Integer;
      S: String;
    Begin
      Result := '';
      J := 0;
      For I := 0 To Length(mSource) Div 3 - 1 Do Begin
          S := Copy(mSource, I * 3 + 1, 3);
          Result := Result + cBase64[Ord(S[1]) Shr 2 + 1];
          Result := Result + cBase64[((Ord(S[1]) And $03) Shl 4) + (Ord(S[2]) Shr 4) + 1];
          Result := Result + cBase64[((Ord(S[2]) And $0F) Shl 2) + (Ord(S[3]) Shr 6) + 1];
          Result := Result + cBase64[Ord(S[3]) And $3F + 1];
          If mAddLine Then Begin
              Inc(J, 4);
              If J >= 76 Then Begin
                  Result := Result + #13#10;
                  J := 0;
                End;
            End;
        End;
      I := Length(mSource) Div 3;
      S := Copy(mSource, I * 3 + 1, 3);
      Case Length(S) Of
        1: Begin
            Result := Result + cBase64[Ord(S[1]) Shr 2 + 1];
            Result := Result + cBase64[(Ord(S[1]) And $03) Shl 4 + 1];
            Result := Result + cBase64[65];
            Result := Result + cBase64[65];
          End;
        2: Begin
            Result := Result + cBase64[Ord(S[1]) Shr 2 + 1];
            Result := Result + cBase64[((Ord(S[1]) And $03) Shl 4) + (Ord(S[2]) Shr 4) + 1];
            Result := Result + cBase64[(Ord(S[2]) And $0F) Shl 2 + 1];
            Result := Result + cBase64[65];
          End;
      End;
    End; { Base64Encode }Function Base64Decode(mCode: String): String;
    Var
      I, L: Integer;
      S: String;
    Begin
      Result := '';
      L := Length(mCode);
      I := 1;
      While I <= L Do Begin
          If Pos(mCode[I], cBase64) > 0 Then Begin
              S := Copy(mCode, I, 4);
              If (Length(S) = 4) Then Begin
                  Result := Result + Chr((Pos(S[1], cBase64) - 1) Shl 2 +
                    (Pos(S[2], cBase64) - 1) Shr 4);
                  If S[3] <> cBase64[65] Then Begin
                      Result := Result + Chr(((Pos(S[2], cBase64) - 1) And $0F) Shl 4 +
                        (Pos(S[3], cBase64) - 1) Shr 2);
                      If S[4] <> cBase64[65] Then
                        Result := Result + Chr(((Pos(S[3], cBase64) - 1) And $03) Shl 6 +
                          (Pos(S[4], cBase64) - 1));
                    End;
                End;
              Inc(I, 4);
            End Else Inc(I);
        End;
    End; { Base64Decode }Function GetMailTitle(Const Value: String): String;
    Var
      iPos: integer;
    Begin
      Result := Value;
      If Copy(Value, 1, 2) <> '=?' Then
        Begin
          Result := Value;
          exit;
        End;
      //'?B?'前面的都要去掉
      iPos := Pos('?B?', Value);
      If iPos = 0 Then
        Begin
          iPos := Pos('?Q?', Value);
          If iPos = 0 Then
            Begin
              Result := Value;
              exit;
            End;
          Inc(iPos, 3);
      //最后的'?='也要去掉
          Result := Copy(Value, iPos, Length(Value) - iPos - 1);
          Result := QuotedPrintableDecode(Result);
        End
      Else
        Begin
          Inc(iPos, 3);
      //最后的'?='也要去掉
          Result := Copy(Value, iPos, Length(Value) - iPos - 1);
          Result := Base64Decode(Result);
        End;End;
    //由于发件人是中文+'<[email protected]>',组成的,所以多加了这个函数!
    Function GetMailSender(Const value: String):String;
    var
      iPos:integer;
      preStr:String;
      bkStr:String;
    begin
      Result:= value;
      If Copy(Value, 1, 2) <> '=?' Then
        Begin
          Result := Value;
          exit;
        End;
      iPos := Pos('?= <', Value);
      if iPos=0 then
        begin
          Result := Value;
          exit;
        end
      else
        begin
          preStr:=Copy(Value,1,iPos+1);
          bkStr:=Copy(Value,iPos+2,length(Value)-iPos+2);
          Result:= GetMailTitle(preStr)+ bkStr;
        end;
    end;end.
      

  8.   

    最后特别要谢谢fei19790920(饭桶的马甲(抵制日货)) ( )和ts707() ( ) ,感激不尽!对csdn又有点信心了~
      

  9.   

    顺便问一下,怎么把帖子放到faq里面去阿???