RE: [Algorithms] Byte Swapping
Brought to you by:
vexxed72
From: Daniel K. <Dan...@ix...> - 2000-07-18 09:42:06
|
Hi Listizens, well, if you look at the line y = (x = x>>16 | x<<16) ^ (x = (x^x>>8) & 0x00FF00FF) ^ (x<<8); especially at the first xor op (x = x>>16 | x<<16) ^ (x = (x^x>>8) & 0x00FF00FF) then you see that the result of the first assignment (x = x>>16 | x<<16), let's call it 'z' is used in the calculation of the second term (x = (x^x>>8) & 0x00FF00FF) or (x = (z^z>>8) & 0x00ff00ff) The new result will overwrite the old content of x (which was z), i.e. the whole operation y = (x = x>>16 | x<<16) ^ (x = (x^x>>8) & 0x00FF00FF) ^ (x<<8) doesnt equal y = z ^ x ^ (x<<8) as expected but y = x ^ x ^ (x<<8) which basically is y = 0 ^(x<<8) = (x<<8) ! That gets us x = 0x01020304 new x #1 (=z) = 0x03040102 new x #2 = (0x03040102 ^ 0x00030401) & 0x00ff00ff = 0x00070003 y = 0 ^ (0x00070003<<8) = 0x07000300. When you write it as y = x = (x>>16)|(x<<16); y ^= (x = ((x^(x>>8)) & 0x00FF00FF)); y ^= (x<<8); the 'z' from above is stored in 'y' as well. That's why the threeliner gives the correct result... Cheers, Daniel. > -----Original Message----- > From: Charles Bloom [mailto:cb...@cb...] > Sent: Tuesday, July 18, 2000 4:50 AM > To: gda...@li... > Subject: Re: [Algorithms] Byte Swapping > > > > Hmm... I'm not sure what's wrong with it, it's some C order > of operations > problem > that I'm not familiar with. If you expand it out into simple steps : > > y = x = (x>>16)|(x<<16); > y ^= (x = ((x^(x>>8)) & 0x00FF00FF)); > y ^= (x<<8); > > then it works just fine. If you have four bytes ABCD, the first line > turns them into CDAB. The second line gives you (0D0B^0C0A). The > last line is thus (D0B0^C0A0). Put them all together : > > y = CDAB^0D0B^0C0A^D0B0^C0A0 = DCBA > > Anyway, this is all just a curiosity because I don't think that's the > most efficient way to do it :^) > > At 12:36 PM 7/18/2000 +1000, you wrote: > >It looks like the way this is meant to work is that it swaps > the top and > >bottom 16 bits then proceeds to do the old 3 xor byte swapping trick > >(x^=y^=x) for each of the two 16 bit segments but I think > the code is a > >little bit broken. I can't see how that second bit works. > > > > > >-----Original Message----- > >From: brian sharon <br...@hu...> > >To: gda...@li... > ><gda...@li...> > >Date: Tuesday, 18 July 2000 12:02 > >Subject: Re: [Algorithms] Byte Swapping > > > > > >> > >>> From: Charles Bloom <cb...@cb...> > >>> > >>> Jumping in late : I'm sure you don't need it now, but > >>> here's a crazy ANSI C byte-swapper : > >>> > >>> let x = a 32 bit ulong , ABCD > >>> then y = DCBA > >>> > >>> y = (x = x>>16 | x<<16) ^ (x = (x^x>>8) & 0x00FF00FF) ^ (x<<8); > >>> > >> > >>wow, I'll say that's crazy...but unfortunately > non-functional. see the > >>results of this program: > >> > >>#include <stdio.h> > >> > >>long swap1(long x) > >>{ > >> return (x = x>>16 | x<<16) ^ (x = (x^x>>8) & > 0x00FF00FF) ^ (x<<8); > >>} > >> > >>long swap2(long x) > >>{ > >> return ((x >> 24) & 0x000000FF) > >> | ((x >> 8 ) & 0x0000FF00) > >> | ((x << 8 ) & 0x00FF0000) > >> | ((x << 24) & 0xFF000000) > >> ; > >>} > >> > >>int main(int argc, char **argv) > >>{ > >> long test = 0x01020304; > >> > >> printf("swap1: 0x%08X 0x%08X 0x%08X \n", test, swap1(test), > >>swap1(swap1(test))); > >> > >> printf("swap2: 0x%08X 0x%08X 0x%08X \n", test, swap2(test), > >>swap2(swap2(test))); > >>} > >> > >>swap1: 0x01020304 0x07000300 0x03000700 > >>swap2: 0x01020304 0x04030201 0x01020304 > >> > >> > >> > > > [snip] > |