パスワードを入力するとファイルを暗号化する簡単なRubyスクリプト

新版暗号技術入門――秘密の国のアリス』が刊行されたので、暗号関連のプログラムを作りたくなりました。
以下、パスワードを入力するとファイルを暗号化する簡単なRubyスクリプトを紹介します。
1. cryptをインストールします。

C:\work> gem install crypt
Successfully installed crypt-1.1.4

2. highlineをインストールします。

C:\work> gem install highline
Successfully installed highline-1.5.0
Installing ri documentation for highline-1.5.0...
Installing RDoc documentation for highline-1.5.0...

3. 以下のファイルrjtest.rbを作成します。

require "rubygems"
require 'highline/import'
require 'crypt/rijndael'

File.open('plain.txt', 'wb') do |f|
  f.print <<-'EOD'
結城浩『新版暗号技術入門――秘密の国のアリス』は、複雑に絡み合う暗号技術を
たくさんの図と やさしい文章で ていねいに解説した入門書です。
対称暗号、公開鍵暗号、デジタル署名、一方向ハッシュ関数、
メッセージ認証コード、擬似乱数生成器、PKI、PGP、SSL/TLSといった
現代の暗号技術を解きほぐしていきます。
詳しくは、http://www.hyuki.com/cr/ を参照してください。
  EOD
end
puts "plain.txt is created."

def password(prompt = 'Password?')
  ask(prompt) { |q| q.echo = false }
end

encrypt = Crypt::Rijndael.new(password('Enter password to encrypt: '));
encrypt.encrypt_file('plain.txt', 'encrypt.bin')
puts "encrypt.bin is created."

decrypt = Crypt::Rijndael.new(password('Enter password to decrypt: '));
decrypt.decrypt_file('encrypt.bin', 'decrypt.txt')
puts "decrypt.txt is created."

このRubyスクリプトは、以下の動作を行います。

  • (1) plain.txtというテキストファイルを作る。
  • (2) ユーザからパスワードを受け付ける。
  • (3) そのパスワードを使ってplain.txtを暗号化し、encrypt.binというファイルを作る。
  • (4) ユーザから再度パスワードを受け付ける。
  • (5) そのパスワードを使ってencrypt.binを復号化(復号)し、decrypt.txtというファイルを作る。

もちろん、(2)と(4)のパスワードが一致しなければ、decrypt.txtはplain.txtと等しいファイルにはなりません。
実行結果です。

C:\work> ruby rjtest.rb
plain.txt is created.
Enter password to encrypt:              ←ここでパスワードを入力(画面表示なし)
encrypt.bin is created.
Enter password to decrypt:              ←ここで再度パスワードを入力(画面表示なし)
decrypt.txt is created.
C:\work> fc /b plain.txt decrypt.txt    ←Windowsのfcコマンドを使ってファイルを比較
ファイル plain.txt と DECRYPT.TXT を比較しています
FC: 相違点は検出されませんでした

参考

アイゲンクラス

メタクラスがどうしたとかアイゲンクラスがどうしたという話になり…

2008-11-03

アイゲンクラスって何だっけ?と思ってじっと考え「きっと特異クラスのことだ」と見当をつけてから検索。
特異クラスの構文に関して以前考えていたメモが見つかった。
http://d.hatena.ne.jp/rubyco/20061225/syntax
学習日記を書いておいてよかったなあと思うのはこういうときである。自分が書いた文章なので、すぐに頭に入る。

Rubyで円を描くパズル

問題
半径が与えられると、文字を使って円を描く関数print_circleを作れ。例えば、以下はprint_circle(10)の出力例。(正確に一致する必要はありません)

          ●
      ●●●●●●●●●
    ●●●●●●●●●●●●●
   ●●●●●●●●●●●●●●●
  ●●●●●●●●●●●●●●●●●
  ●●●●●●●●●●●●●●●●●
 ●●●●●●●●●●●●●●●●●●●
 ●●●●●●●●●●●●●●●●●●●
 ●●●●●●●●●●●●●●●●●●●
 ●●●●●●●●●●●●●●●●●●●
●●●●●●●●●●●●●●●●●●●●●
 ●●●●●●●●●●●●●●●●●●●
 ●●●●●●●●●●●●●●●●●●●
 ●●●●●●●●●●●●●●●●●●●
 ●●●●●●●●●●●●●●●●●●●
  ●●●●●●●●●●●●●●●●●
  ●●●●●●●●●●●●●●●●●
   ●●●●●●●●●●●●●●●
    ●●●●●●●●●●●●●
      ●●●●●●●●●
          ●

解答

続きを読む

Rubyで同値関係を求めるパズル

問題
xxxx=yyyy という形式のデータをたくさん受け取り、等しいもの同士をグルーピングするプログラムを書いてください。データは標準入力から与え、グルーピングした結果は { xxxx, yyyy } のように集合のような形式で標準出力に出すことにします。以下に入力と出力の組の例を示します。グループ同士の出力順は問いませんが、グループの中の各要素は適宜ソートしてください。
◆入力1

b=d
A=B
b=a
B=C
c=b
D=A

◆出力1

{ a, b, c, d }
{ A, B, C, D }

◆入力2

Alice=Alice
Robert=Bob
Liz=Beth
Lisa=Liza
Bess=Beth
Elizabeth=Lisa
Eliza=Liza
Bess=Elizabeth

◆出力2

{ Bob, Robert }
{ Alice }
{ Bess, Beth, Eliza, Elizabeth, Lisa, Liz, Liza }

◆入力3

少女=リズ
少年=ペタ
楽天家=ゲルト
老人=モーリッツ
ジム=ジムゾン
アル=商人
村長=ヴァルター
木こり=トーマス
旅人=ニコラス
ならず者=ディーター
少女=リーザ
行商人=アルビン
ジムゾン=神父
女将=宿屋の女主人
ヴァルター=ヴァル
商人=行商人
少年=ペーター
翁=モーリッツ
羊飼い=カタリナ
パン屋=オットー
青年=ヨアヒム
村娘=パメラ
農夫=ヤコブ
宿屋の女主人=レジーナ
リー=少女
ならず者=ディー
ペー太=ペタ

◆出力3

{ オットー, パン屋 }
{ パメラ, 村娘 }
{ モーリッツ, 翁, 老人 }
{ ならず者, ディー, ディーター }
{ リー, リーザ, リズ, 少女 }
{ ペーター, ペー太, ペタ, 少年 }
{ レジーナ, 宿屋の女主人, 女将 }
{ アル, アルビン, 行商人, 商人 }
{ トーマス, 木こり }
{ ニコラス, 旅人 }
{ ヤコブ, 農夫 }
{ ゲルト, 楽天家 }
{ カタリナ, 羊飼い }
{ ヨアヒム, 青年 }
{ ジム, ジムゾン, 神父 }
{ ヴァル, ヴァルター, 村長 }

※入力3のデータは、人狼BBSまとめサイトから借用しました。
http://wolfbbs.halfmoon.jp/?%C5%D0%BE%EC%BF%CD%CA%AA (現在はNot Found?)
解答

続きを読む

色見本を作るRubyスクリプト

http://d.hatena.ne.jp/hrkt0115311/20080715 を見て、私も作りたくなりました。仕様は少し変えています。

File.open('color.html', 'w') do |f|
  f.puts <<-HEADER_END
  <html>
    <head>
      <title>Color Table</title>
    </head>
    <body>
      <h1>Color Table</h1>
      <pre>
  HEADER_END

  code = [ '00',  '33',  '66',  '99',  'CC',  'FF' ]
  code.each do |r|
    code.each do |g|
      code.each do |b|
        f.print "<font color='#{r}#{g}#{b}'>#{r}#{g}#{b} </font>"
      end
      f.puts
    end
  end

  f.puts <<-FOOTER_END
      </pre>
    </body>
  </html>
  FOOTER_END
end

実行すると、color.html というファイルができるので、Webブラウザで表示します。

RubyGems Documentation Indexを読む(gem_server)

たとえば、gemでamazon-ecsパッケージをインストールします。

> gem install amazon-ecs
Need to update 7 gems from http://gems.rubyforge.org
.......
complete
Successfully installed amazon-ecs-0.5.3
Installing ri documentation for amazon-ecs-0.5.3...
Installing RDoc documentation for amazon-ecs-0.5.3...

ドキュメントを見るため、gem_serverを動かします。

> gem_server
[2008-07-16 17:18:01] INFO  WEBrick 1.3.1
[2008-07-16 17:18:01] INFO  ruby 1.8.5 (2006-12-25) [i386-mswin32]
[2008-07-16 17:18:01] INFO  WEBrick::HTTPServer#start: pid=4988 port=8808

ブラウザでhttp://localhost:8808/にアクセスします。
すると、インストールされているgemsのHTMLドキュメントが表示されます。