Sitzung: Jeden Freitag in der Vorlesungszeit ab 16 Uhr c. t. im MAR 0.005. In der vorlesungsfreien Zeit unregelmäßig (Jemensch da?). Macht mit!

C-Kurs/digitalesSchloesserKnacken/Musterlösung

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

unsigned int* abb;
unsigned int versuche = 0;

void generate(void);
int test(unsigned int);
char * toBin(unsigned int);
unsigned int switchBit(int,int);

int main (void)
{
 generate();
 unsigned int key = 0;
 /* ab hier kannst du versuchen die Tuer mit deinem Schluessel zuknacken.
 veraendere die Variable Key dazu mit den dir bekannten bitweisen Operatoren
 die du in der Vorlesung kennengelernt hast.
 Du kannst deinen Schluessel dann mit der Funktion test() mit deinem Schluessel
 als Parameter testen.
 */
 int i = 0;
 for(; i < 32 ; i++){/* fuer jedes Bit wird geprueft ob es Richtig ist oder ob es getaucht werden muss*/
  int rightBits  = test(key);/* Anzahl der richtigen Bits bevor das i-te Bit getauscht wurde*/
  int newRightBits = test(switchBit(key,i));/* Anzahl der richtigen Bits nachdem das i-te Bit getauscht wurde*/
  if(newRightBits > rightBits)
   key=switchBit(key,i);/* wenn die Anzahl der richtigen Bits nach dem Tausch groeßer ist als vorher ist der Schluessel mit dem getauschten bit der Neue Schluessel*/
 }
return 0;
}

/*Diese Funktion vertaucht das in whichBit uebgebene Bit in dem uebergebenen Schluessel
und liefert den so veraenderten Schluessel als Rueckgabewert*/
unsigned int switchBit(int key , int whichBit)
{
 return key ^ (1<<whichBit);
}

/* diese Funktion liefert die Anzahl der Richtigen Bits im uebergebenen Schluessel zurueck.
falls 32 zurueckgeliefert wird war der Schluessel richtig und die Tuer oeffnet sich.
*/
int test(unsigned int toTest)
{
int rightBits = 0;
int i = 0;
for(; i< 32 ; i++){
 unsigned int x = 1 << i;
 if(! ~((toTest & x) ^ (*abb| ~x))){
  rightBits++;
 }
}
if(rightBits == 32){
 printf ("\nGratulation !\n\n");
 printf ("Die Tuer ist offen.\n");
 printf ("So sahen Schluessel und Schloss aus \n");
 printf ("Schloss    : %32s \n", toBin(*abb));
 printf ("Schluessel : %32s \n", toBin(~*abb));
 exit(0);
}else{
 printf ("%3d . Versuch, %d richtige Bits \n", ++versuche, rightBits);
 return rightBits;
}
}

/*Hier wird das zufaellige Schloss generiert. Bitte nicht veraendern sonst geht der Spaß verloren. */
void generate(void)
{
 printf ("\nSchloss wurde erstellt.\nViel Spass beim probieren.\n\n");
 unsigned int secret;
 abb = (unsigned int*) malloc (1);
 srand ( time(NULL) );
 secret = rand();
 *abb = secret;
}

/*Konvertierungsfunktion zur Ausgabe der Binaerrepraesentation einer Zahl*/
char * toBin(unsigned int num)
{
 static char retbuf[33];
 int i =0;
 for(; i<33 ; i++){
  retbuf[i]='0';
 }
 char *p;
 p = &retbuf[sizeof(retbuf)-1];
 *p = '\0';
 do {
  *--p = "0123456789abcdef"[num % 2];
  num /= 2;
 } while(num != 0);
 return retbuf;
}