/* akyuu.c - Don Yang (uguu.org) 09/07/08 */ /*@ -compdef -usedef @*/ #include #include #ifdef _WIN32 #include #include #endif #define READ_BUFFER_SIZE 10000 #define WRITE_BUFFER_SIZE 8000 /* Decode a 5 character block */ #define BASE 90 #define DECODE_BLOCK \ e = (unsigned int)(*r++) - 33; \ d = (unsigned int)(*r++) - 33; \ c = (unsigned int)(*r++) - 33; \ b = (unsigned int)(*r++) - 33; \ a = (unsigned int)(*r++) - 33; \ output_word = (((a * BASE + b) * BASE + c) * BASE + d) * BASE + e; \ *w++ = (unsigned char)(output_word & 255); \ *w++ = (unsigned char)((output_word >>= 8) & 255); \ *w++ = (unsigned char)((output_word >>= 8) & 255); \ *w++ = (unsigned char)(output_word >> 8); /* Decode file to stdout */ static void Decode(FILE *infile) { unsigned char input[READ_BUFFER_SIZE]; unsigned char output[WRITE_BUFFER_SIZE]; unsigned char *r, *w; unsigned int output_word, a, b, c, d, e; size_t read_size, offset, block_count; offset = 0; while( (read_size = fread(input + offset, 1, READ_BUFFER_SIZE - offset, infile)) > 0 ) { /* Skip over illegal characters in input */ read_size += offset; for(r = w = input + offset; r < input + read_size; r++) { if( (unsigned int)*r >= 33 && (unsigned int)*r < 33 + BASE ) *w++ = *r; } read_size = (size_t)w - (size_t)input; /* Convert input */ r = input; w = output; block_count = read_size / 5; for(offset = 0; offset < block_count; offset++) { DECODE_BLOCK } /* Write output */ (void)fwrite(output, (size_t)w - (size_t)output, 1, stdout); /* Shift last incomplete block */ offset = read_size % 5; if( offset > 0 ) memmove(input, r, offset); } /* Write last incomplete block */ if( offset > 0 ) { for(a = (unsigned int)offset; a < 5; a++) input[a] = (unsigned char)33; r = input; w = output; DECODE_BLOCK (void)fwrite(output, offset - 1, 1, stdout); } } int main(int argc, char **argv) { FILE *infile; #ifdef _WIN32 setmode(fileno(stdout), O_BINARY); #endif if( argc < 2 ) { Decode(stdin); } else if( argc == 2 ) { if( (infile = fopen(argv[1], "rb")) == NULL ) { fprintf(stderr, "Error reading %s\n", argv[1]); return 1; } Decode(infile); (void)fclose(infile); } else { printf("%s [input.txt] > output.bin\n", *argv); } return 0; }