Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

Flying Obfu

by awkmonk (Monk)
on Apr 09, 2003 at 15:54 UTC ( #249270=obfuscated: print w/ replies, xml ) Need Help??

OK this is my first post to obfu, 

I'm not too sure how obfuscated this snippet is, but it it does have the distinction of being a piece of live code (used in an aircraft flight control package of all places and was originally written in ADA *gulp*)

It took me a while to figure it out what it was doing when I came across it:

$a = $a ^ $b; $b = $a ^ $b; $a = $a ^ $b;

Enjoy....


'I think the problem lies in the fact that your data doesn't fit my program'.

Comment on Flying Obfu
Download Code
Re: Flying Obfu
by nothingmuch (Priest) on Apr 09, 2003 at 16:15 UTC
    Swaps a with b. An old assembly idiom... ^= will also get what you want... =)

    Update: used to be common... when i learnt assembly no teacher knew it. I found that in some perl tut actually, which i skimmed for a friend. It discussed something along "while that trick may have been common for swapping registers in assembly, in perl you can do ($a,$b) = ($b, $a) instead.

    -nuffin
    zz zZ Z Z #!perl

      Oops. I didn't realise it was a common assembly trick, or I wouldn't have posted it.

      Still for none assembly people it can be fun to work out how it does it (preferably on paper, and after a couple of pints).

      Thanks for pointing it out.


      'I think the problem lies in the fact that your data doesn't fit my program'.

Re: Flying Obfu
by BUU (Prior) on Apr 09, 2003 at 21:40 UTC
    I've seen this several dozen times and still have no clue why it works. Can anyone write up a nice explanation?

      Essentially it does this:

      # let's assume some values for the sake of discussion $a = 'foo'; $b = 'bar'; $a = $a ^ $b; # $a now contains both variables, $a and $b logical or'ed # together, so at this point a=foo^bar and b=bar $b = $a ^ $b; # logically or-ing them again (since b still contains bar) # returns the original value of a, so now a=foo^bar # and b=foo $a = $a ^ $b; # then we logical-or the combined value with b, which now # contains our original a value. this returns the # original b value, so now a=bar and b=foo

      It's one of those things that you can look at a dozen times, and suddenly your brain just goes 'ah ha!'.

      Update: Of course read 'exclusive or (or xor)' everywhere that I said 'logical or', it must be bedtime.


      We're not surrounded, we're in a target-rich environment!
      $a = ord('A'); # 01000001 $b = ord('B'); # 01000010 $a = $a ^ $b; # 01000001 XOR 01000010 = 00000011 $b = $a ^ $b; # 00000011 XOR 01000010 = 01000001 $a = $a ^ $b; # 00000011 XOR 01000001 = 01000010

      Or, if you think in terms of truth tables:

      original $aoriginal $b$a ^ $b (gives new $a)$a ^ $b (gives new $b)$a ^ $b (gives new $a)
      00000
      01101
      10110
      11011

      As you can see, original $a is the same as new $b and original $b is the same as new $a.

Re: Flying Obfu
by jonadab (Parson) on Apr 14, 2003 at 15:46 UTC
    This was done for speed. XOR is a very fast operation on some processor types (e.g., 8086). Along similar lines, we were taught to use XOR to zero a register, because XORing it with itself was much faster than assigning a constant value to the register. Whether it's actually any faster in Perl than the equivalent swap, I don't know, but it would be faster in some assembly languages. So, three XORs would accomplish the swap faster than the usual three assignments, too. How many times a second does this need to run? You might want to leave it alone, if it's a flight control system, or at least do a benchmark before you change it.

      Not much chance of this one being changed - the paperwork would be horrendous (it's part of the flight control of a Tornado).

      The person that wrote it clearly didn't do it for speed as they didn't recognise that 2 if's are quicker than an and.

      It appears to have been done primarily to avoid introducing a third variable. No ($a, $b) = ($b, $a) functionality available. Even so, I still believe it to be a prime example of 'how not to code' in a high risk, real time environment when it should count as 'quite important' that maintenance staff can clearly follow the code.

      We live and learn I suppose.


      'I think the problem lies in the fact that your data doesn't fit my program'.

Re: Flying Obfu
by Anonymous Monk on Apr 20, 2003 at 06:42 UTC
    let $a = a, $b = b
    remember a ^ a = 0, a ^ 0 = a, (a^b)^c = a^(b^c), a^b=b^a
    
                     $a                   $b
                ------------------ -------------------- 
    $a=$a^$b        a^b                    b
    $b=$a^$b        a^b           (a^b)^b=a^(b^b)=a^0=a
    $a=$a^$b     a^b^a=a^a^b=0^b=b         a
    

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: obfuscated [id://249270]
Approved by diotalevi
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others about the Monastery: (3)
As of 2014-10-02 01:56 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    What is your favourite meta-syntactic variable name?














    Results (41 votes), past polls