プログラムテクニックメモ(2001/07/12)
URLエンコードされたデータを、元の正しい文字列に復元(戻す)ことをいいます。ただし復元される文字列の中に漢字コードが存在した場合は、送り先元の漢字コード体系で復元されます。たとえば送り先元の漢字コード体系が、EUCであるならば EUCで、S-JIS ならば S-JIS で復元されます。
指定されたデータ中に % があった場合、その後に続く2バイトを内部コードに変換します、それ以外は、そのままの文字とします。例えば %A2%A3A と指定されていた場合は、%A2 → 0xA2, %A3 → 0xA3, A → 'A' として変換します。
変換例: abZ+%28%29%27%7E%21%A4%A2*-._ → ()'~!あ*-._
下記ソースは、gcc でコンパイルしましたが、特殊な命令は使用していないので、大抵の Cコンパイラでコンパイルできるでしょう。(ソース)
下記関数の仕様としては、エラー時には(-1)を返し、正常時には変換した文字列長を返します。また、第2引数に指定された領域には、URLデコードした文字列ポインタが格納(使用終了後は、必ずfreeすること)されます。
#include <stdio.h>
#include <string.h>
#include <malloc.h>
const char codetbl[] = "0123456789ABCDEF";
int URLdecode(char *in, char **out)
{
int cnt = 0;
int len;
char *str = in; /* in data pointer */
/* in param nodata */
if (!in || (len = strlen(in)) == 0)
return -1;
/* data output area malloc */
if ((*out = (char *)malloc(sizeof(char) * len)) == NULL)
return(-1);
memset( *out, 0, len );
/**/
while( *str ) {
if (*str != '%') {
*(*out + cnt++) = *str;
} else {
/* null pointer chk */
if ( *(str + 1) == 0 || *(str + 2) == 0) {
break;
}
/* decode */
*(*out + cnt++) = 16 * (strchr(codetbl, *(str + 1)) - codetbl) \
+ (strchr(codetbl, *(str + 2)) - codetbl);
str = str + 2;
}
str++;
}
return(strlen(*out));
}