C#で、Quoted-Printable(メールの件名(Subject))のデコード

メールの件名(Subject)が、Quoted-Printableになっている場合、「=XX=XX=XX」のように「=」と2桁の16進数文字コードの組み合わせになっています。 「=」の後の2桁の16進数文字コードをbyteに変換後、System.Text.Encodingを使って日本語に変換できます。

using System;
using System.Text;

private static string DecodeQuotedPrintable( string input, string charset )
{
    List<byte> data = new List<byte>();
    string code;
    int pos0 = 0;
    int pos1 = 0;

    while( pos0 < input.Length )
    {
        pos1 = input.IndexOf( "=", pos0 );

        if( pos1 < 0 || pos1 + 3 > input.Length )
        {
            data.AddRange( Encoding.ASCII.GetBytes( input.Substring( pos0 ) ) );
            break;
        }

        if( pos1 != pos0 )
        {
            data.AddRange( Encoding.ASCII.GetBytes( input.Substring( pos0, pos1 - pos0 ) ) );
        }

        code = input.Substring(pos1 + 1, 2);

        if( Uri.IsHexDigit( code[0] ) && Uri.IsHexDigit( code[1] ) )
        {
            data.Add( (byte)Convert.ToInt32( code, 16 ) );
            pos0 = pos1 + 3;
        }
        else
        {
            data.Add( (byte)input[pos1] );
            pos0 = pos1 + 1;
        }
    }

    return Encoding.GetEncoding( charset ).GetString( data.ToArray() );
}

string utf8 = DecodeQuotedPrintable( "=E6=9D=B1=E4=BA=AC", "utf-8" );
Console.WriteLine( "utf-8: {0}", utf8 );

string shiftjis = DecodeQuotedPrintable( "=93=8C=8B=9E", "shift-jis" );
Console.WriteLine( "shift-jis: {0}", shiftjis );

string eucjp = DecodeQuotedPrintable( "=C5=EC=B5=FE", "euc-jp" );
Console.WriteLine( "euc-jp: {0}", eucjp );

結果

utf-8: 東京
shift-jis: 東京
euc-jp: 東京