#!/bin/bash echo "1つめの暗号鍵を入力してください" read one #1つめの暗号鍵を読み込む。 one2=`expr $one % 2` #入力された数値を2で割った余りをone2と定義する。 while [ $one = 13 -o $one2 = 0 ] #入力された数値が13もしくは偶数だった場合を条件とする。 do echo '26と互いに素である数字を入力してください' read one one2=`expr $one % 2` #入力された数値が条件を満たした場合、26と互いに素ではないため上記のメッセージを出力させ、再び数値を読み込み新しく2で割った余りを求め、条件を満たさなくなるまで繰り返す。 done echo "2つめの暗号鍵を入力してください" read two echo "複合したい6文字の暗号を入力してください" read word #もう一つの暗号鍵と復号したい6文字の暗号を入力させて読み込む。 word_num=`echo ${#word}` #入力された暗号の文字数をword_numと定義する。 while [ $word_num != 6 ] #word_numが6文字ではない時を条件とする。 do echo '入力された暗号は6文字ではありません。6文字の暗号を入力してください' read word word_num=`echo ${#word}` #6文字でない時、上記のメッセージを出力させて再び文字列を読み込み、また文字数を定義し直す。 done echo "$word" > code.txt code1=`cut -c1 code.txt` code2=`cut -c2 code.txt` code3=`cut -c3 code.txt` code4=`cut -c4 code.txt` code5=`cut -c5 code.txt` code6=`cut -c6 code.txt` #読み込んだ暗号を1つのファイルに移してから、1文字ずつcode1~code6まで定義する。 num=0 for i in {a..z} #a~zについて作業する。 do declare -a a #配列aを定義する。 a[0]="$i" a[1]="$num" #配列の1つめの要素をアルファベット、2つめの要素を数字にする。これはaなら0、bなら1、...、zなら25というように対応させていくようにしている。 echo ${a[0]} >> array$num.txt echo ${a[1]} >> array$num.txt #配列をarray(配列の数字と同じ数字).txtというファイルに、1行目が1つめの要素、2行目が2つめの要素となるよう保存していく。 num=`expr $num + 1` done #以下の作業は、アフィン暗号の暗号鍵が1つめが3、2つめが2の時に限る時の性質を使っていく。まず、xを任意の数字、yを復号前のアルファベットと対応した数字、Aを復号後の数字だとする。このとき、y=(3A+2)%26より、3A+2=26x+yつまりA=(26x+y-2)/3と表すことができる。Aが0~25となってアルファベットと対応するようになるには、yが3で割った時余りが0になる場合はx=1、余りが1になる場合はx=2、余りが2になる場合はx=0となればよい。以下はこの3つの場合に分けて作業している。 for i in 0 3 6 9 12 15 18 21 24 #25までで3で割ったとき余りが0の数字について作業する。 do A=`expr \( 26 - $two + $i \) / $one` echo $A >> array$i.txt #復号後の数字を、復号前の数字が2行目にあるファイルの3行目に書き加えている。 done for i in 1 4 7 10 13 16 19 22 25 #25までで3で割った時の余りが1の数字について、上と同じ作業をする。 do A=`expr \( 26 \* 2 - $two + $i \) / $one` echo $A >> array$i.txt done for i in 2 5 8 11 14 17 20 23 #25までで3で割った時の余りが2の数字について、上と同じ作業をする。 do A=`expr \( -$two + $i \) / $one` echo $A >> array$i.txt done for i in {0..25} do B=`awk 'NR==3 {print $1}' array$i.txt` #作成したファイルの3行目、つまり復号した後の数字をBと定義する。 C=`awk 'NR==1 {print $1}' array$B.txt` #Bが復号前の数字であるファイルの1行目のアルファベットをCと定義する。 echo "$C" >> array$i.txt #Cを作成したファイルの4行目に書き加える。以上より、各ファイルは1行目に復号前のアルファベット、2行目に復号前の数字、3行目に復号後の数字、4行目に復号後のアルファベットが保存された状態になる。 done for i in {0..25} do D=`awk 'NR==1 {print $1}' array$i.txt` #作成したファイルの1行目をDと定義する。 if [ $code1 = $D ] then E=`awk 'NR==4 {print $1}' array$i.txt` echo "$E" >> answer.txt #もしcode1がDと一致するならば、一致したファイルの4行目をEと定義してanswer.txtに書き加える。 fi done #以下は上と同じ作業をcode2~code6まで繰り返す。 for i in {0..25} do D=`awk 'NR==1 {print $1}' array$i.txt` if [ $code2 = $D ] then F=`awk 'NR==4 {print $1}' array$i.txt` echo "$F" >> answer.txt fi done for i in {0..25} do D=`awk 'NR==1 {print $1}' array$i.txt` if [ $code3 = $D ] then G=`awk 'NR==4 {print $1}' array$i.txt` echo "$G" >> answer.txt fi done for i in {0..25} do D=`awk 'NR==1 {print $1}' array$i.txt` if [ $code4 = $D ] then H=`awk 'NR==4 {print $1}' array$i.txt` echo "$H" >> answer.txt fi done for i in {0..25} do D=`awk 'NR==1 {print $1}' array$i.txt` if [ $code5 = $D ] then I=`awk 'NR==4 {print $1}' array$i.txt` echo "$I" >> answer.txt fi done for i in {0..25} do D=`awk 'NR==1 {print $1}' array$i.txt` if [ $code6 = $D ] then J=`awk 'NR==4 {print $1}' array$i.txt` echo "$J" >> answer.txt fi done #code1~code6をif文などで1つにまとめたかったが、うまくまとめて結果が表示できなかったため何度もfor文とif文を使っている。 echo "復号後の文字列 $E$F$G$H$I$J$K" #定義したE~Kは復号後のアルファベットなので、復号後の文字列を順番通りに表示する。 rm code.txt rm array* rm answer.txt #このスクリプトを実行する度にファイルの中身が追加されていき、正しい結果が表示されなくなってしまうため最後に作成したファイルを消去している。