⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 enigma.c

📁 《应用密码学》协议、算法与C原程序(第二版)配套源码。很多人都需要的
💻 C
字号:
/* * engima simulation *  * author: Henry Tieman *  * references:  *     "How Polish Mathematicians Deciphered the Enigma", Marian Rejewski, *     Annals of the History of Computing, Vol 3, no 3, July 1981, Pg 213 ff *     appendix by C. A. Devours. * *     "Machine Cryptography and Modern Cryptanalysis", C.A. Deavours and L. *     Kurth, Artech House, Dedham, Mass 1985. */#include <stdio.h>#include <ctype.h>#ifndef TRUE#define TRUE  1#define FALSE 0#endif#define LINE_LEN 80/* * rotor data *       reference "Machine Cryptography and Modern Cryptanalysis" pg. 100 * * note: rotor stepping is associated with each @PROGCODE = rotor instead *       of position or being constant. */#define NUM_ROTORS 5char ref_rotor[27] = "YRUHQSLDPXNGOKMIEBFZCWVJAT";char rotor[NUM_ROTORS][27] = { /* pre defined rotors */  "EKMFLGDQVZNTOWYHXUSPAIBRCJ",  "AJDKSIRUXBLHWTMCQGZNPYFVOE",  "BDFHJLCPRTXVZNYEIWGAKMUSQO",  "ESOVPZJAYQUIRHXLNFTGKDCMWB",  "VZBRGITYUPSDNHLXAWMJQOFECK",};int step_data[NUM_ROTORS] = {  16,  4, 21,  9, 25           /* steps at: q, e, v, j, z */};/*  * engima key default settings */int order[3] = { 0, 1, 2};     /* rotor order, user input is +1 */char ring[8] = {               /* ring settings */  '\0', 'A',  'A',  'A',       /* default: AAA */  '\0', '\0', '\0', '\0' };int n_plugs = 0;               /* number of plugs */char plugs[80] = "";           /* plug string */int pos[3] = { 0, 0, 0 };      /* rotor positions *//* * simulation data and machine state data  */int data[8][26];               /* working array for machine */int step[3];                   /* steps corresponding to rotors */int double_step;               /* rotor 2 step twice *//* * encipher - C implementation of the engima cipher function */intencipher(int c){  int j;                        /* index for counting */  int idx;                      /* rotor index */  if (isalpha(c))    {      pos[0] = (pos[0] + 1) % 26;  /* first, advances the rotors */      if (pos[0] == step[0])        pos[1] = (pos[1] + 1) % 26;      if (double_step)        {          pos[1] = (pos[1] + 1) % 26;          pos[2] = (pos[2] + 1) % 26;          double_step = FALSE;        }      if (pos[1] == step[1])        double_step = TRUE;      c -= 'A';                 /* start to encipher */      if (n_plugs != 0)        c = data[0][c];      for (j=0;j<3;j++)         /* do rotors forward */        {          idx = (c + pos[j]) % 26;          c   = (c + data[j+1][idx]) % 26;        }      c = (data[4][c]) % 26;    /* reflecting rotor */      for (j=0;j<3;j++)         /* do rotors reverse */        {          idx = (c + pos[2-j]) % 26;          c   = (c + data[j+5][idx]) % 26;        }      if (n_plugs != 0)        c = data[0][c];      c += 'A';    }  return(c);}/* * encipher_file - open and encipher a file */voidencipher_file(char *file_name){  FILE *fp;                     /* plaintext/ciphertext FILE pointer */  char line[LINE_LEN + 1];      /* input data line, inc. '\n' */  char *ret_val;                /* value from fgets(), used for EOF check */  char c;                       /* character from data line */  int len;                      /* length of data line */  int idx;                      /* index/counter */  fp = fopen(file_name, "r");  ret_val = fgets(line, LINE_LEN, fp);  while(ret_val != NULL)    {      len = strlen(line);      for (idx=0;idx<len;idx++)        {          c = line[idx];          if (isalpha(c))            {              c = encipher((int)(toupper(c)));              line[idx] = c;            }        }      printf("%s", line);      ret_val = fgets(line, LINE_LEN, fp);    }  fclose(fp);}/* * init_mach - set up data according to the input data */voidinit_mach( void ){  int i, j;                      /* indexes */  int ds;                        /* used during ring settings */  int u, v;                      /* temps for plugboard input */  /* setup rotor data */  for (j=0;j<26;j++)    data[4][j] = ((int)ref_rotor[j]-'A'+26)%26;  for (i=1;i<4;i++)    {      step[i-1] = step_data[order[i-1]];      for (j=0;j<26;j++)        {          data[i][j] = ((int)(rotor[order[i-1]][j])-'A' + 26) % 26;          data[8-i][data[i][j]] = j;        }    }  /* setup ring settings */  ring[7] = ring[1];  ring[6] = ring[2];  ring[5] = ring[3];  for (i=1;i<8;i++)    if (i != 4)      {        ds = (int)(ring[i]) - 'A';        if (ds != 0)          {            for (j=0;j<26;j++)              data[0][j] = data[i][j];            for (j=0;j<26;j++)              data[i][j] = data[0][(26-ds+j)%26];          }      }  /* setup plug data */  if (n_plugs != 0)    {      j = 0;      for (i=0;i<26;i++)        data[0][i] = i;      for (i=0;i<n_plugs;i++)        {          while (!isalpha(plugs[j]))            {              j++;              if (plugs[j] == '\0')                break;            }          u = toupper(plugs[j++]) - 'A';          v = toupper(plugs[j++]) - 'A';          data[0][u] = v;          data[0][u] = u;        }    }  /* convert all moving rotor data to displacements */  for (i=1;i<8;i++)    {      if (i!=4)        for (j=0;j<26;j++)          data[i][j] = (data[i][j] - j + 26) % 26;    }  /* setup rotor starting positions */  double_step = FALSE;              /* no previous rotor position */  /* input function has already done the rotor positions */}/*  * read_keyfile - a simple function to read in the key file  */voidread_keyfile( char *str ){  FILE *kf;                         /* input key FILE pointer */  int num;                          /* dummy returned from fscanf() */  int idx;                          /* index/counter */  char a[3];                        /* dummy for input */  kf = fopen(str, "r");  num = fscanf(kf, "%d %d %d\n", &order[0], &order[1], &order[2]);  num = fscanf(kf, "%c %c %c\n", &ring[1], &ring[2], &ring[3]);  num = fscanf(kf, "%d\n", &n_plugs);  if (n_plugs != 0)    num = fscanf(kf, "%[^\n]\n", plugs);  num = fscanf(kf, "%c %c %c\n", &a[0], &a[1], &a[2]);  for (idx = 0; idx < 3; idx++)    {      (order[idx])--;      ring[idx+1] = toupper(ring[idx+1]);      pos[idx] = toupper(a[idx]) - 'A';    }  fclose(kf);}/* * usage - function to print out the correct usage of the program */voidusage( char *str ){  fprintf(stderr, "usage: %s [<keyfile>] <infile>\n\n", str);  fprintf(stderr, "\tkeyfile has the form:\n");  fprintf(stderr, "\t\tn n n\t\t- for rotor order, 1 <= n <= 5\n");  fprintf(stderr, "\t\tx x x\t\t- for ring settings, x alpha\n");  fprintf(stderr, "\t\tn\t\t- number of plugs, 0 <= n <= 13\n");  fprintf(stderr, "\t\txx xx xx ...\t- plug letter pairs, one pair"          " for each n\n");  fprintf(stderr, "\t\tx x x\t\t- initial rotor position, x alpha\n\n");  fprintf(stderr, "\toutput is stdout\n");  exit(0);}/* * main - the main function, nothing special here */voidmain( int argc, char ** argv ){  char *infile;            /* plaintext/ciphertext file name ptr */  if ((argc < 2) || (argc > 3))    usage(argv[0]);  if (argc == 2)    {      infile = argv[1];    }  else    {      infile = argv[2];      read_keyfile(argv[1]);    }  init_mach();  encipher_file(infile);}/* * end of engima simulation */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -