/* cirno.c - Don Yang (uguu.org) 09/07/08 */ /*@ -compdef @*/ #include #include #ifdef _WIN32 #include #include #endif #define READ_BUFFER_SIZE (4 * 15 * 128) #define WRITE_BUFFER_SIZE ((5 * 15 + 1) * 128) /* Encode a 4 byte block */ #define BASE 90 #define ENCODE_BLOCK \ input_word = (unsigned int)*r++; \ input_word |= (unsigned int)(*r++) << 8; \ input_word |= (unsigned int)(*r++) << 16; \ input_word |= (unsigned int)(*r++) << 24; \ a = input_word % BASE; \ b = (input_word /= BASE) % BASE; \ c = (input_word /= BASE) % BASE; \ d = (input_word /= BASE) % BASE; \ e = input_word / BASE; \ *w++ = (unsigned char)(a + 33); \ *w++ = (unsigned char)(b + 33); \ *w++ = (unsigned char)(c + 33); \ *w++ = (unsigned char)(d + 33); \ *w++ = (unsigned char)(e + 33); /* Encode file to stdout */ static void Encode(FILE *infile) { unsigned char input[READ_BUFFER_SIZE], *r; unsigned char output[WRITE_BUFFER_SIZE], *w; unsigned int input_word, a, b, c, d, e; size_t read_size, block_count, output_block_count, offset; offset = output_block_count = 0; while( (read_size = fread(input + offset, 1, READ_BUFFER_SIZE - offset, infile)) > 0 ) { read_size += offset; if( read_size < 4 ) { offset = read_size; continue; } /* Convert input */ r = input; w = output; block_count = read_size / 4; for(offset = 0; offset < block_count; offset++) { ENCODE_BLOCK output_block_count++; if( output_block_count == 15 ) { *w++ = (unsigned char)'\n'; output_block_count = 0; } } /* Write output */ (void)fwrite(output, (size_t)w - (size_t)output, 1, stdout); /* Shift last incomplete block to beginning */ offset = read_size % 4; if( offset > 0 ) memmove(input, r, offset); } /* Write last block */ if( offset > 0 ) { for(a = (unsigned int)offset; a < 4; a++) input[a] = (unsigned char)0; r = input; w = output; ENCODE_BLOCK output[offset + 1] = '\n'; (void)fwrite(output, offset + 2, 1, stdout); } else if( output_block_count != 0 ) { (void)fputc('\n', stdout); } } int main(int argc, char **argv) { FILE *infile; if( argc < 2 ) { #ifdef _WIN32 setmode(fileno(stdin), O_BINARY); #endif Encode(stdin); } else if( argc == 2 ) { if( (infile = fopen(argv[1], "rb")) == NULL ) { fprintf(stderr, "Error reading %s\n", argv[1]); return 1; } Encode(infile); (void)fclose(infile); } else { printf("%s [input.bin] > output.txt\n", *argv); } return 0; }