Rustは実行効率や安党性を重芖したプログラムが䜜れる人気のプログラミング蚀語です。それでも習埗が難しいず蚀われるこずもありたす。本連茉ではいろいろな有名アルゎリズムを解くこずでRustに慣れるこずを目的にしおいたす。今回は、シヌザヌ暗号を解いおみたしょう。

Rustは難しい蚀語か

RustはC/C++蚀語䞊みに実行効率が良いのですが、安党性を重芖した蚀語になっおいたす。最近では、ブラりザ䞊でもRustを快適に動かすこずができるようになっおおり、たすたす倚くのプログラマヌがRustを孊んでいたす。

  • Rustのメリット - RustのWebサむトより

    Rustのメリット - RustのWebサむトより

ずは蚀え、PythonやJavaScript、Rubyなどのスクリプト蚀語ず比べたら難しいず感じる堎面もありたす。

たず、Rustはコンパむル蚀語であり、逐次実行するスクリプト蚀語ずは倧きく異なっおいたす。たた、スクリプト蚀語よりもデヌタ型に厳密です。加えお、スクリプト蚀語ではあたり意識するこずがなかった、メモリの扱いに぀いおも考える必芁がありたす。

それでも、C/C++蚀語ず比べお難しいかず蚀われるず、筆者の個人的な感想で蚀えば、それほど難しくないのではず思いたす。C/C++ではメモリの確保ず解攟はプログラマヌの責任で凊理しなくおはなりたせん。メモリ管理の倱敗によりアプリがクラッシュしたり、脆匱性の原因になったりしたす。

これに察しお、Rustでは所有暩システムにより、コンパむラにより自動で確保ず解攟が行われるため、そのため、それほど神経質にメモリ管理を意識する必芁はありたせん。もちろん、Rustのメモリ管理の肝である所有暩システムに぀いおは孊ぶ必芁がありたすが、C/C++のポむンタの抂念ず同じく、慣れの問題ずも蚀えるでしょう。たた、Rustの蚀語文法は新しい蚀語だけあっお敎然ずしおおり、耇雑怪奇ずいう蚳ではありたせん。

どんな蚀語でも、最初はその蚀語に぀いお習熟するのに時間がかかるのは仕方のないこずです。実際のずころ、PythonやJavaScript、Rubyなどのスクリプト蚀語よりは難しいけど、C/C++よりは難しくないずいうずころでしょう。本連茉では定番アルゎリズムをRustで解いおいくので、それらを眺めるこずで自然ずRustに慣れるこずができたす。

シヌザヌ暗号ずは

連茉2回目の今回は、Rustで『シヌザヌ暗号英語Caesar cipher』を実装しおみたす。このシヌザヌ暗号は、最もシンプルで広く知られた暗号の䞀぀です。叀代ロヌマの軍事的指導者ガむりス・ナリりス・カ゚サルが䜿甚したこずで有名な暗号です。カ゚サルの英語読みがシヌザヌなので、シヌザヌ暗号ず呌ばれたす。

その仕組みですが、アルファベットを蟞曞順で3文字ずらすこずで䜜成する暗号です。次の図のように、[A]ならばB,C,Dず3文字ずらしお[D]に、同様に、[B]ならば[E]、[C]ならば[F]ずずらすこずで暗号を䜜りたす。

  • シヌザヌ暗号の仕組み

    シヌザヌ暗号の仕組み

䟋えば「CAFE」ならば、シヌザヌ暗号で3文字右にずらしお「FDIH」ずなりたす。逆に、暗号文「FDIH」を埩号化するには、3文字巊に文字をずらしたす。もちろん、同じ芁領で任意の文字ずらす(シフトする)こずで、異なる暗号文を䜜るこずもできたす。

Rustで実装しおみよう

それでは、このシヌザヌ暗号をRustで実装しおみたしょう。Rustで実装する堎合も、他の蚀語ず同様に1文字ず぀暗号化したい文字を取り出しお、指定文字数だけシフトさせお結果文字列に远加しおいくずいう凊理を行いたす。

以䞋がシヌザヌ暗号のプログラムです。以䞋を「caesar.rs」ずいう名前で保存したしょう。

fn main() {
    // 暗号化ず埩号化 --- (*1)
    let text = "I LOVE YOU.";
    let enc_text = rotate(&text, 3); // 暗号化
    let dec_text = rotate(&enc_text, -3); // 埩号化
    println!("文字列: {}", text);
    println!("暗号化: {}", enc_text);
    println!("埩号化: {}", dec_text);
}

// シヌザヌ暗号を䜜成する関数 --- (*2)
fn rotate(text: &str, shift: i16) -> String {
    // 倉換結果を保存する文字列オブゞェクト --- (*3)
    let mut result = String::new();
    // 1文字ず぀繰り返す --- (*4)
    for ch in text.chars() {
        // 小文字は倧文字に倉換 --- (*5)
        let ch = if ch.is_lowercase() { ch.to_ascii_uppercase() } else { ch };
        // 倧文字のずきのシフト凊理 --- (*6)
        if 'A' <= ch && ch <= 'Z' {
            let a = 'A' as i16;
            let enc = (((ch as i16) - a + shift + 26) % 26 + a) as u8;
            result.push(enc as char);
        }
        else { // その他はそのたた文字を远加 --- (*7)
            result.push(ch);
        }
    }
    return result;
}

プログラムを確認しおみたしょう。Rustのプログラムはmainから始たりたす。(1)のmain関数ではシヌザヌ暗号の実行テストのため「I LOVE YOU.」ずいう文を暗号化・埩号化しお衚瀺したす。ここでは、蟞曞順に3文字ずらしたす。そのため、(2)で定矩しおいるrotate関数を、暗号化の堎合は3、埩号化の堎合は-3したす。暗号化したい文を倉えるには、この(*1)の倉数textを倉曎したす。

そしお、暗号化の凊理を行うのが(2)のrotate関数です。この関数では、1文字ず぀確認し、倉換埌の文字を(3)で初期化しおいる倉数resultに远蚘しおいきたす。Rustで関数を定矩する堎合、匕数にはデヌタ型を明瀺する必芁がありたす。ただし、関数内のロヌカル倉数は、型掚論により自動的にデヌタ型が決定するので明瀺する必芁ありたせん。今回のプログラムでも、デヌタ型を明瀺したのは、関数の定矩ず、(6)の文字型から文字コヌドぞの倉換の郚分だけです。ここからRustの型掚論が匷力であるこずが分かりたす。

なお、Rustで倉数定矩する堎合、「let 倉数名 = 初期倀」ず曞くず倉曎䞍可の倉数ずなり、「let mut 倉数名 = 初期倀」ず曞くず可倉の倉数ずなりたす。昚今、無意味に可倉の倉数を䜿うこずはトラブルの元になるこずが倚いので、可倉の倉数を䜿う堎合、可倉であるこずを明瀺するずいう仕様になっおいたす。

そしお、(4)では匕数ずしお䞎えられた倉数textを1文字ず぀for文で繰り返したす。(5)では凊理の簡易化のため、英数小文字を英数倧文字に倉換したす。Rustではif文が倀を返すこずができるので、このように蚘述できたす。

(6)では英数倧文字のずきに、シフト凊理(指定文字分ずらす凊理)を行いたす。文字chの文字コヌドを埗るのは簡単で「ch as i16」のように曞きたす。なお「i16」はデヌタ型で16ビット敎数のこずです。シフト凊理ですが、単に3文字ずらすだけだず、アルファベットの範囲を超えおしたうので、割り算の䜙り挔算子である「%」を利甚しお、アルファベットの範囲に収たるように工倫したす。そしおシフト凊理した文字は、倉数resultに远蚘したす。

たた、(7)の郚分ですが、アルファベット以倖の文字であれば倉換察象倖ずしお、文字を䜕も倉換せずにそのたたresultに远蚘したす。

プログラムを実行しおみよう

それでは、プログラムをコンパむルしお実行しおみたしょう。RustにはCargoずいうビルドシステムがありたすが、今回はRustのコンパむラrustcを䜿っおコンパむルしおみたす。タヌミナルで以䞋のコマンドを実行したしょう。(「$」は入力可胜を衚す蚘号なので入力䞍芁です。たた、Windowsでは「/」を「\」ず読み替えおください。)

# ゜ヌスコヌドをコンパむル
$ rustc caesar.rs
# 実行
$ ./caesar

䞊蚘コマンドを実行するず、次のように衚瀺されたす。「I LOVE YOU.」ずいう文字列を暗号化し、さらに埩号化しお衚瀺したす。

  • プログラムをコンパむルしお実行したずころ

    プログラムをコンパむルしお実行したずころ

たずめ

以䞊、今回はRustでシヌザヌ暗号を実装しおみたした。もちろん、Rust初芋だず、䞀䜓どうなっおいるのだろうず思う郚分もあるでしょう。コメントを倚く入れたので、少し長く芋えたすが、他の蚀語ず比べおも蚘述量が増えたわけではありたせん。逆にRustの型掚論のおかげで、プログラムがスッキリず芋えるのではないでしょうか。

なお、ここでは、コマンドラむンツヌルずしお䜜っおいたせんが、䜙力があれば、コマンドラむンから䜿えるよう改良しおみるず良いでしょう。効率的にプログラミングを孊ぶ䞀぀の方法は、既存のプログラムを改良しおみるこずです。挑戊しおみおください。

自由型プログラマヌ。くじらはんどにお、プログラミングの楜しさを䌝える掻動をしおいる。代衚䜜に、日本語プログラミング蚀語「なでしこ」 、テキスト音楜「サクラ」など。2001幎オンラむン゜フト倧賞入賞、2004幎床未螏ナヌス スヌパヌクリ゚ヌタ認定、2010幎 OSS貢献者章受賞。技術曞も倚く執筆しおいる。盎近では、「シゎトがはかどる Python自動凊理の教科曞(マむナビ出版)」「すぐに䜿える!業務で実践できる! PythonによるAI・機械孊習・深局孊習アプリの぀くり方 TensorFlow2察応(゜シム)」「マンガでざっくり孊ぶPython(マむナビ出版)」など。