以下のように、置換暗号を実装するプログラムを実装します。
$ ./substitution JTREKYAVOGDXPSNCUIZLFBMWHQ
plaintext: HELLO
ciphertext: VKXXN
背景
置換暗号では、すべての文字を別の文字に置き換えることによってメッセージを暗号化 (すなわち、可逆的な方法で隠す) します。そのために、キーを使います。この場合、アルファベットの各文字と、暗号化するときに対応する文字との対応付けです。メッセージを 「復号化」 するには、メッセージの受信者が鍵を知っている必要があります。そうすれば、暗号化されたテキスト (一般に暗号文と呼ばれます) を元のメッセージ (一般に平文と呼ばれます) に翻訳し直すという、逆のプロセスが可能になります。
たとえば、キーは文字列NQXPOMAFTRHLZGECYJIUWSKDVB
です。この26文字のキーは、A
(アルファベットの最初の文字) をN
(キーの最初の文字) に、B
(アルファベットの2番目の文字) をQ
(キーの2番目の文字) に変換する必要があることを意味します。
HELLO
のようなメッセージはFOLLE
として暗号化され、キーによって決定されたマッピングに従って各文字を置き換えます。
置換暗号を使用してメッセージを暗号化できるsubstitution
と呼ばれるプログラムを作成しましょう。ユーザはプログラムを実行するときに、コマンドライン引数を指定して、実行時に提供する秘密メッセージ内のキーを決定する必要があります。
プログラムの動作例をいくつか示します。たとえば、ユーザがYTNSHKVEFXRBAUQZCLWDMIPGJO
というキーとHELLO
というプレーンテキストを入力したとします。
$ ./substitution YTNSHKVEFXRBAUQZCLWDMIPGJO
plaintext: HELLO
ciphertext: EHBBQ
ユーザがVCHPRZGJNTLSKFBDQWAXEUYMOI
のキーとhello, world
のプレーンテキストを入力すると、プログラムは次のように動作します。
$ ./substitution VCHPRZGJNTLSKFBDQWAXEUYMOI
plaintext: hello, world
ciphertext: jrssb, ybwsp
カンマもスペースも暗号で置換されていないことに注意してください。アルファベット文字のみを置換します。また、元のメッセージの大文字と小文字が保持されていることにも注意してください。小文字は小文字のまま、大文字は大文字のままです。
キー自体の文字が大文字か小文字かは関係ありません。VCHPRZGJNTLSKFBDQWAXEUYMOI
のキーは、機能的にはvchprzgjntlskfbdqwaxeuymoi
(あるいはVcHpRzGjNtLsKfBdQwAxEuYmOi
など) のキーと同じです。
また、ユーザが有効なキーを指定しなかった場合はどうなりますか。
$ ./substitution ABC
Key must contain 26 characters.
ユーザが全く指示に従っていない場合はどうでしょう。
$ ./substitution
Usage: ./substitution key
または…
$ ./substitution 1 2 3
Usage: ./substitution key
試してみましょう
スタッフによるこの問題の実装をテストするには、次のコマンドを実行します。
./substitution key
このサンドボックス内で、keyの代わりに有効な整数を代入します。
Specification仕様
置換暗号を使用してメッセージを暗号化するプログラムsubstitution
を設計および実装します。
- プログラムを
substitution.c
という名前のファイルでsubstitution
という名前のディレクトリに実装します。 - プログラムは、置換に使用するキーである単一のコマンドライン引数を受け入れる必要があります。キー自体は大文字と小文字を区別しないようにする必要があるため、キー内の文字が大文字であるか小文字であるかは、プログラムの動作に影響しません。
- プログラムをコマンドライン引数なしで、または複数のコマンドライン引数を指定して実行した場合、プログラムは選択したエラーメッセージ (
printf
で) を出力し、main
から値1
(エラーを示す) をすぐに返します。 - キーが無効な場合 (たとえば、26文字を含まない、アルファベット以外の文字を含む、または各文字を一度だけ含まない)、プログラムは決められたエラーメッセージを (
printf
を使って) 出力し、すぐにmain
から値1
を返します。 - プログラムは (改行なしの)
plaintext:
を出力し、ユーザに (get_string
を使って) プレーンテキストのstring
を要求しなければなりません。 - プログラムは、(改行なしで)
ciphertext:
として平文に対応する暗号文を出力しなければなりません。平文中のそれぞれのアルファベット文字は、暗号文中の対応する文字に置き換えられます。アルファベット以外の文字はそのまま出力されます。 - プログラムは大文字/小文字を保持する必要があります。大文字は大文字のまま、小文字は小文字のままにしておく必要があります。
- 暗号文を出力した後、改行を出力する必要があります。プログラムは
main
に0
を返して終了するはずです。
ウォークスルー
コードのテスト方法
check50
を使用して以下を実行し、コードの正確さを評価してください。ただし、コンパイルとテストは必ず自分で行ってください。
check50 cs50/problems/2021/x/substitution
以下を実行し、style50
を使用してコードのスタイルを評価します。
style50 substitution.c
提出方法
次のコマンドを実行し、GitHubのユーザ名とパスワードを入力してログインします。セキュリティのため、パスワードには実際の文字ではなくアスタリスク (*
) が表示されます。
submit50 cs50/problems/2021/x/substitution