// For Scrabble3D: cc -o dic dic.c; ./dic < deutsch.dic

#include <stdio.h>
#include <string.h>
#define MAX_LINE 512

// Base 64 unpacking from base64.sourceforge.net/b64.c - go there for copyright info
static void unpack4to3(char *in, char *out)  {
   *out++ = in[0] << 2 | in[1] >> 4; *out++ = in[1] << 4 | in[2] >> 2; *out++ = in[2] << 6 | in[3];
}

static void decode(char *encoded, char *Key) {
   char in[4] = { '\0' }, out[3] = { '\0' };
   int eof = 0, keyidx = 1, v, i, len;

   while (*encoded) {
      for (len = 0, i = 0; i < 4 && *encoded; i++) {
	 v = 0;
	 while ((!eof) && (!v)) {
	    v = *encoded++; eof = !v;
	    if (!eof) {
	       v = ((v < 43 || v > 122) ? 0 : "|$$$}rstuvwxyz{$$$$$$$>?@ABCDEFGHIJKLMNOPQRSTUVW$$$$$$XYZ[\\]^_`abcdefghijklmnopq"[v - 43]);
	       if (v) {v = ((v == '$') ? 0 : v - 61);}
	    }
	 }
	 if (!eof) {len++; if (v) in[i] = v - 1;} else in[i] = '\0';
      }
      if (len > 0) {unpack4to3(in, out); for (i = 0; i < len - 1; i++) {putchar(out[i] ^ Key[keyidx++]); keyidx %= strlen(Key);}}
   }
   putchar('\n');
}

int main(int argc, char **argv) {
   char line[MAX_LINE], section[MAX_LINE], Key[MAX_LINE] = { '\0' }, *p, *s;

   line[MAX_LINE-1] = '\0';
   for (;;) {
      if (!(s = fgets(line, MAX_LINE-1, stdin))) break;
      if (*s) {
         p = s + strlen(s) - 1;
         if (*p == '\n') p -= 1; if (*p == '\r') p -= 1; if (*p == '\n') p -= 1; p += 1; *p = '\0';
      }
      if (*s == '[') puts(strcpy(section, s)); else {
	 if ((!strcmp(section, "[Header]")) && (!strncmp(s, "Key=", 4))) strcpy(Key, s + 4);
	 if ((*Key) && (!strcmp(section, "[Words]"))) decode(s, Key); else puts(s);
      }
   }
   fflush(stdout);
   return 0;
}
