Category Archives: PERSONAL COMPUTER - Page 6

TeraPadで全角スペースを□で表示させる方法

プログラムを自分で書く分なら全然問題にならなかったのですが、自分の記述していないソースを見た時、度々問題になるようなのでとりあえずメモする間でも無い気がしますが一応対策方法をメモしております。

オブジェクト指向 Perl プログラミング 設定用クラスのひな形

Perlでオブジェクト指向なプログラミングを行う時設定ファイルの扱いに困った。confファイルでも使おうかと思ったが、Settingクラスを作ってやったところ思いの外使い勝手が良かったので公開してみる。

Settingクラスは値の設定だけでなく外部の設定ファイルへのアクセスを行うメソッドを定義しておくことでメールのテンプレートや、禁止ワード等幅広い用途で外部の設定ファイルを素早く使う事ができる。

Settingクラス(Setting.cgi)のひな形

package Setting; # クラスのパッケージ名を宣言

sub new {
	my $class = shift;
	my $self= {
		# 設定項目を適当に作る
		setting1 => 'mogempoge',
		setting2 => 'hogehoge.txt',
		setting3 => 'hoguhogu.txt'
	};
	return bless $self , $class;
};

# テンプレートを記述したファイルから内容を読み取り変数に格納し、返すメソッド
sub read_config{
	my $self = shift; #クラスプロパティ
	$self->{ ConfigFile } = $_[0] if( @_ );
	
	open(my $fh, "<", $self->{ ConfigFile }) || die("Can not open file $self->{ ConfigFile }");
	my $file_contents;
	while( my $line = readline $fh ){ 
		$file_contents .= $line;
	}
	return $file_contents;
}

# 改行で区切られたワードを記述したファイルから内容を読み取り配列に格納し、返すメソッド
sub read_words {
	my $self = shift; #クラスプロパティ
	$self->{ ConfigFile } = $_[0] if( @_ );
	
	open(my $fh, "<", $self->{ ConfigFile }) || die("Can not open file $self->{ ConfigFile }");
	my @word_contents;
	while( my $line = readline $fh ){ 
		chomp($line); # 改行を削除
		push(@word_contents, $line);
	}
	return \@word_contents;
}

1;

mainクラス(Test.cgi)のひな形

#!/usr/bin/perl
BEGIN{ $| = 1; print "Content-type: text/html\n\n"; open(STDERR, ">&STDOUT"); }
# オプション関連の宣言
use strict;
use warnings;

# クラスを宣言
require "Setting.cgi";
require "Function.cgi";

# パッケージ名宣言
package main;

my $f_obj = Function->new();
$f_obj->function();

その他クラス(Function.cgi)で設定ファイルを読み込む場合のひな形

package Function; # クラスのパッケージ名を宣言

# コンストラクタを定義する時にSettingクラスを継承してあげる。
sub new {
	# 引数を受ける
	my ( $class, @args ) = @_;
	my %args = ref $args[0] eq 'HASH' ? %{ $args[0] } : @args;
	my $self = { %args }; #クラスプロパティ
	# オブジェクト生成
	$self = Setting->new();
	return bless $self , $class;
};

sub function{
	my $self = shift; #クラスプロパティ
	# "setting1"の値を表示する
	print $self->{ setting1 };
	# テンプレート"setting2"の内容を変数で受け取り表示する
	print $self->read_config( $self->{ setting2 } );
	# ワードリスト"setting3"の一覧を配列で受け取り表示する
	print $self->read_words( $self->{ setting3 } );
}

対ボット+外国人用 平仮名+和製漢字CAPTCHA Perl用ライブラリ

―――――――――――――――――――――――――――――――――――――
【ソフト名】かんたん日本語画像認証(アルファベットも可)
【著作権者】ORBIT
【制作日】2011年07月05日
【種 別】Perlモジュール
【連絡先】https://www.orsx.net/blog/
【配布元】https://www.orsx.net/blog/
【圧縮形式】zip
【動作環境】Perl5とImage::Magick、sazanami-gothicをインストールしたLinux
Windows系OSでは動作しない事が確認されております。
【開発環境】
CentOS5.6 perl, v5.8.8
―――――――――――――――――――――――――――――――――――――
≪著作権および免責事項≫

 本ソフトはフリーソフトです。自由にご使用ください。なお,著作権は作者
であるORBITが保有しています。

 このソフトウェアを使用したことによって生じたすべての障害・損害・不具
合等に関しては、私と私の関係者および私の所属するいかなる団体・組織とも、
一切の責任を負いません。各自の責任においてご使用ください。

・はじめに
 新しいフォームを作った時の副産物の公開です。わずか数行で画像認証機能
を実装することが可能です。
 海外のスパム・人間、共に日本特有の和製漢字・平仮名は入力できないこと
に着目し今回の日本語画像認証を作成しました。

・ファイル構成
readme.txt 当取説ファイル
JCaptcha.pm 本ソフト
background.jpg 画像認証用の下地となる画像ファイル
tmp/imgs/ 作成済みの画像ファイルを保存するディレクトリ

sazanami-gothic.ttf
↑さざなみゴシック(フォント) ライセンスの関係上同封しておりません。

・導入方法
efont プロジェクト日本語トップページ – SourceForge.JP
http://sourceforge.jp/projects/efont/
よりさざなみフォントをダウンロードし、sazanami-gothic.ttfのみ取り出し
ファイル構成のようにJCaptcha.pmと同じディレクトリに格納する。

 画像認証機能を追加したい対象のプログラムと同じディレクトリに上記、
ファイル構成を設置する。

・利用方法
下記の使用例を参考にプログラムに組み込んでください。

簡単な使用例

#!/usr/bin/perl

# 当モジュールを呼び出し
use JCaptcha;

# オブジェクトの生成
my $obj = JCaptcha->new(
		Key    => RX, # 鍵を指定
		Lang   => JP, # 言語を指定(JP/ENG)
		Length => 5   # 文字の長さを指定
	);

# 認証画像作成用メソッドを呼び出す
my $tmp1 = $obj->makeimgcode(); # 認証用画像を作成し、その画像までのパスを受ける
print "$tmp1\n"; # 認証画像までのパスを受け取る

#==============================================#
# 画像を表示し、入力を行う処理を書いてください #
#==============================================#

# 認証
# 入力された文字列で認証を行い、正しければ"1"間違っていれば"0"を受ける
#(受け渡す文字列はフラグ無しUTF-8とする)
my $tmp2 = $obj->enimgcode('入力を受けた文字列');
print "$tmp2\n"; # if文などで認証の成功失敗を判別する

・履歴

2011年09月05日 Ver 1.0.0 公開

作成された画像認証用画像の一例

ライセンス形態:GPL
Download:JCaptcha

Ubuntu 11.04にI2P(匿名ネットワーク)をapt-getで手軽にインストールしてみる

マイナーすぎて海外のサイトでもjava -jar i2pinstall.exeなんてLinuxで動かしてるのを見たら目眩がしたのでしっかりapt-getでインストールしてみました。

公式サイト
http://www.i2p2.de/debian.html#ubuntu

# レポジトリを追加してI2Pをインストール
$ sudo apt-add-repository ppa:i2p-maintainers/i2p
$ sudo apt-get update
$ sudo apt-get install i2p

# いれていない人はインストール(テキストエディタとLinuxの起動時に特定のソフトを起動させるソフト)
$ sudo apt-get install vim chkconfig

デーモンとして起動させる設定
$ sudo vim /etc/default/i2p

# I2P daemon. If set to true, i2p will start automatically when
# the computer boots
#RUN_DAEMON=”false” ← コメントアウトして下記を追加
RUN_DAEMON=”true”

I2P起動
$ sudo service i2p start
http://localhost:7657/  I2Pルーター(管理画面)
localhost:4444      ProxyServer

再起動時に自動起動
$ sudo chkconfig i2p on

Perlで簡易WEBサーバを書く

なんとなく書いてみました。リファラやユーザエージェントとかそんなものは環境変数として取得できませんしForkもしません。とりあえず動かして一対一でHTMLファイルや画像ファイルを表示するだけです。ファイヤウォールを外せば他のパソコンからも閲覧できたりします。(危ないのでやらないようにw)

#!/usr/bin/perl -w
use FindBin;
use Socket qw/sockaddr_in inet_ntoa/;
use HTTP::Daemon;
use HTTP::Status;
 
# バッファリングしない
local $| = 1;
# 公開パス
my $public_path = "$FindBin::Bin"."/public_html";
my %in; # ブラウザからデータを受け取るハッシュを初期化

my $daemon = HTTP::Daemon->new(LocalAddr => '',LocalPort => "8080");
print "START SERVER $public_pathn";

while (my ( $client, $peer_addr ) = $daemon->accept){ # メインループ

    my ( $port, $iaddr ) = sockaddr_in($peer_addr); # PortとIPを取得する
    my $remote_addr = inet_ntoa($iaddr); # バイナリ状態のIPを変換する
    print "Access IP: $remote_addrn";

    while (my $request = $client->get_request){ # リクエスト処理ループ

        if ($request->method eq 'GET'){

            my $resource = $request->url->path;

            # GETで送られてきた情報を取得
            my $get_request = $request->url;
            my $get_data = ""; $get_data = $1 if($get_request =~ m/.*?(.+)/);
            &get_form($get_data) if($get_data);
            
            print "---> PATH: $resource GET: $get_datan";
            foreach my $key (keys (%in)){print "------> HASH: $key -> $in{$key}n";}

            if($resource =~ m/^/-_-/){ # インフォメーションページ
                my $header = HTTP::Headers->new( 'Content-Type' => 'text/html' );
                my $res = HTTP::Response->new( 200, 'OK', $header );
                $client->send_response($res);
                print $client "日本語でおk? PATH: $resource GET: $get_data IP: $remote_addrn";
            }elsif($resource =~ m//$/){ # ファイル名を省略していたらとりあえず"index.html"を表示する
                $client->send_file_response($public_path.$resource."index.html");
            }else{ # それ以外はファイルを探して表示
                $client->send_file_response($public_path.$resource);
            }

        }

    }

    $client->close;

}

sub get_form{
	%in = (); my ($get_data) = @_ ;
	foreach my $data (split(/&/, $get_data)) {
		my ($key, $value) = split(/=/, $data);

		$value =~ s/+/ /g;
		$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack('C', hex($1))/eg;
		$value =~ s/t//g;

		$in{"$key"} = $value;
	}
}

ブラウザで適当にhttp://127.0.01:8080/-_-/ でアクセスすれば下記のような返答があると思います。
日本語でおk? PATH: /-_-/ GET: IP: 127.0.0.1

P7H55-M BIOS設定

BIOS SETUP UTILITY を起動させる。

とりあえず言語設定ができるようなので設定する。
MainのLanguage [English]を[日本語]へ。

オンボードGPU(iGPU)を使う設定を行う(PCI-E x16にRAIDカードを挿すとグラフィックボードと誤認するため)
詳細設定からInitiate Graphic Adapter を[PCI/iGPU]を選択。(何故か[iGPU]ではうまく動作しなかった。)

起動時にIDE用ディバイスを使わないのにスキャンされるのでスキャンしないようにする。
詳細設定からオンボードディバイス設定構成を選択しVT6415 IDE Controllerを[無効]にする。

停電時、電源復旧で自動起動するように設定する。(自動動時に確認としてF2を押すように促す保護機能を外す。)
電源からAnti Sure Supportを[無効]に設定。
APM Configurationを選択しAC 電源切断後の復旧モードを[Power On]に設定する。

RAIDカードの設定はHP SC40Geホスト バス アダプタ リファレンス ガイドを見る。
普段はこんな事はまとめないですが複数導入する予定なので次設定するとき設定し忘れが無いようにww

二分探索の処理の様子を細かく見てみる

二分探索の仕組みを詳しく見てみようと思う。サンプルコードはPerlで書いているがCやRuby、Javaなどほかの言語も似たようなものだと思う。

サンプルコード

#!/usr/bin/perl -w

# パラメータ
my $left = 0; my $right = 100; my $target = 140;
my @a; # 初期化

# 0~100までの数字を二倍しながら配列@aに追加
foreach my $i ($left..$right) {push(@a,$i*2);}

# 配列@aのリファレンスとその他引数を添えて二分探索関数を実行する
print &binary_search (@a , $left , $right , $target);

sub binary_search{
	# 配列@aのリファレンスと引数の受け取り
	my ($a , $left , $right , $target) = @_;
	# リファレンス$aを使い配列@aを読み込む
	my @a = @{$a};
	while($left <= $right){
		my $mid = int(($left + $right) / 2);
		if($a[$mid] == $target){
			return $mid;
		}elsif($a[$mid] < $target){
			$left = $mid + 1;
		}else{
			$right = $mid - 1;
		}
	}
	return -1;
}

変数や条件式の動きを追ってみると次のようになっていることが分かる。

$left $right $mid if($a[$mid] == $target)
0 100 (0 + 100) / 2 = 50 100 < 140 → 50 + 1 ($left)
51 100 (51 + 100) / 2 = 75 150 > 140 → 75 – 1 ($right)
51 74 (51 + 74) / 2 = 62 126 < 140 → 62 + 1 ($left)
63 74 (63 + 74) / 2 = 68 137 < 140 → 68 + 1 ($left)
69 74 (69 + 74) / 2 = 71 143 > 140 → 71 – 1 ($right)
69 70 (69 + 70) / 2 = 69 139 > 140 → 69 + 1 ($right)
70 70 (70 + 70) / 2 = 74 140 == 140 → END

二分探索の仕組みも分かったがPerlのリファレンスについても勉強になった。
一石二鳥ですね~

CentOS 5.5 Ruby on Rails 環境構築

 Red Hat系Linuxのパッケージ管理システムyumからインストールされたRubyはバージョンが古くRailsがインストール出来ないためソースからビルドしインストールした。
 しかし、ソースからビルドし直接インストールした場合、削除・アップデートが非常に困難なためソースから管理を行い易いrpmパッケージを作成しインストールする。

rpmパッケージを作成するためのコマンドcheckinstallのインストール
# rpm -ivh http://apt.sw.be/redhat/el5/en/i386/rpmforge/RPMS/checkinstall-1.6.0-3.el5.rf.i386.rpm

Rubyをソースからrpmパッケージを作成しインストールする

rubyのソースファイルをダウンロード
# wget ftp://ftp.ruby-lang.org/pub/ruby/1.8/ruby-1.8.7-p302.tar.bz2

展開
# bzip2 -dc | tar xvf ruby-1.8.7-p302.tar.bz2

展開されたruby-1.8.7-p302ディレクトリへ移動
# cd ruby-1.8.7-p302

Makefileを作成する
# ./configure –prefix=/usr

ビルドする
# make

rpmパッケージを作成する checkinstallの使い方は下記に記載
# checkinstall –fstrans=no

checkinstall 1.6.0, Copyright 2002 Felipe Eduardo Sanchez Diaz Duran
This software is released under the GNU GPL.

The package documentation directory ./doc-pak does not exist.
Should I create a default set of package docs? [y]: ← Enter

Preparing package documentation…OK

Please choose the packaging method you want to use.
Slackware [S], RPM [R] or Debian [D]? r ← Enter

Please write a description for the package.
End your description with an empty line or EOF.
>> ← Enter

**************************************
**** RPM package creation selected ***
**************************************

This package will be built according to these values:

1 – Summary: [ Package created with checkinstall 1.6.0 ]
2 – Name: [ ruby-1.8.7 ]
3 – Version: [ p302 ]
4 – Release: [ 1 ]
5 – License: [ GPL ]
6 – Group: [ Applications/System ]
7 – Architecture: [ x86_64 ]
8 – Source location: [ ruby-1.8.7-p302 ]
9 – Alternate source location: [ ]
10 – Requires: [ ]
11 – Provides: [ ruby-1.8.7 ]

Enter a number to change any of them or press ENTER to continue: ← Enter

rpmパッケージが作成されたディレクトリへ移動
# cd /usr/src/redhat/RPMS/x86_64

作成されたrpmパッケージでRubyをインストール
# rpm -ivh ruby-1.8.7-p302-1.x86_64.rpm

Rubyがインストールされたかを確認する
# ruby -v
ruby 1.8.7 (2010-08-16 patchlevel 302) [x86_64-linux]

Rubyのライブラリを管理するrubygemsをソースからrpmパッケージを作成しインストールする

rubygemsのソースファイルをダウンロード
# wget http://rubyforge.org/frs/download.php/74234/rubygems-1.5.2.tgz

展開
# tar zxvf rubygems-1.5.2.tgz

展開されたrubygems-1.5.2ディレクトリへ移動
# cd rubygems-1.5.2

rpmパッケージを作成する checkinstallの使い方は上記に記載
# checkinstall -R ruby setup.rb

rubygemsからRailsをインストール
# gem install rails –include-dependencies

Railsがインストールされているか確認する
# rails -v
Rails 3.0.7

Ruby製の出来そこないメールフォーム

とりあえずRubyの参考書を読みながらメールフォームを作成してみました。普段はPerlでオブジェクト指向なモジュールを使って色々書いてますが自分でクラスやメソッドを定義することなんてなかったので今回かなり手こずりました。
メールフォームを表示して受け取ったデータをSendmailに渡して送信するだけのメールフォームです。確認画面はおろかメールアドレスのチェックなんて一切しません。。。
実用的には全く役に立たないが、Rubyを勉強しようかな?って人には役に立たないかもしれない。。。。
うん。役に立たない。。。

mailform.yml (設定ファイル)

# サイトのタイトル
Title: Ruby製のメールフォーム
# 管理者のメールアドレス(お問い合わせ送信先)
To: mogumogu@gokugoku.oe
# メールの件名
Subject: Ruby製のメールフォーム

mailform.rb (メールフォームのindex)

#!/usr/bin/ruby -w

require 'contform.rb'
require 'viewform.rb'
require 'sendform.rb'
cont = Cont.new

puts cont.Output
exit

contform.rb (メールフォームの大元のクラス)

class Cont
	require 'cgi'
	require 'yaml'
	require 'kconv'

	# 変数Yamlに設定ファイルのパスを格納
	Yaml = 'mailform.yml'

	#インスタンス変数生成
	def initialize
		begin
			# YAML.load_fileメソッド呼び出し 設定内容をインスタンス変数に格納
			@yaml = YAML.load_file(Yaml)
		rescue
			# 例外発生時の処理(errorメソッドの呼び出し)
			error('YAMLファイルが読み込めませんでした。')
		end
		# 各種オブジェクトを設定を渡しながら生成する
		@cgi = CGI.new
		@view = View.new(@yaml)
		@send = Send.new(@yaml)
	end

	# フォーム画面表示
	def Output
		# 送信する
		if(@cgi['page'] == 'sendmail')
			puts "content-type:text/htmlnn"
			# メール送信
			@send.sendmail(@cgi['from'], @yaml['To'], nil, nil, @yaml['Subject'], @cgi['textdata'])
			# メール送信完了のメッセージを引数として返す
			return @view.Success
		else
		# フォームを表示する
			puts "content-type:text/htmlnn"
			return @view.TopPage
		end
	end

	# エラー出力
	def error(errstr)
		puts "content-type:text/htmlnn"
		puts <<-__END
		エラーが発生しました!
		#{errstr}
		__END
		exit
	end
end

viewform.rb (メールフォームのHTML関連表示クラス)

class View
	def initialize(yaml)
		@yaml = yaml
	end
	def TopPage
		# メールフォームの表示
		html = <<-__EOT
		<HTML>
				<HEAD>
				<TITLE>#{@yaml['Title']}</TITLE>
				<META http-equiv="Content-Type" content="text/html; charset=UTF-8">

				<script type="text/javascript"> 
				<!-- 
				function check(){
					if(window.confirm('送信してよろしいですか?')){
						return true;
					}else{
						window.alert('キャンセルされました');
						return false;
					}
				}
				// -->
			</script>
			</HEAD>
			</BODY>
				<p>#{@yaml['Title']}</p>

				<form action="mailform.rb" method="post" onSubmit="return check()">
				<INPUT TYPE="hidden" NAME="page" VALUE="sendmail">
				<p>メールアドレス</p>
				<input type="text" name="from" size="35">
				<p>お問い合わせ用メッセージ</p>
				<textarea name="textdata" rows="6" cols="50"></textarea><br>
				<input type="submit" value="送信する" onClick="disp()"><input type="reset" value="リセット">
			</BODY>
		</HTML>
		__EOT
	end
	def Success
		# 送信成功画面
		html = <<-__EOT
		<HTML>
				<HEAD>
				<TITLE>#{@yaml['Title']}</TITLE>
				<META http-equiv="Content-Type" content="text/html; charset=UTF-8">

			</script>
			</HEAD>
			</BODY>
				<p>#{@yaml['Title']}</p>
				<p>送信しました</p>
			</BODY>
		</HTML>
		__EOT
	end
end

sendform.rb (メールフォームのメール送信クラス)

class Send
	def initialize(yaml)
		@yaml = yaml
	end
	# メール送信メソッド
	def sendmail(from, to, cc, bcc, subject, body)

		path = "/usr/sbin/sendmail" # sendmailのパス
		subject = subject.tojis
		subject = [subject].pack('m') # Base64
		subject.gsub!(/n/, "")
		subject = "=?ISO-2022-JP?B?#{subject}?="
		body = body.tojis

		IO.popen("#{path} -t", "r+") { |io|
			io.print "From: #{from}n"
			io.print "To: #{to}n"
			io.print "Cc: #{cc}n" if cc != nil
			io.print "Bcc: #{bcc}n" if bcc != nil
			io.print "Subject: #{subject}n"
			io.print "MIME-Version: 1.0n"
			io.print "Content-Type: text/plain; charset=iso-2022-jpn"
			io.print "Content-Transfer-Encoding: 7bitn"
			io.print "n"
			io.print "#{body}n"
		}

	end
end

そういえば、Javaとは違ってクラス名とファイル名が違っても怒られないんですね~

Rubyで超簡単RSSリーダー

RubyでRSSリーダー Windows 用ですがkconvを利用しなければMacやUNIX系OSでも使えます。

#!/usr/bin/ruby
require 'open-uri'
require "kconv"
require 'rss'

# URLへアクセスしページを取得
uri = URI.parse('https://www.orsx.net/feed')
# RSSとして読み込み
rss = RSS::Parser.parse(uri.read)

puts "SiteName : " + rss.channel.title.kconv(Kconv::SJIS, Kconv::UTF8)
# タイトルを保存していく
rss.items.each_with_index do |item, i|
  puts "#{i+1}. #{item.title.kconv(Kconv::SJIS, Kconv::UTF8)}"
end