#!/bin/bash echo "鍵1の指定を数字で行ってください。" read key1 #鍵1の入力 #鍵1が26と互いに素であるか検証 k=$(( $key1 % 2 )) l=$(( $key1 % 13 )) #互いに素でなければ不適当として弾く(計算エラーを防ぐため) while [ $k = 0 ] || [ $l = 0 ] || [ $key1 -le 0 ] do echo "不適当な数字です。もう一度やり直してください。" echo "鍵1は26と互いに素な数字です。" echo "鍵1の指定を数字で行ってください。" #鍵1の入力 read key1 k=$(( $key1 % 2 )) l=$(( $key1 % 13 )) done #26と互いに素なのは2か13もしくは両方で割り切れないときである。 echo "鍵1を指定" #互いに素な鍵1を指定完了 echo "鍵2の指定を数字で行ってください" read key2 #鍵2の入力 echo "鍵2を指定" #鍵2に関して復号の際は特にエラーを吐くことがないのですべて指定可能とした。 echo "復号する暗号の入力" read affine declare -a num num=(a b c d e f g h i j k l m n o p q r s t u v w x y z ) kuri=1 owari=${#affine} >temp2.txt #numは0〜26までの数字とアルファベットを対応させる #kuriは繰り返しに利用する1〜の数字 #owariは復号する文字の文字数である。 while [[ $kuri -le $owari ]] do expr substr $affine $kuri 1 >> temp2.txt #$affineという文字の$kuri文字目をtemp2.txtに出力。繰り返すことで文字を行ずつに分けられる。$owariつまり全文字が終われば繰り返しから抜ける。 kuri=$(($kuri + 1 )) done >temp3.txt #temp2.txtから一文字ずつ$lineに入れる。 cat temp2.txt | while read line do numnum=0 until [ $line = ${num[ $numnum ]} ] do numnum=$(($numnum + 1 )) done echo "$numnum" >> temp3.txt done #入れた文字に対応する数字をnumを用いてtemp3.txtに出力。 #例えばnum[0]はaを指定する。[]内の数字を0〜26まで入れ、文字が一致したときにtemp3.txtに出力。 awk --assign awk_key2="${key2}" '{print ($1 - awk_key2)}' temp3.txt > temp4.txt #awkにシェルスクリプトの引数を渡し、復号の計算(暗号化された数字-鍵2)を解いてtemp4.txtに出力 gyaku=1 gyaku1=$(($key1 * $gyaku )) gyaku2=$(($gyaku1 % 26 )) #key1はそのままでは式に使えない。mod26での逆数となるからである。ここでkey1のmod26での逆数がgyaku2となるように計算する。 until [ $gyaku2 -eq 1 ] do gyaku=$(($gyaku + 1)) gyaku1=$(($key1 * $gyaku )) gyaku2=$(($gyaku1 % 26 )) done #逆数なので、$key1*$gyaku = 1 (mod26)となればよい。3行かけて計算している。 awk --assign awk_key1="${gyaku}" '{print ($1 * awk_key1)}' temp4.txt > temp5.txt #awkにシェルスクリプトの引数を渡し、復号の計算((暗号化された数字-鍵2)/鍵1 (mod26) )が完成。 >temp6.txt #temp5.txt(先の逆数をかけた数字列)から一文字づつ数字を$lineに入れる。 cat temp5.txt | while read line do #0より小さいときは0より大きくなるまで26を足す。 if [ $line -lt 0 ] then until [ $line -ge 0 ] do line=$(( 26 + $line )) done echo "$line" >> temp6.txt #0より大きくなった時点でその数字をtemp6.txtに出力。 #mod26で考えているので指定する文字に変化はない。 #0以上のときは26より小さくなるまで26を引く else until [ $line -lt 26 ] do line=$(( $line - 26 )) done echo "$line" >> temp6.txt #26より小さくなった時点でその数字をtemp6.txtに出力。 fi done >syuturyoku.txt #temp6.txtには複合された数字が入っている。数字を一つずつ$lineに入れる。 cat temp6.txt | while read line do echo -n ${num[$line]} >> syuturyoku.txt done #数字にしたときと逆の方法を用いている。文字はsyuturyoku.txtに改行なしに出力される。 echo `cat syuturyoku.txt` #最後に結果を出力、使用したtempファイルは破棄する。 rm temp2.txt rm temp3.txt rm temp4.txt rm temp5.txt rm temp6.txt rm syuturyoku.txt