Search code examples
c++arrayscharxor

XORing char* Arrays


Hi guys and sry for my bad english^^ ... I tried to xor-ing some char* arrays like:

"hello" ^ "moin" ^ "servus" = xorUnit 

and xor-ing it back to the original char* arrays like:

"hello" ^ "moin" ^ xorUnit = "servus"

but the result that I got was "serv" instead of "servus", it seems like a problem with the length and hope you can help me :)

#include <iostream> 
#include <iomanip> 
#include <stdlib.h> 
#include <stdio.h> 
#include <string.h> 
#include <vector> 

using namespace std; 

struct UNIT 
{ 
    int size; 
    char *content; 
}; 

 UNIT XOR( vector<UNIT> list ) 
{ 
   char* unit; 
   char* temp; 

   UNIT xorUnit;   
   int unitLength = 0; 
   int maxLength = 0; 
   int minLength = 0; 
   int bigger = 0; 

   for( int i = 0; i < list.size(); i++ ) 
   { 
     unitLength = list[i].size; 

     if( minLength == 0 && maxLength == 0 ) 
     { 
       maxLength = unitLength; 
     } 
     else if( unitLength > maxLength ) 
     { 
       minLength = maxLength; 
       maxLength = unitLength; 
       bigger = 1; 
     } 
     else if( unitLength < maxLength ) 
     { 
       minLength = unitLength; 
       bigger = 0; 
     } 
     printf("bigger: %d\n", bigger); 
     printf("MaxLänge: %d\n", maxLength); 
     printf("MinLänge: %d\n", minLength);   

     temp = new char[maxLength]; 

     for(int j = 0; j < minLength; j++) 
     { 
       temp[j] = list[i].content[j] ^ unit[j]; 
     } 
     for(int j = minLength; j < maxLength; j++) 
     { 
       temp[j] = list[i].content[j]; 
     } 
     unit = temp; 
   } 

   xorUnit.content = unit; 
   if( bigger == 0 ) { 
     xorUnit.size = minLength; 
   } else { 
     xorUnit.size = maxLength; 
   } 
   bigger = 0; 

   return xorUnit; 
} 


int main(int argc,char **argv) {       
   int i; 

   vector<UNIT> list; 
   vector<UNIT> backupList; 

   //Eingabeunits 
   UNIT input1; 
   UNIT input2; 
   UNIT input3; 

   UNIT xorUnit;   
   UNIT output; 

   input1.size = 5; 
   input1.content = "hallo";     
   input2.size = 6; 
   input2.content = "servus";   
   input3.size = 4; 
   input3.content = "moin"; 

   list.push_back( input1 ); 
   list.push_back( input2 );   
   list.push_back( input3 );   

   for( i = 0; i < list.size(); i++ ) 
   { 
      output = list[i]; 
      printf("Vector(%d): %s %d\n", i, output.content, output.size); 
   } 

   xorUnit = XOR( list ); 
   printf("XOR: %s %d\n\n\n", xorUnit.content, xorUnit.size); 

   backupList.push_back( input3 ); 
   backupList.push_back( input1 );   
   backupList.push_back( xorUnit );   

   for( i = 0; i < backupList.size(); i++ ) 
   { 
      output = backupList[i]; 
      printf("Vector(%d): %s %d\n", i, output.content, output.size); 
   } 

   xorUnit = XOR( backupList ); 
   printf("XOR: %s %d\n", xorUnit.content, xorUnit.size); 

   return 0; 
}

Solution

  • So, it is totally not clear to me why your XOR function is so complicated. If I understand your problem correctly, the XOR function can be simply written as:

    UNIT XOR( vector<UNIT> list )
    {
        // Find the length of the longest unit
        int maxLength = 0;
        for (int i=0; i<list.size(); ++i)
            maxLength = std::max(maxLength, list[i].size);
    
        // Allocate space for the new unit.
        // Note that calloc will zero out any allocated space.
        UNIT xorUnit;
        xorUnit.size = maxLength;
        xorUnit.content = (char *) calloc(maxLength + 1, sizeof(char)); 
    
        // xor each member of the list with xorUnit
        for (int i = 0; i<list.size(); ++i)
            for (int j=0; j<list[i].size; ++j)
                xorUnit.content[j] ^= list[i].content[j];
    
        return xorUnit;
    }
    

    This produces an output of:

    Vector(0): hallo 5
    Vector(1): servus 6
    Vector(2): moin 4
    XOR: vkwts 6
    
    
    Vector(0): moin 4
    Vector(1): hallo 5
    Vector(2): vkwts 6
    XOR: servus 6
    

    Note: You are quite lucky with this example that you get printable characters back. In general, this type of code will produce lots of characters that are not considered printable characters. For example, "Hi" ^ "Ho" => "\0\9", neither of which are printable characters.