c++ - Can you explain what this binary swapping operation is doing? -


i'm trying solve programing programing puzzle. puzzle encrypting messages using following c++ code:

int main() {   int size;    cin >> size;    unsigned int* = new unsigned int[size / 16]; // <- input tab encrypt   unsigned int* b = new unsigned int[size / 16]; // <- output tab    (int = 0; < size / 16; i++) {   // read size / 16 integers     cin >> hex >> a[i];   }    (int = 0; < size / 16; i++) {   // write size / 16 zeros b     b[i] = 0;   }     (int = 0; < size; i++)     (int j = 0; j < size; j++) {       b[(i + j) / 32] ^= ( (a[i / 32] >> (i % 32)) &                (a[j / 32 + size / 32] >> (j % 32)) & 1 ) << ((i + j) % 32);   // magic centaurian operation   }    for(int = 0; < size / 16; i++) {     if (i > 0) {       cout << ' ';     }     cout << setfill('0') << setw(8) << hex << b[i];       // print result   }   cout << endl;   /*      luck humans       */   return 0; } 

the objective reverse encoding (that should known mathematical operation when identified). problem i'm facing cannot understand encoding works , these binary operations doing. can explain me how encoding works?

thank you!

to learn operations are, break down loop-by-loop , line-by-line, apply rules of precedence. nothing more, nothing less. if haven't lost track somewhere in bitwise swamp, effect of boils down exclusive xor'ing orignal value @ index b[(i + j) / 32] power of 2 in range of signed integer (or 0). analysis this:

for (int = 0; < size; i++)      (int j = 0; j < size; j++) {          b[(i + j) / 32] ^=           ( (a[i / 32] >> (i % 32)) &              (a[j / 32 + size / 32] >>               (j % 32)) & 1 ) <<               ((i + j) % 32);   // magic centaurian operation     } } 

what first operation:

 b[(i + j) / 32] ^=  

this in exclusive or of value @ index. if let idx represent jumble computes index, can write as:

b[idx] ^= stuff 

which applying rules of precedence (right-to-left ^=) same writing:

b[idx] = b[idx] ^ stuff 

the order of precedence tells me need figure out stuff before can apply value of b[idx]. looking @ stuff have:

  |                                                 | << |      b      |   |          c      | & |             d               |    |             |   |                 |   |          e            | & 1 |    |             |   +-----------------+---+-----------------------+-----+----+-------------+   ( (a[i/32]>>(i%32)) & (a[j/32+size/32]>>(j%32)) & 1 ) << ( (i+j) % 32 ); 

breaking in down, have a << b, can further broken down as:

( c & d ) << b 

or finally:

(c & e & 1) << b 

the rules of precedence relevant (c & e & 1) << b applied left-to-right giving deference parenthesis grouping.

so b? number grouping (c & e & 1) shifted left by. in terms of index values i , j modded number of bits in integer, shift bits in grouping (c & e & 1) left 0-31 bits depending on combined value of i+j.

the grouping (c & e & 1) entirely similar analysis. a[i/32]>>(i%32) nothing more value @ a[i/32] shifted right (i%32). e same differnt index manipulation: (a[j/32+size/32]>>(j%32)) value @ index shifted right (j%32). result of both of shifts anded 1. means entire grouping (c & e & 1) have value if both c & e odd number values.

why odd values? binary standpoint, odd numbers values have one-bit 1. (e.g. 5 & 7 & 1 (101 & 111 & 1) = 1). if of values even or 0, whole grouping 0.

understanding grouping (c & e & 1) (or have largely grouped a), can at:

a << b 

knowing a 0 or 1, know way result of shift have value if a 1, , result of group value of 1 shifted left b bits. knowing b has range of 0-31, range of values a << b between 0 - 2147483648, but since shifting between 0 - 31, values a << b positive powers of 2 between 0 - 2147483648 (binary: 0, 1, 10, 100, 1000, etc...)

then brings

b[idx] = b[idx] ^ stuff 

which when exclusively or power of two, serve flip bit @ power of 2 in number. (e.g. 110101 (26) ^ 1000 (8) = 111101 (61)). other bits unchanged. final effect of operations make:

b[idx] = b[idx] ^ stuff 

nothing more than:

b[idx] = b[idx] ^ (power of two) 

or

b[idx] = b[idx] ^ 0   /* nothing more b[idx] begin */ 

let me know if have questions. can dump index calculations @ values, should cover operations @ issue.


Comments

Popular posts from this blog

html - Outlook 2010 Anchor (url/address/link) -

javascript - Why does running this loop 9 times take 100x longer than running it 8 times? -

Getting gateway time-out Rails app with Nginx + Puma running on Digital Ocean -