Search code examples
cobfuscationdeobfuscation

Multiple Ternary in C with comma?


so I saw this code

b[2080];
main(j) {
  for (;;) {
    printf("\x1b[H");
    for (j = 1; j < 2080; j++) 
    b[j] = j < 2000 ? (b[j + 79] + b[j + 80] + b[j] + b[j - 1] + b[j + 81]) / 5 : rand() % 4 ? 0 : 512, j < 1840 ? putchar((j % 80) == 79 ? '\n' : " .:*#$H@" [b[j] >> 5]) : 0;
    usleep(20000);
  }
}

so I tried to rewrite it, why even divide 32?
The array got to declare as global else it won't work. any idea?
also why 512? here is my attempt so far, any problem?

for (int j = 1; j < 2080; j++) 
            {
                if (j < 2000) {
                    b[j] = (b[j + 79] + b[j + 80] + b[j] + b[j - 1] + b[j + 81]) / 5;
                }
                else if (rand() % 4 != 0) { // Generate random integers in range 0 to 4
                          b[j] = 0;
                     }
                     else
                     {
                         b[j] = 512;
                     }
                   
                }
            }

Solution

  • Here's the functionally equivalent code with the ternary operators converted into if/else statements:

                if (j < 2000) {
                    b[j] = (b[j + 79] + b[j + 80] + b[j] + b[j - 1] + b[j + 81]) / 5;
                } else if (rand() % 4) {
                    b[j] = 0;
                } else {
                    b[j] = 512;
                }
                if (j < 1840) {
                    if ((j % 80) == 79) {
                        putchar('\n');
                    } else {
                        putchar(" .:*#$H@"[b[j] / 32]);
                    }
                }
    

    As for the question of what does the right shift >> 5 do, it divides by 32 (25), and then indexes the array " .:*#$H@" with that divided value.

    edit: As for why the array is global, it's probably just to get it initialised to zero without extra code (the whole thing seems to be written as short as possible, e.g., using implicit int types and j from the argument).

    Note that there is an access out of bounds bug in the (original) code: b[j + 81] can be accessed when j is 1999 (since that is < 2000), but 1999 + 81 == 2080, and b[2080] is out of bounds. You can replace the array with a local int b[2081] = { 0 }; but it changes the output slightly while fixing the bug.