/* * Baltisot * Copyright (C) 1999-2009 Nicolas "Pixel" Noble * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include // Banned chars: ",/:.[\] // EOF marker: ~ static char cb85[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$%&'()*+-;<=>?@^_`{|}"; static char lookup[] = { // x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x 0, 62, 0, 63, 64, 65, 66, 67, 68, 69, 70, 71, 0, 72, 0, 0, // 2x 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, 73, 74, 75, 76, 77, // 3x 78, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, // 4x 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 79, 80, // 5x 81, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, // 6x 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 82, 83, 84, 0, 0, // 7x 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx }; String Base85::encode_block(unsigned char in_tab[4], int len) { unsigned int tuple; char r[6]; tuple = in_tab[0]; tuple |= in_tab[1] << 8; tuple |= in_tab[2] << 16; tuple |= in_tab[3] << 24; r[0] = cb85[tuple % 85]; tuple /= 85; r[1] = cb85[tuple % 85]; tuple /= 85; r[2] = len > 1 ? cb85[tuple % 85] : '~'; tuple /= 85; r[3] = len > 2 ? cb85[tuple % 85] : '~'; tuple /= 85; r[4] = len > 3 ? cb85[tuple % 85] : '~'; r[5] = 0; return r; } String Base85::encode(const char * data, int stream_size) { String encoded = ""; unsigned char in_tab[4]; int len, i, s_pos; s_pos = 0; while (stream_size > 0) { in_tab[0] = 0; in_tab[1] = 0; in_tab[2] = 0; in_tab[3] = 0; len = stream_size >= 4 ? 4 : stream_size; for (i = 0; i < len; i++) { in_tab[i] = data[s_pos + i]; } encoded += encode_block(in_tab, len); s_pos += 4; stream_size -= 4; } return encoded; } int Base85::decode_block(char s1, char s2, char s3, char s4, char s5, unsigned char * out_tab) { int len, sb1, sb2, sb3, sb4, sb5; unsigned int tuple; len = s3 == '~' ? 1 : s4 == '~' ? 2 : s5 == '~' ? 3 : 4; s3 = (s3 == '~') || (s3 == 0) ? 0 : s3; s4 = (s4 == '~') || (s4 == 0) ? 0 : s4; s5 = (s5 == '~') || (s5 == 0) ? 0 : s5; sb1 = lookup[s1]; sb2 = lookup[s2]; sb3 = lookup[s3]; sb4 = lookup[s4]; sb5 = lookup[s5]; tuple = sb5; tuple *= 85; tuple += sb4; tuple *= 85; tuple += sb3; tuple *= 85; tuple += sb2; tuple *= 85; tuple += sb1; out_tab[0] = tuple & 255; tuple >>= 8; out_tab[1] = tuple & 255; tuple >>= 8; out_tab[2] = tuple & 255; tuple >>= 8; out_tab[3] = tuple & 255; return len; } unsigned char * Base85::decode(const String & str_in, int * len_out) { int s_len = str_in.strlen(), len = 0, i, j, t_len; char s1, s2, s3, s4, s5; unsigned char t_out[4]; unsigned char * out = (unsigned char *) malloc(s_len * 4 / 5 + 5); unsigned char * p = out; for (i = 0; i < s_len; i += 5) { s1 = str_in[i + 0]; s2 = str_in[i + 1]; s3 = str_in[i + 2]; s4 = str_in[i + 3]; s5 = str_in[i + 4]; t_len = decode_block(s1, s2, s3, s4, s5, t_out); for (j = 0; j < t_len; j++) { *(p++) = t_out[j]; } len += t_len; } if (len_out) { *len_out = len; } return out; }