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 <stdio.h>
#include <string.h>
#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 < NR_ROTORS; i++) {
        r[i].start = 0;
        r[i].rotatePos = 0;
        r[i].rotateCount = 0;   
    }
}
void reflectorInit(int *reflector, char *conf) {
    for(int i = 0; i < ROTORSIZE; i++) {
        for(int j = 0; j < ROTORSIZE; j++) {
            if (conf[i] == conf[j] && reflector[i] == -1 && i!=j) {
                reflector[i] = j;
                reflector[j] = i;
                break;
            }
        }
    }
}
int getConf(Rotor *r, int *reflector, int *messages) {
    for(int i = 0; i < NR_ROTORS; i++) {
        scanf("%s %d", r[i].elemts , &r[i].rotatePos);
        if (strlen(r[i].elemts) != ROTORSIZE)
            return 1;
    }
    char conf[ROTORSIZE+1];
    scanf("%s", conf);
    reflectorInit(reflector, conf);
    scanf("%d", messages);
    if (strlen(conf) != ROTORSIZE || *messages < 0)
            return 1;
    return 0;
}
int calcOffset(Rotor r, int offset) {
    return mod(offset + r.elemts[mod((r.start+offset),ROTORSIZE)] - 
           (INIT_CHAR + mod((r.start+offset),ROTORSIZE)),ROTORSIZE);    
}
void shiftRotors(Rotor *r) {
    r[NR_ROTORS-1].start = mod(++r[NR_ROTORS-1].start, ROTORSIZE);
    r[NR_ROTORS-1].rotateCount++;
    for (int i = NR_ROTORS-1; 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", initPos);
        if (initPos[NR_ROTORS] != '*')
            rotate = 1;
        else rotate = 0;
        for(int j = 0; j < NR_ROTORS; j++) {
            rotors[j].start = initPos[j] - INIT_CHAR;
            rotors[j].rotateCount = ROTORSIZE - 
                (rotors[j].rotatePos - rotors[j].start+1);
            rotors[j].rotateCount = mod(rotors[j].rotateCount, 
                            ROTORSIZE);
        }
        int offset = 0;
        char c = fgetc(stdin);
        while (c != '\n') {
            if (rotate == 1) 
                shiftRotors(rotors);
            offset = c - INIT_CHAR; 
            printf("%c",INIT_CHAR
                + encrypt(rotors, reflector, rotate, offset));
            c = fgetc(stdin);
        }
        printf("\n");
    }
    return 0;
}
In order to run the program you need to give it an initial rotor and reflector configurations. Input example:
EKMFLGDQVZNTOWYHXUSPAIBRCJ 16
AJDKSIRUXBLHWTMCQGZNPYFVOE 4
BDFHJLCPRTXVZNYEIWGAKMUSQO 21
ABCDEFGDIJKGMKMIEBFTCVVJAT
2
MCK
QMJIDOMZWZJFJR
ABC
ENCRYPTTHISMESSAGE
- The first 3 lines define the rotor configuration. The integer denotes the position in which the rotor causes the rotation of next rotor.
- Fourth line defines the reflector configuration.
- The fifth line is the number of messages you want to encrypt/decrypt
- Sixth line is the initial position (letter) of each rotor
- Seventh line is the actual message you want to encrypt/decrypt
Repeat six and seven depending on your input in the fifth line.


