#include <stdio.h>
#include <string.h>
#include
<mbstring.h>
//mime変換のためのテーブル
0123456789012345678901234567890123456789012345678901234567890123
const
char
MimeEncodeTable[70]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
//逆mime変換のためのテーブル
char MimeDecodeTable[0x80];
//逆mime変換のためのテーブル作成(逆mime変換作業前に作っておく必要がある)
void
makeMineDecodeTable(void)
{
int
i;
for (i=0; i<0x40; i++)
MimeDecodeTable[MimeEncodeTable[i]]=i;
for (i=0;
i<0x80; i++) {
printf("
%02x,",MimeDecodeTable[i]);
if (i%0x10==0xf) printf("\n");
}
}
//文字列intext(normal)を文字列otext(mime
encoded)に変換
//BASE64を利用したMIME変換
void PureMimeEncode(char *intext,
char *otext, int len)
{
unsigned char
*p;
unsigned long int x,x1;
unsigned char tmp[8]={0,0,0,0,0,0,0,0};
char
one[4]="A";
int add,len1,i,j;
add=0;
len1=len;
if (len%3!=0)
{
add=
3-(len%3);
len1=len/3*3;
}
p=(unsigned
char *)intext;
*otext=0;
for
(i=0; i<len1; i+=3) {
x=(p[0]<<16)+(p[1]<<8)+p[2];
x1=(x>>18)&0x3f; one[0]=MimeEncodeTable[x1];
strcat(otext,one);
x1=(x>>12)&0x3f; one[0]=MimeEncodeTable[x1];
strcat(otext,one);
x1=(x>>06)&0x3f; one[0]=MimeEncodeTable[x1];
strcat(otext,one);
x1=( x )&0x3f; one[0]=MimeEncodeTable[x1];
strcat(otext,one);
p+=3;
}
if (add)
{
for (j=0 ; i<len;
i++,j++) tmp[j]=*p++;
x=(tmp[0]<<16)+(tmp[1]<<8)+tmp[2];
x1=(x>>18)&0x3f; one[0]=MimeEncodeTable[x1];
strcat(otext,one);
x1=(x>>12)&0x3f; one[0]=MimeEncodeTable[x1];
strcat(otext,one);
x1=(x>>06)&0x3f; one[0]=MimeEncodeTable[x1];
strcat(otext,one);
x1=( x )&0x3f; one[0]=MimeEncodeTable[x1];
strcat(otext,one);
}
//add=0
-> del=0, add=1 -> del=1, add=2 -> del=2
p=otext+strlen(otext)-1;
for (i=0; i<add; i++)
*p--='=';
}
//文字列intext(normal)を文字列otext(mime
encoded)に変換
//BASE64を利用したMIME変換
//header 0: 何もしない 1:mime header
footerをつける
void MimeEncode(char *intext, char *otext, int
header)
{
static char
text[16384];
PureMimeEncode(intext,text,strlen(intext));
if
(header) strcpy(otext,"=?ISO-2022-JP?B?");
else
*otext=0;
strcat(otext,text);
if (header) strcat(otext,"?=");
}
//文字列intext(mime
encoded)を文字列otext(normal)に変換
//otextの有効文字数を返す
int
PureMimeDecode(char *intext, char *otext)
{
char
*p;
char three[4]="ABC";
unsigned long int x;
int
del,op,len,i;
len=strlen(intext);
del=0;
if
(len) {
while
(intext[len-1-del]=='=') del++;
}
//printf("del=%d\n",del);
op=0;
p=intext;
while (*p)
{
x=MimeDecodeTable[*p++];
//123456
x<<=6;
//123456000000
if (!*p)
break;
x|=MimeDecodeTable[*p++];
//123456123456
x<<=6;
//123456123456000000
if
(!*p) break;
x|=MimeDecodeTable[*p++];
//123456123456123456
x<<=6;
//123456123456123456000000
if (!*p) break;
x|=MimeDecodeTable[*p++];
//123456123456123456123456
three[2]=(char)x;
x>>=8;
three[1]=(char)x;
x>>=8;
three[0]=(char)x;
for (i=0;
i<3; i++,op++) otext[op]=three[i];
}
otext[op]=0;
return
op-del;
}
//文字列intext(mime
encoded)を文字列otext(normal)に変換
//otextの有効文字数を返す
int MimeDecode(char
*intext, char *otext)
{
char
*p,*q;
int num;
q=NULL;
if (strstr(intext,"=?ISO-2022-JP?B?"))
{
q=strstr(intext,"?=");
if
(q) *q=0;
p=intext+strlen("=?ISO-2022-JP?B?");
} else
{
p=intext;
}
num=PureMimeDecode(p,otext);
if (q)
*q='?';
return num;
}
/*非文字はコードで表すputs()相当の関数*/
void putString(char
*text)
{
while (*text)
{
if (0x20<=((unsigned
char)*text) && ((unsigned char)*text)<0x7f)
{
putchar(*text);
} else
{
printf("[%02x]",(unsigned
char)*text);
}
text++;
}
putchar('\n');
}
//文字列sjistext(Shift JIS)を文字列jistext(JIS)に変換
void Sjisstr2Jisstr(char
*sjistext, char *jistext)
{
char
one[4]="A";
char two[4]="AB";
char rtlf[4]="\r\n";
unsigned short int
sjis,jis;
const char shiftin[4]={ 0x1b, 0x24, 0x42,
0 };
const char shiftout[4]={ 0x1b, 0x28, 0x42, 0
};
unsigned char *p=(unsigned char
*)sjistext;
int kanjimode=0;
*jistext=0;
while (*p)
{
if
(kanjimode==0&&(*p&0x80))
{
strcat(jistext,shiftin);
kanjimode=1;
} else if
(kanjimode==1&&(!(*p&0x80)))
{
strcat(jistext,shiftout);
kanjimode=0;
}
if (kanjimode==1)
{
sjis=((*p)<<8);
p++;
if (!(*p))
break;
sjis+=*p;
jis=_mbcjmstojis(sjis);
two[1]=(char)jis;
two[0]=(char)(jis>>8);
strcat(jistext,two);
} else
{
if
(*p=='\n' && *(p-1)!='\r')
{
strcat(jistext,rtlf);
} else
{
one[0]=*p;
strcat(jistext,one);
}
}
p++;
}
if (kanjimode==1)
{
strcat(jistext,shiftout);
}
}
//文字列jistext(JIS)を文字列sjistext(Shift JIS)に変換
void Jisstr2Sjisstr(char
*jistext, char *sjistext)
{
char
one[4]="A";
char two[4]="AB";
unsigned short int sjis,jis;
const char shiftin[4]={
0x1b, 0x24, 0x42, 0 };
const char shiftout[4]={
0x1b, 0x28, 0x42, 0 };
unsigned char *p=(unsigned
char *)jistext;
int
kanjimode=0;
*sjistext=0;
while (*p) {
if
(strstr((char *)p,shiftin)==(char *)p)
{
p+=2;
kanjimode=1;
} else if
(strstr((char *)p,shiftout)==(char *)p)
{
p+=2;
kanjimode=0;
} else if
(kanjimode==1)
{
jis=((*p)<<8);
p++;
if (!(*p))
break;
jis+=((*p)&0xff);
sjis=_mbcjistojms(jis);
two[1]=(char)sjis;
two[0]=(char)(sjis>>8);
strcat(sjistext,two);
} else
if (*p=='\r')
{
/*コピーしない*/
} else
{
one[0]=*p;
strcat(sjistext,one);
}
p++;
}
}
//ユーザIDuserとパスワードpassからauth文字列(mime(user\0user\0pass))を作る
void
makeAuthPlain(char *user, char *pass, char
*auth)
{
int num,i;
char
plain[256];
strcpy(plain,user);
strcat(plain,"\t");
strcat(plain,user);
strcat(plain,"\t");
strcat(plain,pass);
puts(plain);
num=strlen(plain);
for (i=0;i<num;i++) if
(plain[i]=='\t') plain[i]=0;
PureMimeEncode(plain,auth,num);
}
int main()
{
char
sjis1[200]="今日はよい天気です。";
char
sjis2[200]="今日は雨です。\n明日はよい天気でしょう";
char
jis[200];
char
auth1[200]="dXNlcgB1c2VyAHBhc3M=";
char
auth2[200]="VXNlcm5hbWU6";
char
auth3[200]="UGFzc3dvcmQ6";
char
user[200]="user";
char
pass[200]="pass";
char
MimeEncoded[200];
char
obtainedJis[200];
char
obtainedSjis[200];
char
plain[200];
int num,i;
makeMineDecodeTable();//mime逆変換表を作る
putchar('\n');
/*sjis1に関するテスト*/
Sjisstr2Jisstr(sjis1,jis);
MimeEncode(jis,MimeEncoded,1);
MimeDecode(MimeEncoded,obtainedJis);
Jisstr2Sjisstr(obtainedJis,obtainedSjis);
puts(sjis1);
putString(jis);
puts(MimeEncoded);
putString(obtainedJis);
puts(obtainedSjis);
putchar('\n');
/*sjis2に関するテスト*/
Sjisstr2Jisstr(sjis2,jis);
MimeEncode(jis,MimeEncoded,1);
MimeDecode(MimeEncoded,obtainedJis);
Jisstr2Sjisstr(obtainedJis,obtainedSjis);
puts(sjis2);
putString(jis);
puts(MimeEncoded);
putString(obtainedJis);
puts(obtainedSjis);
putchar('\n');
/*sjis1に関するテスト*/
Sjisstr2Jisstr(sjis1,jis);
MimeEncode(jis,MimeEncoded,0);
MimeDecode(MimeEncoded,obtainedJis);
Jisstr2Sjisstr(obtainedJis,obtainedSjis);
puts(sjis1);
putString(jis);
puts(MimeEncoded);
putString(obtainedJis);
puts(obtainedSjis);
putchar('\n');
/*sjis2に関するテスト*/
Sjisstr2Jisstr(sjis2,jis);
MimeEncode(jis,MimeEncoded,0);
MimeDecode(MimeEncoded,obtainedJis);
Jisstr2Sjisstr(obtainedJis,obtainedSjis);
puts(sjis2);
putString(jis);
puts(MimeEncoded);
putString(obtainedJis);
puts(obtainedSjis);
putchar('\n');
/*auth1に関するテスト*/
puts(auth1);
num=PureMimeDecode(auth1,plain);
puts(plain);
for (i=0; i<num; i++)
{
if (plain[i])
putchar(plain[i]);
else
putchar('.');
}
putchar('\n');
for (i=0; i<num; i++) printf("%02x
",(unsigned char )plain[i]);
putchar('\n');
putchar('\n');
/*auth2に関するテスト*/
puts(auth2);
num=PureMimeDecode(auth2,plain);
puts(plain);
for (i=0; i<num; i++)
putchar(plain[i]);
putchar('\n');
for (i=0; i<num; i++) printf("%02x
",(unsigned char )plain[i]);
putchar('\n');
putchar('\n');
/*auth3に関するテスト*/
puts(auth3);
num=PureMimeDecode(auth3,plain);
puts(plain);
for (i=0; i<num; i++)
putchar(plain[i]);
putchar('\n');
for (i=0; i<num; i++) printf("%02x
",(unsigned char )plain[i]);
putchar('\n');
putchar('\n');
/*userに関するテスト*/
puts(user);
PureMimeEncode(user,MimeEncoded,strlen(user));
puts(MimeEncoded);
putchar('\n');
/*passに関するテスト*/
puts(pass);
PureMimeEncode(pass,MimeEncoded,strlen(pass));
puts(MimeEncoded);
putchar('\n');
/*user user passでplainauth文字列を作るテスト*/
puts(user);
puts(pass);
makeAuthPlain(user, pass, MimeEncoded);
puts(MimeEncoded);
return 0;
}