シーザー暗号の実装

はじめに

暗号技術のすべてという本を購入しました。
そこでシーザー暗号が出てきたので改めて実装してみることにしました。

シーザー暗号とは

シーザー暗号とは、アルファベットの先頭文字を指定したROT分だけずらす暗号方式のことです。
ABCのROT1なら、BCDとなります。ずらした結果がZを超えてしまった場合はAに戻ります。
ちなみにアルファベットは26文字なのでROT13だと二回暗号化を行うと実質復号になるという性質も持ちます。(Aの13文字ずらしはNであり、Nの13文字ずらしはAだからです)


では、実装したコードを載せます

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>

#define CASELEN 26

char case_u[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char case_l[] = "abcdefghijklmnopqrstuvwxyz";

int str_check(char character) {
  for (int i = 0; i < CASELEN; i++) {
    if (character == case_u[i])
      return 1;
  }
  
  return 0;
}
  
   
void encryption(char str[], int length, int rot) {
  for (int i = 0; i < length; i++) {
    str[i] = toupper(str[i]);
  }
  for (int i = 0; i < length; i++) {
    if (str_check(str[i])) {
      printf("%c", case_u[(str[i]-'A'+rot)%CASELEN]);
    } else {
      printf("%c", str[i]);
    }
  }
}

int main(void) {
  char str[256];
  int rot;

  printf("文字列>");
  fgets(str, sizeof str, stdin);

  printf("ROT >");
  scanf("%d", &rot);

  encryption(str, strlen(str), rot);

  return 0;

}

str_check関数はアルファベットなのかそれ以外(記号や数字)なのかを判定する関数です。
それを用いてencryption関数ではアルファベットなら文字をずらして表示し、そうでないならそのまま表示するようにします。
暗号的には、空白もピリオドも暗号化した方が良いのでしょうが、今回は結果がわかりやすいことを重視してこの実装にしました。
scanfで空白文字が入力できないのを忘れていて少し焦ったのですがfgetsを使うことで実装できました。
ということで、実行結果を示します。

f:id:kisaragi211:20190221175432p:plain    f:id:kisaragi211:20190221175436p:plain

ROT13なので2回の実行で元どおりになりました。

おわりに

シーザー暗号は理解しやすい暗号なので初学者の私でもとても面白かったです。
暗号技術のすべてには、まだまだ色々な暗号方式が載っているみたいなのでインプット頑張ろうと思います。
理解できた範囲でアウトプットも行なっていこうと思います。