#include #include #include static int seed, i, max_step_bits, b2, b3, size, bit_indices[16], step_indices[18], macro_table[36], x, y, byte, skip; static char *p, *q, *string_table[17], cmd[4], string_data[999] = "Qd%R>Rd%R%%RNIPRfi#VQ}R;TtuodtsRUd%RUd%RUOSetirwf!RnruterR{RTSniamRtniQ>h.oidtsrebmun<=NIPD-RhtiwRelipmocResaelPRrorre#QNIPRfednfi#V__ELIF__R_Renifed#V~-VU0V;}V{R=R][ORrahcRdengisnuRtsnocRcitatsVesle#Vfidne#V53556..1RfoRegnarRehtRniRregetniRnaRsiR]NIP[RerehwQQc.tuptuoR>Rtxt.tupniR= 81 && *p < 81 + 6 ? patch[*p - 81] : *p; if( !*q ) string_table[--x] = q + 1; } } for(; *bytecode; bytecode++) { if( *bytecode != ' ' ) { if( *bytecode != 'o' ) { byte = (byte + *bytecode) % (5 * 37); if( skip ) { skip--; } else { x = byte / 37 % 7; y = byte % 37; x > 0 ? printf(*string_table, string_table[x], y == 0 ? '_' : macro_table[y - 1]) : y > 14 && y < 33 ? printf(string_table[15 + (y > 15)], y > 15 ? 2 << (y % 16) : size, y > 15 ? (1 << (y % 16)) - 1 : 1) : puts(string_table[y % 28]); } byte = 0; } else { byte += 82; } } } } static void GenerateShuffledArray(int count, int *output) { int i, tmp; for(i = 0; i < count; i++) output[i] = i; for(; --count > 1;) { i = rand() % (count + 1); tmp = output[i]; output[i] = output[count]; output[count] = tmp; } } int main(int argc, char **argv) { if( argc != 0 ) { if( argc != 2 || sscanf(argv[1], "%d", &seed) != 1 || seed < 1 || seed > 65535 ) { Output("\""); return 1; } srand(time(NULL)); GenerateShuffledArray(16, bit_indices); /* Shuffle macro names. */ GenerateShuffledArray(36, macro_table); for(i = 0; i < 36; i++) macro_table[i] += macro_table[i] < 26 ? 'a' : 'A' - 26; /* Decoder header. */ Output(/* "#ifndef PIN\n" "#error Please compile with -DPIN=\n" */ "ou" /* #else */ "$" /* #ifndef _ */ "oB" /* #define _ __FILE__ */ "ot" /* Initialize PIN bits. { #if PIN %% %d > %d #define BIT%d #endif } * 16 */ "ow]#" "ox^#" "oy_#" "oz`#" "o{a#" "o|b#" "o}c#" "o~d#" "oo-e#" "oo.f#" "oo/g#" "oo0h#" "oo1i#" "oo2j#" "oo3k#" "oo4l#" /* static const unsigned char Z[] = { */ "op"); /* Initialize maximum number of steps to be at least 8 bits. This is needed since we use the step counter for both running PRNG and also for building characters, so we need at least 8 bits to support all possible character outputs even if the maximum number of steps between PRNG runs can be represented in less than 8 bits. */ max_step_bits = 8; size = 0; while( (i = getchar()) != EOF ) { /* Count number of steps needed to advance PRNG, with a minimum bound so that consecutive equal bytes will still advance the PRNG some number of times. */ b2 = (rand() % 16) + 1; for(b3 = 0; b3 < b2 || main(0, NULL) != i; b3++) { x = seed ^ (seed >> 2) ^ (seed >> 3) ^ (seed >> 5); seed = ((seed >> 1) | (x << 15)) & 0xffff; } /* Output directives to advance PRNG steps, testing the bits in shuffled order so that it's less obvious which macros map to which bits. Bit 17 is always included so that OUTPUT_BYTE is included in output macros. */ GenerateShuffledArray(18, step_indices); b3 |= 1 << 17; for(b2 = 0; b2 < 18; b2++) { i = step_indices[b2]; if( (b3 & (1 << i)) != 0 ) { /* #define STEP%d */ *cmd = kDefine * 37 + 1 + i; Output(cmd); if( i < 17 && max_step_bits < i ) max_step_bits = i; } } /* #include _ */ Output("!"); size++; } /* Decoder footer. */ Output(/* }; */ "oq" /* #include */ /* int main() { return !fwrite(data, %d, 1, stdout); } */ "ov" /* #else */ "$" /* #ifdef OUTPUT_BYTE */ "7" /* #undef OUTPUT_BYTE */ "o/" /* #define RUN_PRNG */ "n" /* #include _ */ "!"); /* Convert PRNG bits to byte increment bits. */ for(i = 0; i < 8; i++) { /* #ifdef BIT%d */ cmd[0] = kIfdef * 37 + 19 + bit_indices[i]; /* #define STEP%d */ cmd[1] = kDefine * 37 + 1 + i; /* #endif */ cmd[2] = kString * 37 + 35; Output(cmd); } /* Generate byte and start next byte. */ Output(/* #undef RUN_PRNG */ "oA" /* #include _ */ "!" /* 0, */ "or" /* #else */ "$"); skip = (16 - max_step_bits) * 7; /* Run PRNG steps. { #ifdef STEP%d #undef STEP%d #include _ #define STEP(%d-1) #include _ #define STEP(%d-1) #endif } * 16 */ Output("6o.!Z!Z#" "5o-!Y!Y#" "4~!X!X#" "3}!W!W#" "2|!V!V#" "1{!U!U#" "0z!T!T#" "/y!S!S#" ".x!R!R#" "-w!Q!Q#" "ooAv!P!P#" "+u!O!O#" "*t!N!N#" "oo>s!M!M#" "oo=r!L!L#" "'q!K!K#" /* Run a single step of PRNG, or increment pending byte by 1. */ /* #ifdef STEP0 */ "&" /* #undef STEP0 */ "p" /* #ifdef RUN_PRNG */ "I" /* #undef BIT16 */ "o@" /* Using linear feedback shift register, bit16 = bit0^bit2^bit3^bit5 */ ":;=oUm#$8m##$=8m#$oUm###$;=8m#$oUm##$=oUm#$8m####" /* seed = (bit16 | seed) >> 1 { #undef BIT%d #ifdef BIT(%d+1) #define BIT%d #endif } * 16 */ "o09]#" "o1:^#" "o2;_#" "o3<`#" "o4=a#" "o5>b#" "o6?c#" "o7@d#" "o8Ae#" "o9Bf#" "o:Cg#" "o;Dh#" "oGk#" "o?Hl#" /* #else */ "$" /* -~ */ "os" /* #endif */ "#" /* #endif */ "#" /* #endif */ "#" /* #endif */ "#" /* #endif */ "#"); seed = 0; } for(x = y = 0; x < 8; x++) { if( (seed & (1 << bit_indices[x])) != 0 ) y |= 1 << x; } return y; }