プログラムリスト MIME変換,MIME逆変換 SJIS→JIS JIS→SJIS

プログラム 各種変換関数のテスト

#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;
}

実行結果

 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 3e, 00, 00, 00, 3f,
 34, 35, 36, 37, 38, 39, 3a, 3b, 3c, 3d, 00, 00, 00, 00, 00, 00,
 00, 00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 0a, 0b, 0c, 0d, 0e,
 0f, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 00, 00, 00, 00, 00,
 00, 1a, 1b, 1c, 1d, 1e, 1f, 20, 21, 22, 23, 24, 25, 26, 27, 28,
 29, 2a, 2b, 2c, 2d, 2e, 2f, 30, 31, 32, 33, 00, 00, 00, 00, 00,

今日はよい天気です。
[1b]$B:#F|$O$h$$E75$$G$9!#[1b](B
今日はよい天気です。
[1b]$B:#F|$O$h$$E75$$G$9!#[1b](B
今日はよい天気です。

今日は雨です。
明日はよい天気でしょう
[1b]$B:#F|$O1+$G$9!#[1b](B[0d][0a][1b]$BL@F|$O$h$$E75$$G$7$g$&[1b](B
今日は雨です。 明日はよい天気でしょう
[1b]$B:#F|$O1+$G$9!#[1b](B[0d][0a][1b]$BL@F|$O$h$$E75$$G$7$g$&[1b](B
今日は雨です。
明日はよい天気でしょう

今日はよい天気です。
[1b]$B:#F|$O$h$$E75$$G$9!#[1b](B
GyRCOiNGfCRPJGgkJEU3NSQkRyQ5ISMbKEI=
[1b]$B:#F|$O$h$$E75$$G$9!#[1b](B
今日はよい天気です。

今日は雨です。
明日はよい天気でしょう
[1b]$B:#F|$O1+$G$9!#[1b](B[0d][0a][1b]$BL@F|$O$h$$E75$$G$7$g$&[1b](B
GyRCOiNGfCRPMSskRyQ5ISMbKEINChskQkxARnwkTyRoJCRFNzUkJEckNyRnJCYbKEI=
[1b]$B:#F|$O1+$G$9!#[1b](B[0d][0a][1b]$BL@F|$O$h$$E75$$G$7$g$&[1b](B
今日は雨です。
明日はよい天気でしょう

dXNlcgB1c2VyAHBhc3M=
user
user.user.pass
75 73 65 72 00 75 73 65 72 00 70 61 73 73

VXNlcm5hbWU6
Username:
Username:
55 73 65 72 6e 61 6d 65 3a

UGFzc3dvcmQ6
Password:
Password:
50 61 73 73 77 6f 72 64 3a

user
dXNlcg==

pass
cGFzcw==

user
pass
user    user    pass
dXNlcgB1c2VyAHBhc3M=