Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation

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;


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

Replies are listed 'Best First'.
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.

    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 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
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)

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

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: obfuscated [id://249270]
Approved by diotalevi
and the questions are moot...

How do I use this? | Other CB clients
Other Users?
Others cooling their heels in the Monastery: (11)
As of 2018-06-22 16:15 GMT
Find Nodes?
    Voting Booth?
    Should cpanminus be part of the standard Perl release?

    Results (124 votes). Check out past polls.