/* ASCII Armour Encoding, (C) 2004 HardCore SoftWare These are some small, efficient "plug and play" functions for encoding binary data in a safe ASCII transport medium. It is somewhat similar to base64 encoding, but simpler. This software is Copyright (C) 2004 By Hardcore Software. The software is distributed under the terms of the GNU General Public License. See the website www.gnu.org for more information. This function encodes a collection of binary data stored at the memory location "in", of length "len". It stores the ASCII encoded string in the memory location "out". "out" should have at least %50 more space available than "len". void encodearmour(char *in, int len, char *out); This function decodes an ASCII encoded string created by the encodearmour() function, stored in the memory location "in" and stores it into "out". "out" should have as much space as strlen(in). This function returns the number of bytes of data stored into "out". int decodearmour(char *in, char *out); -Doug Hoyte */ static char map[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+*"; static char revmap[] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x3F\x3E\0\0\0\0\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\0\0\0\0\0\0\0\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\0\0\0\0\0\0\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33"; void encodearmour(char *in, int len, char *out) { int curpos, bitoff, curbit, t=0; if (len == 0) { *out = '\0'; return; } curpos = curbit = 0; while(1) { curpos = curbit / 8; bitoff = curbit % 8; if (curpos == len-1) { if (bitoff == 2) { t = in[curpos] & 63; *(out++) = map[t]; } else if (bitoff == 0) { t = (in[curpos] & 0xFF) >> 2; *(out++) = map[t]; *(out++) = map[(in[curpos] & 3) << 4]; } else if (bitoff == 4) { t = (in[curpos] & 15) << 2; *(out++) = map[t & 63]; } break; } if (bitoff == 0) t = (in[curpos] & 0xFF) >> 2; else if (bitoff == 2) t = in[curpos] & 63; else if (bitoff == 4) t = ((in[curpos] & 15) << 2) | ((in[curpos+1] & 0xFF) >> 6); else if (bitoff == 6) t = ((in[curpos] & 3) << 4) | ((in[curpos+1] & 0xFF) >> 4); *(out++) = map[t & 63]; curbit += 6; } *out = '\0'; } int decodearmour(char *in, char *out) { int curbit=0, t, c1=0, c2=0, bytes=0; if (*in == 0) return 0; while(*in != '\0' && *in != '\n' && *in != '\r' && *in != ' ') { t = revmap[(int) *(in++)]; if (curbit == 0) c1 = t << 2; else if (curbit == 2) c1 |= t; else if (curbit == 4) { c1 |= t >> 2; c2 = (t & 3) << 6; } else if (curbit == 6) { c1 |= t >> 4; c2 = (t & 15) << 4; } curbit += 6; if (curbit >= 8) { *(out++) = c1 & 0xFF; bytes++; c1 = c2; c2 = 0; curbit %= 8; } } return bytes; }