2011/05/11

c++でcgi ー URLデコード

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

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

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

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



  1. #include <iostream>  
  2. #include <string>  
  3. #include <ctype.h> // toupper  
  4.   
  5. //! %XXのXXをchar型にして返します。  
  6. char hexToChar( char first, char second )  
  7. {  
  8.  int digit;  
  9.     
  10.  digit = ( first >= 'A' ? (( first & 0xDF ) - 'A') + 10 : ( first - '0' ));  
  11.  digit *= 16;  
  12.  digit += ( second >= 'A' ? (( second & 0xDF ) - 'A' ) + 10 : ( second - '0' ));  
  13.  return static_castchar >( digit );  
  14. }  
  15.   
  16. //! 改行コードか判定します。  
  17. bool isLF( const std::string            & str,   
  18.      const std::string::size_type & length,  
  19.      std::string::size_type       & index,  
  20.      char                         * tmpStr )  
  21. {  
  22.  if ( tmpStr[ 0 ] != '0' )  
  23.   return false;  
  24.   
  25.  tmpStr[ 1 ] = toupper( tmpStr[ 1 ] );  
  26.  if ( tmpStr[ 1 ] == 'A' )  
  27.  {  
  28.   // [0A]は改行コード  
  29.   return true;  
  30.  }  
  31.    
  32.  if ( tmpStr[ 1 ] == 'D' )  
  33.  {  
  34.   // [0D]も改行コード  
  35.   if (( index + 3 ) < length && str[ index + 1 ] == '%' )  
  36.   {  
  37.    // [0D]の後に[%0A]がある時は、[%0A]の後までインデックスを進めます。  
  38.    tmpStr[ 0 ] = str[ index + 2 ];  
  39.    tmpStr[ 1 ] = str[ index + 3 ];  
  40.      
  41.    if ( tmpStr[ 0 ] == '0' &&   
  42.      ( tmpStr[ 1 ] == 'A' || tmpStr[ 1 ] == 'a' ))  
  43.    {  
  44.     index += 3;  
  45.    }  
  46.   }  
  47.   return true;  
  48.  }  
  49.   
  50.  return false;  
  51. }  
  52.   
  53. /** 
  54.    URLデコードをした文字列を返します。  
  55.    改行コード(0x0A, 0x0D)は'\n'にします。 
  56. **/  
  57. std::string UrlDecorde( const std::string & str )  
  58. {  
  59.  std::string retStr;  
  60.  char tmpStr[ 2 ];  
  61.  std::string::size_type length = str.size();   
  62.   
  63.  for ( std::string::size_type i = 0 ; i < length ; i++ )  
  64.  {  
  65.   if ( str[ i ] == '+' )  
  66.   {  
  67.    // [+]は半角スペース  
  68.    retStr += ' ';  
  69.   }  
  70.   else if ( str[ i ] == '%' && ( i + 2 ) < length )  
  71.   {  
  72.    tmpStr[ 0 ] = str[ i + 1 ];  
  73.    tmpStr[ 1 ] = str[ i + 2 ];  
  74.   
  75.    if ( std::isxdigit( tmpStr[ 0 ] ) && std::isxdigit( tmpStr[ 1 ] ))  
  76.    {  
  77.     i += 2;  
  78.   
  79.     // 改行コードのチェック  
  80.     if ( isLF( str, length, i, tmpStr ))  
  81.     {  
  82.      retStr += "<br>";  
  83.     }  
  84.     else  
  85.     {  
  86.      retStr += hexToChar( tmpStr[ 0 ], tmpStr[ 1 ] );  
  87.     }  
  88.    }  
  89.    else  
  90.    {  
  91.     // no digit  
  92.     retStr += '%';  
  93.    }  
  94.   }  
  95.   else  
  96.   {  
  97.    retStr += str[ i ];  
  98.   }  
  99.  }  
  100.  return retStr;  
  101. }  
  102.   
  103. int main()  
  104. {  
  105.  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;  
  106.   
  107.  return 0;  
  108. }  

0 コメント:

コメントを投稿

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