【高校情報】大学入学共通テスト対策 試作問題 第5問解説 プログラミング 擬似言語を使ったシーザー暗号(大学入試センター2020年12月発表)
共通テスト「情報」試作問題 第5問解説 プログラミング 擬似言語
※以前解説しましたが、更に分かりやすくリメイクしました※
【資料ダウンロード】
PDFの他、パワーポイント、学習指導案 等の原本も無料提供しています。
情報教育の底上げが目的なので、資料を修正して、学校・塾(営利目的含む)の授業等で利用して頂いて問題ありません。私への連絡不要ですが、利用する際には、YouTubeチャンネル・情報Ⅰ動画教科書・IT用語動画辞典を紹介してもらえると嬉しいです。
■独自解説パワーポイント
https://toppakou.com/info1/download/98_大学入学共通テスト/2020試作問題/情報大学入学共通テスト対策【202012試作問題_大問5】.pptx
■試作問題ダウンロード
大学入試センター・情報処理学会
https://www.ipsj.or.jp/education/9faeag0000012a50-att/sanko2.pdf
【文字おこし】
大学入学共通テスト 情報対策講座
今回は大学入試センターが2020年12月に発表している、大学入学共通テスト
情報の試作問題の内、大問5の擬似言語・プログラミング問題の解説をしていきます。
簡単な暗号化方法のシーザー暗号に関するプログラミング問題になります。
事前知識として文字列シフトについて説明します。
シフト暗号はアルファベットを文字数分シフトつまりずらして置換えるきわめて単純な暗号手段になります。
小文字のアルファベット順にaからzまで並んだ配列があるとします。
今回は、配列番号(添字)は0番から割りふります。
右にずらすことを右シフト、左にずらすことを左シフトといいます。
右に5文字分シフトしていきます。
たとえば文字「a」を5文字右にシフトした場合 fが対応します。
文字xの場合はまず2文字シフトして右に到達した後、一番左端にもどり3文字シフトした文字cに置き変わります。
他の文字も同じように対応付けするとこの図の様なイメージになります。
暗号化された文字列を復号したい場合は、今行った行為と逆で5文字左にシフトします。
問題を解くうえで注意する点(混同しやすい点)
配列番号は0番から始まります。
ただ、文字数としては1から数えます。
配列番号なのか、文字数で答えるのかを注意する必要があります。
では、今話した知識をベースに問題を解いて行きましょう。
Tさん 復号は必ずしも反対にシフトする必要はないよね。
たとえば9文字右にシフトされていた場合、復号するには9文字左にシフトしても良いけど、右に 空欄アイシフトすることもできるね とあります。
これは時計に置き換えると分かりやすいと思います。
12の数字を右回りに 3つシフトすると 3の位置になります
左側に9つシフトしても同じ3の位置になります。
これを計算式であらわすと
左シフト数= 12(全体数)-3(右シフト数) となります。
これを今回の問題に当てはめると
全体数はアルファベットの文字数 26
左シフト数 9 なので
右シフト数 = 26(全体数)-9(左シフト数) =17
となり アイ は17となります。
―――
次の空欄を見ていきましょう。
図2のようにアルファベットに0~25の番号を割り当てて考えてみると、暗号化してx番目の文字になった時、復号はx+17の値が 空欄ウエ以下であれば x+17番目の文字に置き変わるけど、空欄ウエより大きい場合は、x+17―空欄オカの文字に置き変われば復号できるよね。
とあります。
――
たとえば、bの文字を右に9文字シフトして暗号化した、配列番号:1番のkの文字を復号する場合で考えていきましょう。先ほどの右シフトによる複合方法では、17文字右シフトすれば bに復号できます。
配列番号では今の配列番号1+17で 配列番号18の bが対応することが分かります。
ただ、tを暗号化したc(配列番号:19)を復号するためには
19+17 で 36 となり、桁あふれをおこします。
配列番号が25より大きくなってしまう場合は、26を引く必要があります。
この例だと19+17-26で配列番号10が復号後の文字tということが分かります。
はじめに説明したように最後尾の配列番号25番まで来たら配列番号0番になります。
なので 復号はx+17の値が、25以下(ウエの答え、配列番号)以下であれば、x+17番の文字に置き変えることができます。 よって空欄ウエは25になります。
ただ、25より大きい場合は、配列の始めの番号0番にする必要があるので、26を引く必要があります。
よってx+17-26(オカの答え)となります。
空欄オカは26が入ります。
では、次の空欄を見ていきましょう。
Mさんが 暗号化で文字を何文字シフトしているか分かれば、この復号法で解読できるよね。どうやったら分かるかな。
Tさんは すべての可能性、つまりシフトしない時を除いた 空欄キク通りをプログラムで試せればいいんじゃない?
とあります。
アルファベットは全部で26文字あって「シフトしない時を除いた」とあるので
この図のようにずらす文字数を1ずつ増やしていくイメージになります。
全文字数の26 ― シフトしない場合の1通りをマイナスして、 25通りとなります。
―――
ただ、この方法だと問題があることをMさんから指摘されます。
大文字があったり、日本語のように文字種の数が多い言語ではとても効率が悪いこと。
そして、一般的な英文のアルファベットの出現頻度にはこの図3の様な傾向があることで、出現頻度を調べれば、何文字シフトされているかを推測することができる可能性があるということです。
それを確認するのが問2になります。
Tさんは、暗号化された英文のアルファベットの出現頻度を数え上げる図5のプログラムを考えました。
そしてそのプログラムでは配列変数Angoubunに暗号文を入れて、1文字ずつアルファベットの出現頻度を数え上げて、その結果を配列変数Hindoに入れているとあります。
例えば a の文字が 32回 zの文字が11回 出現した場合は
aは配列番号(添字) 0なので Hindo[0] = 32
zは配列番号が25なので Hindo[25] = 11 となります。
目的は Angoubun 配列に存在する文字の 出現頻度を求めて Hindo 配列の該当配列番号の部位を更新していくことになります。
1行目から説明していきます。
Angoubun配列に解読したい文字列をいれています。
「Angoubun」というローマ字から「暗号文」を入れるんだな~という推測ができます。
Hindo配列の初期化になります。すべて0にします。
3行目から6行目は
Angoubun配列数分 4行目から6行目の処理を繰り返します。
-1しているのは配列番号が0番から始まるから 要素数の数えは1からなのでつじつまを合わせています。
差分関数は 空欄ケ に入れられたアルファベットの位置を返し それをbangou変数に格納しています。
暗号文の要素数分ループを回していて、ここは Angoubunの文字を一文字ずつ判定 して Hindo配列の該当部分を加算しています。
差分( )のカッコ内に入れれるものはアルファベットなので Angoubunの中身を取り出してあげないといけません。
何番目の配列を取り出すかは0から始まるループ回数と等しいので
空欄ケはAngoubun[i] となります。
例えば Angoubun配列の配列番号5に「z」の文字が出てきた場合
差分(Angoubun[5])は 25を返却し bangouに 25を格納します。
5行目は変数 bangouの値がー1でなければという意味になります。―1はアルファベット以外を意味するので、言い換えると アルファベットなら6行目の処理を行います。
今回のHindoのカウント対象なら、06の処理に入ります。
6行目について、アルファベットはカウント対象なのでHindo配列を更新する処理になります。
ループなので今までカウントした数字がHindo配列に入っている可能性があります。
なので今のカウント値に+1する必要があります。
bangouが更新対象の文字配列の場所に等しいので
更新対象の配列番号は Hindo[bangou] (コの答え) となります。
このプログラムを実行してHindo配列をグラフ化したものが図6になります。
これは一般的な出現頻度をもとにした図3と比較すると 答えが導けます。
どれくらい右にシフトすると図3と図6のグラフの形が近くなるかで復号するシフト値の推測をしています。
図3のabcdeの形と図6のklmnoの形が非常に似ているので
10(サシの答え) 右にシフトしていると推測します。
次に問3を解説していきます。
図7は暗号文を1文字ずつ復号して表示するプログラムになります。
空欄サシと空欄ケは先ほどの問2で答えが分かっているので埋めています。
1行目は Angoubun配列の定義 で 変数名の通り暗号化されている文字列を配列として定義しています。
2行目で 中身は空っぽの配列変数Hirabunを定義します。
暗号文を復号した値が入ります。
3行目の変数hukugousuuはシフトする文字数を格納しています。
問2より空欄サシは10なのfukugousuuには16が代入されます。
4行目がループ条件でループ回数としてはAngoubun配列の要素数分12行目までの処理を繰り返します。
先ほど説明したように、配列番号は0から始まり、要素数は1から数えるので、つじつま合わせでー1しています。
空欄ケ は 問2 より Angoubun[i] がはいります。
ここで平文に戻すため 暗号文配列より1文字が取り出されます。
それを 差分関数にいれています。
差分関数はアルファベットの「a」との位置の差分を返します。
6行目から12行目は問1で説明した内容になります。
bangou != -1 なので アルファベットならばと言い換えられる
8行目で 文字(ス)をHirabunに入れていることから スは復号後のアルファベットの位置を表す配列番号だと考えられる
今の暗号化されている配列番号+復号の為のシフト値となるので
bangou+hukugousuu がスの答えとなる。
配列番号が25を超えるパターンは問1で説明済
配列の0番目に戻す必要があるので
bangou+hukugousuu -26 になる
12行目は、アルファベットでない場合の処理になり、暗号文の内容はそのまま使うので
つまり Angoubun[i]になります。
13行目でHirabun配列の中身をまとめて表示します。
つぎはプログラムの簡略化について
7行目から10行目の内容を1行にするにはどうしたら良いかの会話になります。
abcde.......xyz で配列で
復号後の配列番号を基準に
26で左端に戻るということは、26を超えたものから配列番号0、1・・と数えます。
これは、シフト後の配列番号を26で割った余りを使うことで可能となります。
(暗号化された配列の位置+復号数)%26 となる
変数に置き換えると
(bangou+hukugousuu)%26 となります。
このかっこが無いと復号数%26の計算が優先されてしまうので注意しましょう。
以上
【参考サイト・参考文献】
問題ダウンロード(情報処理学会)
https://www.ipsj.or.jp/education/9faeag0000012a50-att/sanko2.pdf
高等学校「情報Ⅰ」:共通テスト試作問題を検討する|E.V.ジュニア|note
【YouTubeチャンネル】
【IT用語動画辞典】
【解説重要用語】
擬似言語、変数、配列
★私の目標
「とある男が授業をしてみた」 の葉一さん
https://www.youtube.com/user/toaruotokohaichi
※Google社に招待頂いた、「YouTube教育クリエイターサミット2020」で
葉一さんと文部科学省・Google役員の対談セッションに感銘を受けて、高校情報講座スタートしています。
この記事が気に入ったらサポートをしてみませんか?