HiveBrain v1.2.0
Get Started
← Back to all entries
patterncMinor

What an Enigma! (Machine Simulator)

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
machinesimulatorenigmawhat

Problem

I've made this some time ago for an assignment and I was wondering how it could be improved both in terms of performance and best practices for C code.

```
#include
#include

#define NR_ROTORS 3 / Number of rotors /
#define ROTORSIZE 26 / Rotor charset size /
#define INIT_CHAR 'A' / initial char /

typedef struct Rotor Rotor;

struct Rotor {
int start;
int rotatePos;
int rotateCount;
char elemts[ROTORSIZE+1];
};

void rotorInit(Rotor *r);
void reflectorInit(int reflector, char conf);
int getConf(Rotor r, int reflector, int *messages);
int calcOffset(Rotor r, int offset);
void shiftRotors(Rotor *r);
int encrypt(Rotor r, int reflector, int rotate, int offset);
int mod(int a, int b);

void rotorInit(Rotor *r){
for(int i = 0; i 0; i--) {
if (r[i].rotateCount == ROTORSIZE) {
r[i-1].start = mod(++r[i-1].start, ROTORSIZE);
r[i-1].rotateCount++;
r[i].rotateCount = 0;
}
}
}

int encrypt(Rotor r, int reflector, int rotate, int offset) {
for (int j = NR_ROTORS-1; j >= 0; j--)
offset = calcOffset(r[j], offset);
offset = reflector[offset];
for (int j = 0; j < NR_ROTORS; j++) {
for (int k = 0; k < ROTORSIZE; k++) {
if (INIT_CHAR + (mod((r[j].start+(offset)),ROTORSIZE))
== r[j].elemts[mod((r[j].start+k),ROTORSIZE)]) {
offset = k;
break;
}
}
}
return offset;
}

int mod(int a, int b) {
int r = a % b;
return r < 0 ? r + b : r;
}

int main (int argc , char* argv[]) {
Rotor rotors[NR_ROTORS];
int reflector[ROTORSIZE] = {[0 ... ROTORSIZE-1] = -1};
char initPos[NR_ROTORS+1];
int messages = 0, rotate = 0;
rotorInit(rotors);
if (getConf(rotors, reflector, &messages) == 1) {
fprintf (stderr, "Error: Bad input\n");
return 1;
}
for (int i = 0; i < messages; i++) {
initPos[NR_ROTORS] = 0;
scanf("%s\n", i

Solution

Dangerous scanf()

This code here is susceptible to buffer overruns:

char conf[ROTORSIZE+1];
scanf("%s", conf);


If the user inputs a string longer than ROTORSIZE (26), your buffer will overflow and your program may crash.

One way of avoiding the buffer overruns is to use fgets instead. You could use fgets to grab the whole line, and then you can use sscanf to parse the rotor part of the line, knowing that the line length is bounded:

#define LINESIZE 80  // Or whatever length you prefer

char line[LINESIZE];
char conf[LINESIZE];

if (fgets(line, sizeof(line), stdin) == NULL)
    return 1;
if (sscanf(line, "%s", conf) != 1)
    return 1;
if (strlen(conf) != ROTORSIZE)
    return 1;
// ...

Code Snippets

char conf[ROTORSIZE+1];
scanf("%s", conf);
#define LINESIZE 80  // Or whatever length you prefer

char line[LINESIZE];
char conf[LINESIZE];

if (fgets(line, sizeof(line), stdin) == NULL)
    return 1;
if (sscanf(line, "%s", conf) != 1)
    return 1;
if (strlen(conf) != ROTORSIZE)
    return 1;
// ...

Context

StackExchange Code Review Q#113198, answer score: 5

Revisions (0)

No revisions yet.