* [9fans] Base64 mime encode/decode program
@ 1998-11-18 9:01 okamoto
0 siblings, 0 replies; only message in thread
From: okamoto @ 1998-11-18 9:01 UTC (permalink / raw)
I tried to make base64 encoding/decoding program
to use with such as rin's header lines. This is a limited
implementation of RFC 1341/1342. However, I believe
this works for most cases.
My basic policy is:
Encoding whole text line as a part which means I don't
care even if such a text cannnot be read from English
terminal. This is because I believe no one have any
interests on those text, even if a part can be read anyway.
All or nothing should be the reasonable way in this case.
I tested this program of decoding patrt by reading
many Japanese articles from fj, but hadn't have any
problem up to now. The encoding part is new.
I also put new version of tcs library which would be
neccessary to compile this program on our plan 9
site: http://basalt.cias.osakafu-u.ac.jp/plan9/p9index.html
which is written by UTF-8.
Kenji
--------cut here------
/*
* MIME encode/decode test program for Japanese mode rin
* Nov. 18, 1998 Kenji Okamoto
*
* char1 char2 char3 char4
* |----------|-----------|-----------|-----------|
* 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8
* |--------------|---------------|---------------|
* 1 2 3
*/
#include <u.h>
#include <libc.h>
#include <tcs.h>
char *mime_decode(char *, char*);
static char *decodeB64(char *);
char *
mime_decode(char *from, char *decoded) {
char *mimest, *charst, *newline;
char tbuff[150], tbuff2[150];
*decoded = 0;
if(!(mimest = strstr(from, "=?")))
return(from);
else { /* mime encoded */
if (charst = strstr(from, "ISO-2022-JP?"))
charst += 12;
else if(charst = strstr(from, "iso-2022-jp?"))
charst += 12;
else
return(from); /* MIME but other than JIS */
}
if(*charst++ != 'B')
return(from); /* probably Q encoded */
charst++; /* top address of B64 encoded string */
/* if(*charst != 'G')
return(from); not JIS */
strncpy(decoded, from, mimest-from); /* not encoded part */
decoded[mimest-from] = 0;
mimest = strstr(charst, "?="); /* mimest=last address + 1 */
strncpy(tbuff, charst, mimest-charst);
tbuff[mimest-charst] = 0;
if(newline = strstr(tbuff, "\n\t")) {
tbuff2[0] =0;
strncat(tbuff2, tbuff, newline-tbuff);
strcat(tbuff2+(newline-tbuff), newline+2);
tbuff[0] = 0;
strcat(tbuff, tbuff2);
}
decoded = strcat(decoded, decodeB64(tbuff));
return(decoded);
}
static char
*decodeB64(char *from) {
char decoded[150];
int char1, char2, char3, char4;
int i=0,j=0;
char base64[] = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
-1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
};
decoded[0] = '\0';
while(from[i] != 0) {
if((char1 = base64[from[i]]) == -1)
return 0;
if(from[i+1] == '=') {
char2 = 0;
decoded[j] = (char1 << 2) | ((char2 & 0x30) >> 4);
decoded[j+1] = '\0';
break;
}else if(from[i+2] == '=') {
if((char2 = base64[from[i+1]]) == -1)
return 0;
char3 = 0;
decoded[j] = (char1 << 2) | ((char2 & 0x30) >> 4);
decoded[j+1] = ((char2 & 0x0f) << 4) | ((char3 & 0x3c) >> 2);
decoded[j+2] = '\0';
break;
}else if(from[i+3] == '=') {
if((char2 = base64[from[i+1]]) == -1)
return 0;
if((char3 = base64[from[i+2]]) == -1)
return 0;
char4 = 0;
decoded[j] = (char1 << 2) | ((char2 & 0x30) >> 4);
decoded[j+1] = ((char2 & 0x0f) << 4) | ((char3 & 0x3c) >> 2);
decoded[j+2] = ((char3 & 0x03) << 6) | char4;
decoded[j+3] = '\0';
break;
}else {
if((char2 = base64[from[i+1]]) == -1)
return 0;
if((char3 = base64[from[i+2]]) == -1)
return 0;
if((char4 = base64[from[i+3]]) == -1)
return 0;
decoded[j] = (char1 << 2) | ((char2 & 0x30) >> 4);
decoded[j+1] = ((char2 & 0x0f) << 4) | ((char3 & 0x3c) >> 2);
decoded[j+2] = ((char3 & 0x03) << 6) | char4;
decoded[j+3] = '\0';
i+=4;
j+=3;
}
}
return(decoded);
}
/*
* mime Base64 encode routine
* K.Okamoto Nov. 18, 1998
*/
static char B64charset[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static int encodeB64(char*, char*);
char *mime_encode(char*, char*);
char
*mime_encode(char *from, char *encoded) {
char *jisstr, *ptr;
char buff[100];
int i, j;
ptr = encoded;
while(*from) {
if (*from >= ' ' && *from <= 0x7f) /* ASCII code */
*ptr++ = *from++;
else if (*from == '\n' || *from == '\t')
*ptr++ = *from++;
else if (*from == '\033') { /* ESC sequence for JIS code */
j = 0;
if (!strncmp(from, "\033$B", 3)) { /* JISIN */
strncpy(ptr, "=?ISO-2022-JP?B?", 16);
jisstr = ptr + 16;
j = encodeB64(from, jisstr);
for(i=0;*jisstr;jisstr++, i++);
ptr = ptr+i+16;
strncpy(ptr, "?=", 2);
ptr += 2;
*ptr = 0;
from += j;
}
}
}
if((i = strlen(encoded)) > 66) { /* folding og large length line */
strncpy(buff, encoded, 66);
buff[66] = '\n';
buff[67] = '\t';
strncpy(buff+68, encoded+66, i-66);
i += 2;
while(*encoded) *encoded = 0;
strncpy(encoded, buff, i);
encoded[i] = 0;
}
return(encoded);
}
static int
encodeB64(char *from, char *encoded)
{
int char1, char2, char3;
char *first;
first = from;
while (char1 = *from++) {
if (char2 = *from++) {
if (char3 = *from++) {
*encoded++ = B64charset[char1 >> 2];
*encoded++ = B64charset[((char1 & 0x3) << 4) | ((char2 & 0xF0) >> 4)];
*encoded++ = B64charset[((char2 & 0xF) << 2) | ((char3 & 0xC0) >> 6)];
*encoded++ = B64charset[char3 & 0x3F];
} else {
*encoded++ = B64charset[char1 >> 2];
*encoded++ = B64charset[((char1 & 0x3) << 4) | ((char2 & 0xF0) >> 4)];
*encoded++ = B64charset[((char2 & 0xF) << 2) | ((0 & 0xC0) >> 6)];
*encoded++ = '=';
break;
}
} else {
*encoded++ = B64charset[char1 >> 2];
*encoded++ = B64charset[((char1 & 0x3) << 4) | ((0 & 0xF0) >> 4)];
*encoded++ = '=';
*encoded++ = '=';
break;
}
}
*encoded = '\0';
return(from-first);
}
void *
main(void) {
char txt[150];
char encoded[150];
uchar outp[150];
int i;
for(i=0;i<150;i++) outp[i]=0;
for(i=0;i<150;i++) txt[i] = 0;
strcpy(txt, "Re: ^[$B$3$l$O^[(HmimeB64^[$B$N%F%9%H$G$9^[(H.");
print("\noriginal text = %s\n", txt);
tcs((uchar*)txt, outp, "jis", "utf");
print("\nvisible original text = %s\n", (char *)outp);
for(i=0;i<150; i++) encoded[i] = 0;
mime_encode(txt, encoded);
print("\nencoded string = %s\n", encoded);
for(i=0;i<150;i++) txt[i]=0;
print("\ndecoded string = %s\n", mime_decode(encoded, txt));
}
-----end of this mail------
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~1998-11-18 9:01 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1998-11-18 9:01 [9fans] Base64 mime encode/decode program okamoto
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).