2011/05/11

c++でcgi ー URLデコード

HTMLのフォームからGETやPOSTで送られてくる文字列は、URLエンコードされてくるので、デコードして元の形に戻すプログラムです。

こちらのページを参考にしました。)

引数で渡された文字列から、以下の変換を行った文字列を返します。

  • [+] → [ ](半角スペース)
  • [%○○](○は16進数) → 2桁の16進数の文字
  • [%0A][%0D%0A](改行コード) →<br>



#include <iostream>
#include <string>
#include <ctype.h> // toupper

//! %XXのXXをchar型にして返します。
char hexToChar( char first, char second )
{
 int digit;
  
 digit = ( first >= 'A' ? (( first & 0xDF ) - 'A') + 10 : ( first - '0' ));
 digit *= 16;
 digit += ( second >= 'A' ? (( second & 0xDF ) - 'A' ) + 10 : ( second - '0' ));
 return static_cast< char >( digit );
}

//! 改行コードか判定します。
bool isLF( const std::string            & str, 
     const std::string::size_type & length,
     std::string::size_type       & index,
     char                         * tmpStr )
{
 if ( tmpStr[ 0 ] != '0' )
  return false;

 tmpStr[ 1 ] = toupper( tmpStr[ 1 ] );
 if ( tmpStr[ 1 ] == 'A' )
 {
  // [0A]は改行コード
  return true;
 }
 
 if ( tmpStr[ 1 ] == 'D' )
 {
  // [0D]も改行コード
  if (( index + 3 ) < length && str[ index + 1 ] == '%' )
  {
   // [0D]の後に[%0A]がある時は、[%0A]の後までインデックスを進めます。
   tmpStr[ 0 ] = str[ index + 2 ];
   tmpStr[ 1 ] = str[ index + 3 ];
   
   if ( tmpStr[ 0 ] == '0' && 
     ( tmpStr[ 1 ] == 'A' || tmpStr[ 1 ] == 'a' ))
   {
    index += 3;
   }
  }
  return true;
 }

 return false;
}

/**
   URLデコードをした文字列を返します。 
   改行コード(0x0A, 0x0D)は'\n'にします。
**/
std::string UrlDecorde( const std::string & str )
{
 std::string retStr;
 char tmpStr[ 2 ];
 std::string::size_type length = str.size(); 

 for ( std::string::size_type i = 0 ; i < length ; i++ )
 {
  if ( str[ i ] == '+' )
  {
   // [+]は半角スペース
   retStr += ' ';
  }
  else if ( str[ i ] == '%' && ( i + 2 ) < length )
  {
   tmpStr[ 0 ] = str[ i + 1 ];
   tmpStr[ 1 ] = str[ i + 2 ];

   if ( std::isxdigit( tmpStr[ 0 ] ) && std::isxdigit( tmpStr[ 1 ] ))
   {
    i += 2;

    // 改行コードのチェック
    if ( isLF( str, length, i, tmpStr ))
    {
     retStr += "<br>";
    }
    else
    {
     retStr += hexToChar( tmpStr[ 0 ], tmpStr[ 1 ] );
    }
   }
   else
   {
    // no digit
    retStr += '%';
   }
  }
  else
  {
   retStr += str[ i ];
  }
 }
 return retStr;
}

int main()
{
 std::cout << UrlDecorde( "%E3%81%82%E3%81%84%E3%81%86%E3%81%88%E3%81%8A%0D%0A%E3%81%8B%E3%81%8D%E3%81%8F%E3%81%91%E3%81%93" ) << std::endl;

 return 0;
}

0 コメント:

コメントを投稿

 
Design by Free WordPress Themes | Bloggerized by Lasantha - Premium Blogger Themes | Blogger Templates