static const char* to_b64 =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
/* encode 72 characters per line */
#define CHARS_PER_LINE 72
char* b64enc(char* buff, int size, char* string)
{
int div = size / 3;
int rem = size % 3;
int chars = div*4 + rem + 1;
int newlines = (chars + CHARS_PER_LINE - 1) / CHARS_PER_LINE;
const byte* data = buff;
if (string)
{
register char* buf = string;
chars = 0;
/*@+charindex@*/
while (div > 0)
{
buf[0] = to_b64[ (data[0] >> 2) & 0x3f];
buf[1] = to_b64[((data[0] << 4) & 0x30) + ((data[1] >> 4) & 0xf)];
buf[2] = to_b64[((data[1] << 2) & 0x3c) + ((data[2] >> 6) & 0x3)];
buf[3] = to_b64[ data[2] & 0x3f];
data += 3;
buf += 4;
div--;
chars += 4;
if (chars == CHARS_PER_LINE)
{
chars = 0;
*(buf++) = '\r';
*(buf++) = '\n';
}
}
switch (rem)
{
case 2:
buf[0] = to_b64[ (data[0] >> 2) & 0x3f];
buf[1] = to_b64[((data[0] << 4) & 0x30) + ((data[1] >> 4) & 0xf)];
buf[2] = to_b64[ (data[1] << 2) & 0x3c];
buf[3] = '=';
buf += 4;
chars += 4;
break;
case 1:
buf[0] = to_b64[ (data[0] >> 2) & 0x3f];
buf[1] = to_b64[ (data[0] << 4) & 0x30];
buf[2] = '=';
buf[3] = '=';
buf += 4;
chars += 4;
break;
}
/*@=charindex@*/
/* *(buf++) = '\n'; This would result in a buffer overrun */
*buf = '\0';
}
return string;
}
int b64dec(const char* string, char* buff)
{
int size;
if (string)
{
int length = strlen(string);
/* do a format verification first */
if (length > 0)
{
int count = 0, rem = 0;
const char* tmp = string;
while (length > 0)
{
int skip = strspn(tmp, to_b64);
count += skip;
length -= skip;
tmp += skip;
if (length > 0)
{
int i, vrfy = strcspn(tmp, to_b64);
for (i = 0; i < vrfy; i++)
{
if (isspace(tmp[i]))
continue;
if (tmp[i] == '=')
{
/* we should check if we're close to the end of the string */
rem = count % 4;
/* rem must be either 2 or 3, otherwise no '=' should be here */
if (rem < 2)
return 0;
/* end-of-message recognized */
break;
}
else
{
/* Transmission error; RFC tells us to ignore this, but:
* - the rest of the message is going to even more corrupt since we're sliding bits out of place
* If a message is corrupt, it should be dropped. Period.
*/
return 0;
}
}
length -= vrfy;
tmp += vrfy;
}
}
size = (count / 4) * 3 + (rem ? (rem - 1) : 0);
if (buff)
{
if (count > 0)
{
int i, qw = 0, tw = 0;
byte* data = buff;
length = strlen(tmp = string);
for (i = 0; i < length; i++)
{
register char ch = string[i];
register byte bits;
if (isspace(ch))
continue;
bits = 0;
if ((ch >= 'A') && (ch <= 'Z'))
{
bits = (byte) (ch - 'A');
}
else if ((ch >= 'a') && (ch <= 'z'))
{
bits = (byte) (ch - 'a' + 26);
}
else if ((ch >= '0') && (ch <= '9'))
{
bits = (byte) (ch - '0' + 52);
}
else if (ch=='+') {
bits = 62;
}
else if (ch=='/') {
bits = 63;
}
else if (ch == '=')
break;
switch (qw++)
{
case 0:
data[tw+0] = (bits << 2) & 0xfc;
break;
case 1:
data[tw+0] |= (bits >> 4) & 0x03;
data[tw+1] = (bits << 4) & 0xf0;
break;
case 2:
data[tw+1] |= (bits >> 2) & 0x0f;
data[tw+2] = (bits << 6) & 0xc0;
break;
case 3:
data[tw+2] |= bits & 0x3f;
break;
}
if (qw == 4)
{
qw = 0;
tw += 3;
}
}
}
}
}
}
return size;
}
#define SKIP '\202'
#define NOSKIP 'A'
const char hexmap[] = {
SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 ,
8 , 9 , SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
SKIP, 10, 11, 12, 13, 14, 15, SKIP,
SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP
};
int qpdec(const char* string, char* buff)
{
char *s;
char *result = buff;
int i;
char mid[3];
bool ok = true;
s = string;
while (*s != '\0') //loop through the entire string...
{
if (*s == '=') //woops, needs to be decoded...
{
for (i = 0; i < 3; i++) //is s more than 3 chars long...
{
if (s[i] == '\0')
{
return 0;
}
}
s++; //move past the "="
//let's put the hex part into mid...
for (i = 0; i < 2; i++)
{
if (hexmap[s[i]] == SKIP)
{
//we have an error, or a linebreak, in the encoding...
ok = false;
if (s[i] == '\r' && s[i + 1] == '\n')
{
s += 2;
//*(result++) = '\r';
//*(result++) = '\n';
break;
}
else
{
//we have an error in the encoding...
//s--;
}
}
mid[i] = s[i];
}
//now we just have to convert the hex string to an char...
if (ok)
{
int m;
s += 2;
m = hexmap[mid[0]];
m <<= 4;
m |= hexmap[mid[1]];
*(result++) = m;
}
}
else
{
if (*s != '\0') *(result++) = *(s++);
}
}
*(result++)=0;
return strlen(string);
}
【 在 freewizard (Enter HAPPY :: Reloaded :: Revolution) 的大作中提到: 】
: --- mailgate.pl.031122 Sun Nov 23 22:25:56 2003
: +++ mailgate.pl Sun Nov 23 22:27:17 2003
: @@ -46,7 +46,7 @@
: $_ = $MAIL[$index];
: last if ( $_ eq "\n" );
: chop;
: - if (/^(\S+): (.*)$/) {
: + if (/^(?:(\S+): ([^;]*))?;?\s*(?:(\S+)="(.*)")?(?:(\S+)=(.*))?$/) {
: $hhh = $Header{$1};
: if ( $1 eq "Received" && $hhh ) {
: $tmp = "$2";
: ...................
--
FROM yesterday