Thaddeus has isolated a couple of bugs for you - "luckily" your outer loop in main never looks like it executed, as had it done so the first time you dereferenced a you'd have probably crashed the program by writing to memory somewhere around the start of the virtual address space.
As well as the points he made (initialising the array and loop variables) are you sure your decode function is correct?
"1234567890abcdefghijklmnopqrstuvwxyz"[a[i/npack]>>((i%npack)*2)&3]
looks so complicated it has to be wrong - you're using an esoteric feature of C string literals, using modulo AND a bitwise gimmick to simulate modulo all in the same expression. If you unroll that expression for 6 passes around the loop it becomes:
const char glyphs[] = "1234567890abcdefghijklmnopqrstuvwxyz";
putc( glyphs[ a[0] ] );
putc( glyphs[ a[0] ] >> 2 );
putc( glyphs[ a[0] ] );
putc( glyphs[ a[0] ] >> 2 );
putc( glyphs[ a[1] ] );
putc( glyphs[ a[1] ] >> 2 );
so you're not actually reading 80% of the array passed in AND you'll be printing out multiple identical values.
Anyway the moral here is write code other people can understand easily, 'cause when you have to debug it or test it you're suddenly that other person. What sounds cool now ("Hey I can use array addressing on string literals!", "Did you know you can simulate modulo for one less than 2 raised to the power of n by ANDing with 2^n - 1??") becomes a real pain in the rectum to understand later.
Oh, and if the decode function is really meant to do what the code says it does, can you enlighten me as why? I'm buggered if I can see a reason for doing it but I'm always interested in learning new things.
Cheers,
Ash