[Piet]ヴィジュネル暗号プログラム(その1)
前回に引き続き暗号化プログラムの作成をします。 今回扱うのはヴィジュネル暗号です。
ヴィジュネル暗号とは
今回も前回同様、英語(アルファベット)の文章を暗号化することが前提です。
前回のカエサル暗号は、平文(暗号化前の文章)の各文字を、アルファベット順にある文字数だけずらして暗号文を作りました。
この暗号には弱点があり、つまりずらす文字数のパターンが25通りしかありません。したがって、25通り総当たりで文字をずらしてみれば、あっさり平文が見つかることになります。
この弱点を改善したのが「ヴィジュネル暗号」です。 ヴィジュネル暗号は平文を1文字暗号化するごとに、ずらす文字数を変えていきます。
たとえば、「I have a pen.」という平文を暗号化します。 暗号化は"I"→"h"→"a"→"v"→"e"→...の順に行いますが、 ずらし方を、たとえば3文字、14文字、6文字の順に変えていくとします。
- "I"は3文字ずらすとして、"L"に
- "h"は14文字ずらして"v"に
- "a"は6文字ずらして"g"に
- "v"は再び3文字ずらして"y"に
- ...
1文字だけ見ればシーザー暗号と変わらず25通りの変換しかできませんが、 3文字置きにずらし方を変えていくと、25の3乗の15625通りの暗号化ができるようになります。 さらに、3文字置きではなく、5文字置き、10文字置きなど、 ずらし方は自由ですので、暗号化のパターンはさらに増えます。
ずらす文字数を数字で覚えておくのは大変なので、しばしばアルファベットで記憶する方法がとられます。 ずらす文字数が0文字なら”a”、1文字なら"b"のように数値を変換すると、 上の例の場合はずらす文字数が"dog"のようにまとめられ、簡単に記憶することができます。
このように、暗号化のヒントになる"dog"のような文字列を暗号化の「鍵」と言います。
先ほどの例で全ての文字を暗号化すると、次のようになります。
平文 | 鍵文字 | ずらす文字数 | 暗号文 |
---|---|---|---|
I | d | 3 | L |
h | o | 14 | v |
a | g | 6 | g |
v | d | 3 | y |
e | o | 14 | s |
a | g | 6 | g |
p | d | 3 | s |
e | o | 14 | s |
n | g | 6 | t |
結局"I have a pen."は"L vgys g sst."と暗号化されます。
ヴィジュネル暗号を実装する
仕様
それではPietで実装していきます。仕様は次のようにしました。
- 入力:「平文.鍵.」のように、平文と鍵をピリオド( . )で区切って入力
- 平文:使用可能な文字は、半角英数字(ピリオド除く)
- 鍵:使用可能な文字は半角英字のみ
上の例なら"I have a pen.dog."と入力すれば暗号化できます。
入力に関する補足(クリックして開く)
- 平文にピリオドは使用不可(平文終了の目印になるため)
- 平文の英字以外はそのまま出力し、鍵文字を更新しない
- 平文には大文字・小文字いずれも使用可能
- 鍵には大文字・小文字いずれも使用可能
2については、 たとえば上記の"I have a pen"のスペースを消したり英字以外の記号を入れて "#Ihave!a pen"とすると、"#Lvgys!g sst"となります。 記号はそのまま出力されますが、 "have"が"vgys"に、"pen"が"sst"に変換されるなど、平文のアルファベット部分の暗号化の結果は変わりません。
3については、 入力を"I HAVE A PEN"とすると、出力は"L VGYS G SST"となります。 入力を大文字にすると出力も大文字になりますが、暗号文は変化しません。
4については、 鍵の"dog"を"DOG"や"Dog"にしても、"I have a pen"は"L vgys g sst"に暗号化されます。 (大文字・小文字も変わりません。)
処理の流れ
処理の流れはおおよそ次のようにしました。
- 平文と鍵を入力する
- ★ループ開始地点
- 平文から暗号化する文字を取り出す(全て暗号化済みなら終了)
- 鍵から暗号化に使う文字を取り出す
- 平文の文字が英字以外ならそのまま出力して★ループ開始地点へ戻る
- 鍵の文字がアルファベット順で何番目か調べる(K番目とする)
- 平文の文字をK文字アルファベット順にずらして出力する
- 暗号化に使う鍵文字の位置を1文字ずらす
- ★ループ開始地点に戻る
この処理をPietソースコード生成用のコードで記述すると、次のようになります。 命令397個と、かなり長くなったので、興味のある方は開いてみてください。
処理コード(クリックして開く)
goto:inputPlain #------------------------------ :fInput push1 dup sub push3 push1 roll :fInput_loop inc push3 push2 roll dup push4 push1 roll if:fInput_isOK:fInput_push :fInput_push dup push3 push2 roll dup push4 push1 roll push5 add push1 roll push4 push3 roll push1 add push4 push1 roll :fInput_isEnd push2 push2 push1 roll goto:fIsPeriod :fInput_isEnd_retIsPeriod pop if:retInput: pop goto:fInput_loop :fInput_isOK push1 push2 push1 roll goto:fIsAlpha :fInput_isOK_retIsAlpha pop if:fInput_push: push1 push2 push1 roll goto:fIsPeriod :fInput_isOK_retIsPeriod pop if:fInput_push: pop goto:fInput_loop :retInput pop push2 push1 roll pop dup push1 add push2 push1 roll dup push1 dup sub sub if::inputPlain_retInput dup push1 sub if::inputKey_retInput end #---- :fIsAlpha :fIsAlpha_isUC dup dup push2 push3 push4 add mul dup push1 sub push2 push3 add mul push1 sub push2 push1 roll push1 add push2 push3 mul mul push1 add push4 push1 roll gt push3 push1 roll gt add push2 sub if:fIsAlpha_isLC:fIsAlpha_UC :fIsAlpha_isLC dup dup push2 dup dup dup dup mul mul mul mul dup push3 mul push2 push1 roll push2 dup mul mul push5 sub push4 push1 roll gt push3 push1 roll gt add push2 sub if:fIsAlpha_notAlpha:fIsAlpha_LC :fIsAlpha_notAlpha push1 push1 sub goto:retIsAlpha :fIsAlpha_UC push2 push1 sub goto:retIsAlpha :fIsAlpha_LC push1 push2 sub goto:retIsAlpha :retIsAlpha push3 push2 roll dup push1 sub if::fInput_isOK_retIsAlpha dup push2 sub if::fCalcBase_retIsAlpha end #------- :fIsPeriod dup push1 push3 dup dup push2 add mul mul add sub not push3 push2 roll dup push1 sub if::fInput_isOK_retIsPeriod dup push2 sub if::fInput_isEnd_retIsPeriod end #-------- :fCalcBase push2 push2 push1 roll goto:fIsAlpha :fCalcBase_retIsAlpha pop dup if::fCalcBase_notAlpha push3 dup mul dup mul push4 dup mul push3 push2 roll mul sub goto:retCalcBase :fCalcBase_notAlpha pop push1 dup sub goto:retCalcBase :retCalcBase push3 push2 roll dup push1 sub if::ENC_key_retCalcBase dup push2 sub if::ENC_plain_retCalcBase end #------------------------------ :inputPlain push1 dup sub dup goto:fInput :inputPlain_retInput pop :inputKey push1 push2 push1 roll goto:fInput :inputKey_retInput pop push4 push1 roll push1 sub push4 push2 roll pop goto:ENC_loop #----- :ENC_loop push3 push2 roll dup if::ENC_clearKey dup push1 sub push4 push1 roll push3 push2 roll dup push4 push1 roll dup push3 push1 roll add push4 add push1 push2 sub roll push2 push1 roll push4 add push1 push2 sub roll dup push2 push3 mul push1 roll :ENC_key push1 push2 push1 roll goto:fCalcBase :ENC_key_retCalcBase pop sub push2 push1 roll :ENC_plain push2 push2 push1 roll goto:fCalcBase :ENC_plain_retCalcBase pop dup if::ENC_loop_notAlpha dup push3 push1 roll sub push3 push2 roll add push2 dup dup dup mul mul push3 mul add mod add outc goto:ENC_loop :ENC_loop_notAlpha pop outc pop push4 push3 roll push3 push2 roll dup push4 push1 roll push3 add push1 roll goto:ENC_loop # ----- :ENC_clearKey push3 push2 roll :ENC_clearKey_loop dup if::ENC_clearPlain dup push3 add push1 push2 sub roll pop push1 sub goto:ENC_clearKey_loop :ENC_clearPlain pop :ENC_clearPlain_loop dup if::ENC_clear_done push3 push2 roll pop push1 sub goto:ENC_clearPlain_loop :ENC_clear_done pop pop end
Pietソースコード生成
先ほどのコードをもとに、Pietソースコードを生成してみます。
出力画像サイズ427 × 470(上の画像は2倍に拡大しているので854x940)でした。 今までに比べてかなり大きな部類です。
npietで試してみると次のようになります。 暗号化する文章ですが、Wikipediaに具体例があったので、 動作確認がてら正しく暗号化されるかやってみます。
平文 :THEOLDMANANDTHESEA
鍵 :athensparisstlouis
暗号文:talsyvbaeifvmssmms
...Wikipedia, ヴィジュネル暗号, https://ja.wikipedia.org/wiki/%E3%83%B4%E3%82%A3%E3%82%B8%E3%83%A5%E3%83%8D%E3%83%AB%E6%9A%97%E5%8F%B7] (as of June 2, 2022, 10:27 GMT).
この場合、入力は「THEOLDMANANDTHESEA. athensparisstlouis.」となります。
./npiet VigenereCipherx2.png -cs 2 ? THEOLDMANANDTHESEA. athensparisstlouis. ? ? (中略) ? TALSYVBAEIFVMSSMMS.
仕様の都合で大文字・小文字が異なりますが、確かに正しく暗号化できているようです。
忘れもの
そして、いま気づいたのですが、このプログラムに復号化処理(=暗号文を平文に戻す処理)を入れるのを忘れていました・・・(´・ω・`)
この修正にはちょっと手間がかかりそうです。気が向いたら修正します。
プログラムの解説
さて、今回コードが長く処理も複雑です。 文字だけで解説するのは難しいので、図で説明しようと思っているのですが、 図を作るのに手こずっています。
そこで今回は解説まではせず、全体のフローの流れだけを示して、 とりあえず複雑な流れなんだなー、と実感していただくところで終えようと思います。
先ほどのプログラムの中にコロン「:」で始まる行があります。 大雑把にいうと、それがひとまとまりの処理の開始地点を表しています。 このコロンのブロック同士の流れを図にすると、 次のようになります。
処理は頂上の「:1」というブロックから始まり、 中央右の丸ブロック「:ENC_clear_done」で完了します。
その間、キー入力受付、アルファベット判定、ピリオド判定、暗号化計算など、 さまざまな処理を行なっています。 図の準備ができたら別記事で解説しますので、もう少々お待ちください。
ではまた。
[Piet]カエサル暗号プログラム
今回はカエサル暗号を作るPietプログラムを作ってみました。
カエサル暗号とは
以下、英語(アルファベット)の文を暗号化する前提で説明します。
カエサル暗号とは、平文(暗号化前の文章)の各文字を、アルファベット順に一定の文字数だけずらして暗号文を作る手法です。
1文字ずらす場合は、平文に出てくる"A"を"B"に、"B"を"C"に、…、"Z"を"A"に、それぞれ変換します。
2文字ずらす場合は、平文に出てくる"A"を"C"に、"B"を"D"に、…、"Y"を"A"に、"Z"を"B"に、それぞれ変換します。
たとえば、"HELLO FOX"という平文を、カエサル暗号で暗号化することを考えます。暗号化の際にアルファベット順に5文字ずらすとします。5文字の場合は、"H"は"M"に、"E"は"J"に、…と変換されるので、暗号文は、"MJQQT KTC"となります。
カエサル暗号はわかりやすいですが、簡単に解読されやすい暗号でもあります。 アルファベットは26文字しかないため、例えば、1文字ずらす場合と27文字ずらす場合では同じ暗号化結果が出ます。 従って暗号化のパターンは、ずらす文字数が1文字、2文字、…、25文字の25通りしかありません。 (26文字ずらすと、ずらした結果が平文と一致するので、暗号になりません。) 何文字ずらしたかわからなくても、最悪25通り全ての可能性を調べ上げれば解読できるのです。
カエサル暗号を実装する
暗号化のフローは次のようになります。
- 平文を入力する(ピリオドが入力されたら終了)
- 暗号化のときにずらす文字数を入力する
- 暗号化ループ開始
- 全ての平文が暗号化されていたら終了
- 未暗号の平文のうち、先頭1文字を取り出す
- 英字なら暗号化して出力、そうでないならそのまま出力
- 暗号化ループ先頭に戻る
この処理をPietソースコード生成用のコードで書くと次のようになります。
push1 dup sub :CaesarCipher_input_loop inc dup push3 push2 roll push1 add push2 push1 roll goto:CaesarCipher_input_isperiod :CaesarCipher_input_isperiod dup push2 dup dup dup dup push1 add mul mul mul push1 sub mul sub not if:CaesarCipher_input_key: pop goto:CaesarCipher_input_loop :CaesarCipher_input_key pop inn :CaesarCipher_check_key dup push1 dup sub gt if:CaesarCipher_encription: push2 dup dup dup push3 mul mul mul add add goto:CaesarCipher_check_key :CaesarCipher_encription dup outn push2 push1 roll :CaesarCipher_encription_loop dup if::CaesarCipher_end dup push3 push1 roll push2 add push1 push2 sub roll dup push3 push2 roll dup push4 push3 roll goto:isalpha :CaesarCipher_encription_isalpha dup if:CaesarCipher_encription_case_alpha: pop outc pop push2 push1 roll pop goto:CaesarCipher_encription_next :CaesarCipher_encription_case_alpha push2 dup mul dup mul mul push3 dup mul dup mul push2 push1 roll sub dup push4 push2 roll add push2 push1 roll sub push2 dup dup dup push3 mul mul mul add mod add outc push2 push1 roll pop goto:CaesarCipher_encription_next :CaesarCipher_encription_next push2 push1 roll push1 sub goto:CaesarCipher_encription_loop :CaesarCipher_end pop pop end #------- :isalpha :isalpha_upper dup dup push2 push3 push4 add mul dup push1 sub push2 push3 add mul push1 sub push2 push1 roll push1 add push2 push3 mul mul push1 add push4 push1 roll :isalpha_upper_judge gt push3 push1 roll gt add push2 sub if:isalpha_lower:isalpha_UC :isalpha_lower dup dup push2 dup dup dup dup mul mul mul mul dup push3 mul push2 push1 roll push2 dup mul mul push5 sub push4 push1 roll :isalpha_lower_judge gt push3 push1 roll gt add push2 sub if:isalpha_not_alpha:isalpha_LC :isalpha_not_alpha push1 push1 sub goto:isalpha_end :isalpha_UC push2 push1 sub goto:isalpha_end :isalpha_LC push1 push2 sub goto:isalpha_end :isalpha_end goto:CaesarCipher_encription_isalpha
ちょっと長いですが解説します。 処理は大まかに「ラベル」ごとに分割できます。「ラベル」とはコロン「:」で始まる文字列のことで、goto命令やif命令のジャンプ先になります。 例えば、先頭付近にある「:CaesarCipher_input_loop」や「:CaesarCipher_input_isperiod」はラベルです。
各ラベルの処理内容は次のとおりです。No.には先ほどの処理フローの対応する項目番号を記入しています。
No. | ラベル名 | 説明 |
---|---|---|
:1 | 開始地点。スタック初期化 | |
1 | :CaesarCipher_input_loop | 平文入力ループ開始。入力された文字を受け取る |
:CaesarCipher_input_isperiod | 入力された平文の文字がピリオドか判定する(※1) | |
2 | :CaesarCipher_input_key | 暗号化時にずらす文字数を入力する |
:CaesarCipher_check_key | ずらす文字数が負の数なら、正の数になるまで26を足す | |
3 | :CaesarCipher_encription | 暗号化開始準備 |
3~5 | :CaesarCipher_encription_loop | 暗号化ループ開始。未暗号化の平文があるか判定(※2) |
6 | :isalphaで始まるラベルたち | 次に暗号化する文字が英字か判定する |
:CaesarCipher_encription_isalpha | 処理分岐(※3) | |
:CaesarCipher_encription_case_alpha | 暗号化して出力し「:CaesarCipher_encription_next」に進む | |
7 | :CaesarCipher_encription_next | 暗号化ループ終わり。スタックを調整し「:CaesarCipher_encription_loop」に戻る |
:CaesarCipher_end | プログラム終了 |
分岐詳細:
- ※1:
- ピリオド以外なら平文入力を継続(「:CaesarCipher_input_loop」に戻る)
- ピリオドなら次の処理へ(「:CaesarCipher_input_key」に進む)
- ※2:
- なければ終了(「:CaesarCipher_end」に進む)
- あれば次に暗号化する文字を準備して「:isalpha」に進む
- ※3:
- 英字なら「:CaesarCipher_encription_case_alpha」に進む
- 英字でないなら、そのまま出力して「:CaesarCipher_encription_next」に戻る
また、ラベル間の処理の遷移を図にすると次のようになります。
いくつかのラベルは内部に条件分岐やジャンプ命令を含んでおり、内部でもループが発生しうるため、 薄い灰色の波線ブロックでその様子を表現しています。先ほどの説明と合わせると、プログラムがどのような順に処理をしているのか、なんとなくイメージがつくのではないかと思います。
出力結果
このプログラムをGridPietGeneratorに入力してPietソースコードを自動生成すると次のようになります。
画像サイズは223 × 206でした。
npietで動作確認してみます。
./npiet -tpic CaesarCipher_raw.png ? AbCDefG:HijklMn/OpqrStu vWXyZ.3 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 3DeFGhiJ:KlmnoPq/RstuVwx yZAbC.
私の環境だとこのような結果になりました。 なぜか暗号化後の文章の先頭にずらす文字数の3が出ています (そういう仕様だったかもしれませんが…)が、それ以外を比較すると
AbCDefG:HijklMn/OpqrStu vWXyZ. DeFGhiJ:KlmnoPq/RstuVwx yZAbC.
となります。英字部分のみ3文字ずれて暗号化されていることがわかります。 大文字・小文字の対応が取れていることや、英字以外の文字がそのまま出力されていることもわかります。
これで暗号化し放題です。
遊んでみる
「hello, world!」を8文字ずらして暗号化してみます。
./npiet -tpic CaesarCipher_raw.png ? hello, world!.8 ? ? ? ? ? ? ? ? ? ? ? ? ? ? 8pmttw, ewztl!.
「pmttw, ewztl!.」と暗号化されました。
この暗号文を受け取った人は、8文字逆方向にずらせば元の平文を復元できます。 何文字ずらすかあらかじめ取り決めておく必要があります。
逆方向にずらす場合はずらす文字列として-8を入力すればOKです。
./npiet -tpic CaesarCipher_raw.png ? pmttw, ewztl!.-8 ? ? ? ? ? ? ? ? ? ? ? ? ? ? 18hello, world!.
無事平文が出てきました。やったね!
終わりに
今回はカエサル暗号をPietにしてみました。 今までより格段に複雑なので、雰囲気を感じ取っていただければ良いと思います。
次回はさらに複雑なビジュネル暗号を扱ってみます。
それでは、eqq kag msmuz!.
[Piet作ってみた]円周率の近似値表示プログラムの解説
こんにちは。先日1年半ぶりに投稿して、円周率の近似値を表示するプログラムを作ってみました。
ymos-hobby-programing.hatenablog.com
今回はこのプログラムの仕組みを解説をしていきたいと思います。
ソースコードおさらい
円周率の近似値を表示するプログラムをもう一度見てみます。
メッシュが荒すぎて海岸風景に見えないところはご愛嬌です。
作り方おさらい
このプログラムはPietソースコードを、海岸風景の写真(をPiet風にリメイクしたもの)に埋め込むことで作られています。埋め込む際には、円周率プログラムの処理部分と、ただの背景部分がごちゃ混ぜにならないようにする必要があるため、人手でやるのは至難の技です。
そこで、
を自動的に行うプログラムを作っています。
今回は、背景として次のような海岸風景の画像を使い、
これに円周率の近似値計算と表示処理をするPietソースコードを自動生成して埋め込んでいます。
興味があればgithubからソースを落として遊んでみてください。詳細は過去記事でも説明しています。
ymos-hobby-programing.hatenablog.com
ymos-hobby-programing.hatenablog.com
処理の概要
円周率の近似といっても、大したことはしていません。355/113という分数が円周率の近似値として使われるそうなので、単純に355÷113という割り算の結果を表示しただけです。なんてことはない。
処理の流れ
とはいえPietでは整数しか扱えませんので、小学校で教わる割り算の筆算を、自力でPietプログラムに落とし込むことになります。 割り算の筆算の仕方、覚えてますか?電卓信者の私は思い出すのに数分かかりました。
割り算の筆算は次のようにするとおもいます。
- 割られる数(355)の左隣に割る数(113)を書き、その間に”)”を書き、割られる数の上に横線を引く
- 商(=割られる数の中に割る数がいくつ入っているか)を計算する
(割る数113の3倍が339、4倍が452なので、商は3) - 割られる数の棒の上、355の右端の5の上に、商”3”を書く(この時だけ小数点を打つ)
- 割る数113に商3をかけた339を、割られる数355の下に書き、引き算する(答えは16)
- 引き算の答え16の末尾に0をつけた160を、新たに割られる数とみなす
- 商(=割られる数の中に割る数がいくつ入っているか)を計算する
(割る数113の1倍が113、2倍が226なので、商は1です) - 割られる数の棒の上、先ほどの商”3”の右隣に、次の商”1”を書く
- 割る数113に商1をかけた113を、割られる数160の下に書き、引き算する(答えは47)
- 引き算の答え47の末尾に0をつけた470を、新たに割られる数とみなす
- 以下繰り返す
よくみると6は2と同じ処理であり、そのほかも同じ処理を繰り返しています。 また、5などに出てくる「末尾に0をつける」とは、「10倍する」のと同じことです。 これらを意識して処理の流れを書き直すと次のようになります。
- 割られる数(最初は355)と割る数(最初は113)を準備する
- 割られる数を割る数で割った商(整数)を求める
- 商を表示する(最初だけ小数点を表示する)
- 割られる数から「割る数×商」を引き算する
- 引き算の結果(=余り)を10倍したものを新たな割られる数とする
- 2に戻る
今回作ったPietプログラムの処理の流れもおおよそ上の通りです。 ただ、このままだと無限ループするので、 小数以下指定した桁まで表示したら処理を止めるようにします。
Pietソースコード生成
それではまずPietソースコードを自動生成します。 自動生成のためには、処理の流れを専用のプログラミング言語で記述する必要があります。
専用の言語についても過去記事で紹介はしています。Pietの命令を文字起こしして処理順序を書いたものになりますが、難易度はやや高めです。
ymos-hobby-programing.hatenablog.com
ymos-hobby-programing.hatenablog.com
この言語で割り算の筆算処理を記述すると次のようになります。
#割られる数の初期値(355)入力[処理1] push5 dup push7 mul push2 mul push1 add mul #割る数の初期値(113)入力[処理1] :bumbo push3 push2 push1 push2 dup mul add dup dup push1 add add mul mul add # ループ回数(10回)と小数点を打つかどうかのフラグを初期化 :shori push1 push10 push4 push2 roll #---ループ開始--- # 計算に使う数値をメモリ上で複製 :dispfracloop dup dup push4 push3 roll dup push4 push3 roll #商の計算と出力[処理2〜3] div outn push2 push1 roll #余りの計算[処理4〜5] mod push2 push5 mul mul push2 push1 roll #小数点表示判定[処理3] push4 push3 roll dup if::pccheck #小数点表示(初回のみ) push1 sub push7 push7 mul push3 sub outc # ループ終了判定 :pccheck push4 push1 roll push3 push2 roll push1 sub dup if::end # ループ継続処理[処理6] push3 push1 roll goto:dispfracloop ##---ループ終了--- # 終了時の割られる数と割る数を表示(デバッグ) :end push4 push8 mul outc pop outn push4 push8 mul outc outn pop end
このファイルをPietソースコード自動生成プログラムに入力すると、先ほど示したPietソースコード画像が出力されますが、どこでどのような処理をしているのかパッとみただけでは分かりません。
Pietソースコードの解析
Pietソースコードの自動生成プログラムのログを解読すると、どこでどのような処理をしているか分かります。それを図にしてみると次のようになります。
プログラムは左上の「割られる数の初期化」から始まって、図中の矢印の順に処理内容が変化していき、最終的に右上の「デバッグ表示」に到達して終了します。途中、赤矢印で示した部分はループ処理です。赤点線は、初回のみ通るルートで、小数点を表示しています。
ちなみに、自動生成されたPietソースコードは、画像フチで処理を行い、中心部分はほとんどソースコードがありません。そのため、画像にソースコードを埋め込んでも、元の画像が崩れにくくなります。
一方で、画像中央には細かい色付きセルが散らばっています。これはPietインタプリタの移動方向を制御するためのもので、上図の矢印の順に処理が進むように配置されています。その結果、Pietインタプリタは画像のフチだけでなく、画像全体を縦横無尽に移動することになります。
実行結果
このPietソースコードを実行すると、円周率の近似値355/113=3.141592920と、ループ終了時の割る数113と割られる数400を表示して終了します。
3.141592920 113 400
最後に
前回紹介した円周率表示プログラムの解説をしました。やっぱり解説するとなると、それなりにブログ書くのに時間かかりますね。
さて、ふとPietで暗号化プログラムが作れないかと思い立ちまして、先日から試しておりました。結果、なんとかうまくいったので次回以降紹介したいと思います。暗号といっても古典的(?)なもので、カエサル暗号やビジュネル暗号などのことです。それぞれの暗号がどのようなものか解説もしながら、次回以降、説明していきたいと思います。
ではまた。