シーザー暗号を生成するJavaScriptのサンプルコードを紹介します。
シーザー暗号とは
※実はここの説明は以前作成したVBA版と同じなのですが・・
シーザー暗号は元の文章の中の各文字を、決められた文字数分シフトして暗号文とする暗号です。
文字数のシフト数が3の場合は下記のとおりです。
平文 | 暗号文 |
---|---|
excel | buzbi |
古代ローマの軍事的指導者ガイウス・ユリウス・カエサル(英語読みでシーザー)が使用したことから、シーザー暗号と呼びます。
ただし、この暗号方式は既に解読法がわかっている暗号方式なので、遊び程度で使用するのがよろしいかと思います。
仕様
HTML形式で下記のような画面を用意し、暗号化ボタンを押下した際に、指定したシフト数分、文字が前にずれる仕様にします。
下の画像は実行結果のイメージです。
制約
- Aが入力された場合はアルファベットのZに戻り出力するというシンプルな仕様にするため、入力は全て英字に限定します。
- アルファベットAからZに戻るだけでなく、記号やスペース、ひらがなや漢字を含めたときに文字体系ごとに考慮が必要になり、コードが複雑になるのを避けるためです。
- 大文字・小文字は全て小文字に変換します。
- 大文字Aの前は小文字のzでいいのか、大文字のZでいいのかという問題が出てきます。
- カンマ、スペース、ピリオドは無視します。
ソースコード
JavaScriptで実現するのですが、実行と実行結果を見やすくするために、HTMLとCSSを含めた構成にします。
面倒な場合は、JavaScriptファイルのsetAngo()関数内にある平文、シフト数を直接設定して、暗号化を試せばよいかと思います。
HTML
ファイル名 | 文字コード |
index.html | UTF-8 |
<!DOCTYPE html>
<html>
<head>
<title>シーザー暗号</title>
<link href="./css.css" rel="stylesheet" type="text/css">
<script src="./caesar.js"></script>
</head>
<body>
<p>シーザー暗号</p>
<form action="" method="get">
<div >
<label for="shift">シフト数:</label>
<input type="text" name="shift" required value="1"></input>
</div>
<div>
<label for="hirabun">平文:</label>
<textarea name="hirabun" required>This is a pen.</textarea>
</div>
<div>
<label for="ango">暗号文:</label>
<textarea name="ango" required></textarea>
</div>
<button type="button" onClick="setAngo()">暗号化</button>
</form>
</body>
</html>
CSS
ファイル名 | 文字コード |
css.css | UTF-8 |
div {
margin-top:10px;
}
label {
vertical-align:top;
display: inline-block;
width: 100px;
}
textarea {
height:100px;
width: 200px;
}
button{
margin-top:20px;
}
JavaScript
ファイル名 | 文字コード |
caesar.js | UTF-8 |
function setAngo(){
const form = document.forms[0];
const hirabun = form.hirabun.value; // 平文取得
const shift = parseInt(form.shift.value, 10); // シフト数
form.ango.value = getCiphertext(hirabun, shift); // 暗号文設定
alert("暗号化しました");
}
function getCiphertext( planetext, shiftNum ){
let ciphertext = "";
for ( let i = 0; i < planetext.length; i ++ ) {
let char = planetext[i];
if ( char.match( /[A-Za-z, ]|\.|\r|\n/ ) ){
// 英数を小文字に変換する
char = char.toLowerCase();
} else {
// 上記以外はエラー
alert("英字以外の文字が入力されています");
return "";
}
const code = char.charCodeAt(0);
let newCharNum = 0;
if ( code >= "a".charCodeAt(0) && code <= "z".charCodeAt(0) ){
// a~zの文字を処理する
// シフト数前の値を取得する
newCharNum = code - shiftNum;
if(newCharNum < "a".charCodeAt(0)){
//a-zの範囲外の場合、a-zの文字数(26文字)を加算する
newCharNum = newCharNum + ( "z".charCodeAt(0) - "a".charCodeAt(0) + 1)
}
} else {
// a-z以外の文字はそのまま出力する
newCharNum = code;
}
// 変換後文字を結合する
ciphertext = ciphertext + String.fromCharCode(newCharNum);
}
return ciphertext;
}
テスト実行
ではテスト実行してみます。
実行前
平文は英文を入れ、シフト数は1を指定しています。
シフト数は1を指定しているため、T→s、h→g・・・と1文字ずつ前の文字にズレていくはずです。
実行後
想定通りの暗号化がされました。
参考情報
環境
下記の環境で作成・実行しております。
No. | 環境 | バージョン |
---|---|---|
1 | OS | Windows10 |
2 | ブラウザ | Google Chrome 107.0 |
以上です。
コメント