Click here to Skip to main content
15,896,111 members
Articles / Programming Languages / C++

A Curious Economic Swap

Rate me:
Please Sign up or sign in to vote.
2.52/5 (6 votes)
30 Mar 2007CPOL2 min read 29.7K   149   10   11
A way to swap two variables of any type using the XOR operator.

Introduction

This articles has code to answer the following question: how to interchange the value between a couple of variables, of type int, without using an intermediate variable?

Beginning to think

A trivial algorithm for a swap between integer types is:

C++
/** Changes the value between two integer variables. In other words, in the end of
the function the first variable will have the second variable value and vice-versa.
*/
void normalSwap(int &first, int& second)
{

   int third = first;
   first = second;
   second = third; // first variable value into second one
}

int main()
{
   int first = 13;
   int second = 42;

   cout << "first: " << first << ", second: " << second << endl;
   normalSwap(first, second);
   cout << "first: " << first << ", second: " << second << endl;
}

Output:

first: 13, second: 42
first: 42, second: 13

One of the solutions that must exist (at least I know one) is to use the XOR operator. This binary operator has the not-so-trivial feature of keeping two bit patterns inside only one storage space. If you have one or two patterns, you get the second. Let's remember the truth table:

C++
void xorTable()
{
   cout << "XOR Table\\n---------\\n"
      << "0 XOR 0 = " << ( 0 ^ 0 ) << '\\n'
      << "1 XOR 0 = " << ( 1 ^ 0 ) << '\\n'
      << "0 XOR 1 = " << ( 0 ^ 1 ) << '\\n'
      << "1 XOR 1 = " << ( 1 ^ 1 ) << '\\n';
}

Ouput:

XOR Table
â€"â€"â€"
0 XOR 0 = 0
1 XOR 0 = 1
0 XOR 1 = 1
1 XOR 1 = 0

In other words, imagine we have values 1 and 0. Keeping both using XOR, we get 1, since:

1 (first pattern) XOR 0 (second pattern) = 1 (patterns together)

Later, we can get the first pattern using the second:

1 (patterns together) XOR 0 (second pattern) = 1 (first pattern)

In order to get the second pattern, we just have to use the first one:

1 (patterns together) XOR 1 (first pattern) = 0 (second pattern)

Use the same logic in the four possible combinations, and you will see we can always get both patterns using one of them. As the logic is a bit number independent since bit operators use one bit at a time, we can extend the technique to put together two integers, two strings, and even "two things stored in a sequence of ones and zeros":

C++
template<typename>
void universalXor(const T& first, const T& second, T& result)
{
   typedef unsigned char byte;

   const byte* pFirst = reinterpret_cast<const>( &first );
   const byte* pSecond = reinterpret_cast<const>( &second );

   byte* pResult = reinterpret_cast<byte*>( &result );

   for( size_t i = 0; i < sizeof(first) && i < sizeof(second); ++i )
      pResult[i] = pFirst[i] ^ pSecond[i];
}

That is the most basic way of symmetric-key algorithm. The first pattern has the role of the plain text, the second pattern has the role of a password, and the third one will be the obfuscated text. In order to see the plain text, we need the password.

Using the Code

The code is straightforward. The code just needs to call the function like in an ordinary swap.

C++
int main()
{
   // swaping ints
   int x = 13, y = 42;

   cout << "x: " << x << ", y: " << y << '\\n';
   universalXor(x, y, x);
   universalXor(x, y, y);
   universalXor(x, y, x);
   cout << "x: " << x << ", y: " << y << "\\n\\n";

   // swaping strings
   char str1[50] = "xor test", str2[50] = "we accept strings!";

   cout << "str1: " << str1 << ", str2: " << str2 << '\\n';
   universalXor(str1, str2, str1);
   universalXor(str1, str2, str2);
   universalXor(str1, str2, str1);
   cout << "str1: " << str1 << ", str2: " << str2 << '\\n';

   return 0;
}

Output:

x: 13, y: 42
x: 42, y: 13str1: xor test, str2: we accept strings!
str1: we accept strings!, str2: xor test

Points of Interest

I think it is worth saying that this is just a funny code technique, not a professional production code. In other words, it's a code to learn about some concepts and to use the concepts to make something more useful.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Technical Lead Intelitrader
Brazil Brazil
Wanderley Caloni
Backend Specialist
Location: São Paulo, Brazil
Email: wanderley.caloni@gmail.com
Skills
C, C++, Assembly, Windows, x86, Reverse Engineering, Cryptography, Tech/Art Writing, Debugging, Git, SQL

Experience
Intelitrader, 2015 - current (Tech Lead)
Market Data System
DataHub System
Finantial Market Vendor Projects
BitForge, 2015 - current (Owner Developer)
Appliance ATM System Security
Information Security Product Maintenance
Minor projects and skills
Communication API with HID USB devices
Windows Phone and Android user interfaces programming
Boost.Asio Winsock bug
Hidapi issue with IO pending
UOL Diveo Broker, 2012 - 2015 (Backend Developer)
Financial Market Risk System (Stock Broker)
HUB Network API Development and Maintenance
Scua Information Security, 2008 - 2012 (Security Developer)
Information Security Product Maintenance
Disk Cryptography
Team Coordination
Minor projects and skills
Hardware inventory using WMI/SMBIOS
Software inventory using Windows Registry
PrintScreen protection using COM interfaces
Windows Event Log using device driver
User/Kernel communication using DeviceIoControl API
VNC like development
PsExec like development
Documents print control using regex (boost) and shell hook
User policies management using Windows Registry and API hooks
Database migration from CTree to SQL using OLE classes
Windows authentication using DCOM service, custom GINA and Credential Provider (Windows Vista)
Database synchronization using DCOM service
Linux maintenance bootable CD, bash scripts and cryptography tools
USB Cryptography (pen drives)
Crash dump analysis using Windbg
System account process execution using COM service
MBR (Master Boot Record) customization analysing BIOS features
Blowfish and SHA-1 development in 16 bits assembly (x86)
Audit driver using shared memory between user and kernel events
Open Communications Security, 2005 - 2008 (Security Specialist)
Reverse Engineering (Trojan Analysis)
API Hooking
Antidebugging Solution
Code Ofusc

Comments and Discussions

 
QuestionHow are fast those different swap methods? Pin
V.S.31-Mar-07 6:07
V.S.31-Mar-07 6:07 
AnswerRe: How are fast those different swap methods? Pin
Wanderley Caloni31-Mar-07 12:18
professionalWanderley Caloni31-Mar-07 12:18 
AnswerRe: How are fast those different swap methods? Pin
Sergey Alexandrovich Kryukov2-Oct-12 11:33
mvaSergey Alexandrovich Kryukov2-Oct-12 11:33 
GeneralRe: How are fast those different swap methods? Pin
Wanderley Caloni3-Oct-12 2:41
professionalWanderley Caloni3-Oct-12 2:41 
GeneralRe: How are fast those different swap methods? Pin
Sergey Alexandrovich Kryukov3-Oct-12 6:19
mvaSergey Alexandrovich Kryukov3-Oct-12 6:19 
GeneralRe: How are fast those different swap methods? Pin
Wanderley Caloni3-Oct-12 7:09
professionalWanderley Caloni3-Oct-12 7:09 
GeneralRe: How are fast those different swap methods? Pin
Sergey Alexandrovich Kryukov3-Oct-12 7:48
mvaSergey Alexandrovich Kryukov3-Oct-12 7:48 
GeneralAnother method Pin
DaTxomin30-Mar-07 12:04
DaTxomin30-Mar-07 12:04 
GeneralRe: Another method Pin
Wanderley Caloni30-Mar-07 12:19
professionalWanderley Caloni30-Mar-07 12:19 
GeneralRe: Another method Pin
toxcct31-Mar-07 0:06
toxcct31-Mar-07 0:06 
GeneralRe: Another method Pin
Emilio Garavaglia31-Mar-07 3:12
Emilio Garavaglia31-Mar-07 3:12 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.