結城 浩さんの『暗号技術入門』を読んで、
「せっかくなら勉強中のJavaScriptで解こう!」と思ったので、備忘を兼ねて投稿します。
P.26 クイズ① シーザー暗号
問題内容
下記の通りです。
問題文
シーザー暗号化(※)された暗号文『PELCGBTENCUL』を解読してください。鍵は不明です。
※「abcde」を「bcdef」のようにズラしてメッセージを暗号化する方法
シーザー暗号の詳細はこちらをご参照ください。
問題を解いたコード
下記に解いたコードを載せます。やり方としては、
- 「a」〜「z」のアルファベットを文字列として格納した配列を作る
- 問題文で与えられた暗号文に存在する全文字で、「この文字はアルファベット配列の要素でいうと何番目になるか」を調べて、新しく配列を作る(もし暗号文が 'abc' だったら、[0, 1, 2]の配列を作る)
- 作成した配列の全要素に対して、「a」〜「z」の全アルファベット26回分、1つずつ後ろにずらす処理をする。(0回目:[0, 1, 2] 1回目:[1, 2, 3] ...というイメージ)
- 1つずつ後ろにずらす処理をする度に、数字の配列を元のアルファベットに戻す([0, 1, 2]なら abc、[1, 2, 3]ならbcd)
- アルファベットに戻すたびに、関数から返す配列
decryptedArray
に追加する - 「アルファベットに戻したもの」の配列を
return
する -
return
したresults
を1つずつ取り出して、コンソールに出力する
caesar.js
function convertTextToIndex(cryptedText) {
let splitted = cryptedText.split('')
return splitted.map(val => alphabets.indexOf(val))
}
function bruteForceAttack(indexArray) {
let decrypedArray = []
for (let i = 0; i < alphabets.length; i++) {
// 手順3
const shiftedIndexArray = indexArray.map(value => {
let shiftedIndex = value + i
if (shiftedIndex > alphabets.length-1) return shiftedIndex - alphabets.length
return shiftedIndex
})
// 手順4,5
decrypedArray.push(shiftedIndexArray.map(num => alphabets[num]).join(''))
}
// 手順6
return decrypedArray
}
// 手順1
const alphabets = [
'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',
];
const cryptedText = 'pelcgbtencul';
// 手順2
const indexArray = convertTextToIndex(cryptedText);
const results = bruteForceAttack(indexArray);
// 手順7
results.forEach(result => console.log(result.toUpperCase()));
分かりにくかったらすみません。
理解度が少し上がったら、もっと分かりやすく書き直します。
おかしな実装等あればビシバシご指摘いただけると嬉しいです、
よろしくお願いします。