>>3555 瀧上 > 上記以外に一般的な(適切)な方法があるなら教えて下さい。 しょせん決め事なので、一般解はありませんが、 - コマンドオプション (--debug や -d など) を指定する - make debug で、デバッグ用バイナリを生成する - make install すると ~/bin/ に通常バイナリを、~/bin/debug/ にデバッグ用バイナリを格納する などの方法があります。 どれでもいいので、いずれかをプロジェクトのルールとして決定して おくのがよいでしょう。 わたしの場合、 「デバッグモードは開発時のためのモードではなく、通常運用時や 後々のバグ追及時にこそ有用なもの」 という考え方なので、わたしが好む方法は以下の通りです。 - デバッグモードを実装する。デバッグモードの場合、rollback するなどして、データを一切更新しないようにする (まわりの環境に 一切影響を与えない) - デバッグモードとは別に、冗長なメッセージを出すだけの冗長 モード (verbose モード) を実装する。冗長モードの場合は、 通常どおりデータを更新する。 - エラー発生に気づきやすいよう、ログに吐いたメッセージは 標準出力・標準エラー出力にも吐くようにする。 - オプションでデバッグモード・冗長モードを切り替えられること。 例えば --debug でデバッグモード、--verbose で冗長モード、など。 デバッグモードの場合、自動的に冗長モードも有効にするようにする。 コード例は以下の通り。 int debug_flg = 0; int verbose_flg = 0; for ( i=1 ; i<argc ; i++ ){ if ( strcmp(argv[i], "--debug") == 0 ){ debug_flg = 1; verbose_flg = 1; } if ( strcmp(argv[i], "--verbose") == 0 ){ verbose_flg = 1; } } /* こんな感じで各種情報を出力 */ verbose("ほげほげ foo=[%d]", foo); .... if ( debug_flg ){ EXEC SQL ROLLBACK RELEASE WORK; } else { EXEC SQL COMMIT RELEASE WORK; } void verbose(char *fmt, ... ){ va_list ap; char buf[8192]; /* verbose モードでなければ、何もしない */ if ( ! verbose_flg ){ return; } va_start(ap, fmt); vsnprintf(buf, sizeof(buf-1), fmt, ap); va_end(ap); fprintf(stderr, "debug: %s", buf); } 使い方としては、 - 単に詳細なメッセージを表示したい場合は冗長モードを使う。 - まわりの環境に影響を与えず、とりあえずうまく動くか確かめたい 場合はデバッグモードを使う。 となります。 > UNIXの環境構築 UNIX の環境構築と言っても範囲が広すぎるので、なんともいえません。 > ジョブスケジューラにおけるNET設計 これは何でしょうか? JP1 とかの話? |
大変参考になります。 方式だけでなく、考え方とコードまで載せていただいたのは恐縮です。 参考例を深慮して方式を定めます。 ありがとうございました。 > UNIXの環境構築 UNIX の環境構築と言っても範囲が広すぎるので、なんともいえません。 →そうですね、すみません、主にUNIX環境でのバッチ処理におけるShellの置き場所や構成の最適な方式を調査できるHPを探していました。「コンパイラ等、ツールの環境(変数)設定ファイルは全て別で持つのが好ましいのか」、、とか、「バッチ処理起動shellでsourceする環境設定ファイルにディレクトリとOracleSIDを考えているが、これが最適なのか?」等です。。。開発、本番時に必要な要件を洗い出していけばおのずと出てくると思うので、考えてみます。 開発とUNIXでの開発経験が乏しいので、自分の知っている方式を、プロジェクトの標準として使っていいのか不安なのです(^^;) > ジョブスケジューラにおけるNET設計 これは何でしょうか? JP1 とかの話? そうです。本日書籍購入しました。上記と同じで、もし有効なHP等ご存知であれば教えてもらいたいと思ったので。。。。 |
>>3557 瀧上 > 主にUNIX環境でのバッチ処理におけるShellの置き場所や > 構成の最適な方式を調査できるHPを探していました。 そういうことを書いている web は見たことないですね。基本的に趣味で やってる人には関係ないし、それを知ってる企業は「ノウハウ」として 隠してしまいますので。 # しょーもないやり方を「ノウハウ」などと称しているところも # 多いわけですが。 ちょっと長くなりますが、まぁひととおり書いてみます。 まず、ユーザを複数作ります。例えばユーザ名が hoge なら、 hogedevel (開発環境) hogesi (SI (結合テスト) 環境) hogert (RT (受入テスト) 環境) の 3つくらい。それぞれのホームディレクトリは /home/hogedevel, /home/hogesi, /home/hogert などとします。 さらに DB が必要であれば、これも 3つ (hogedevel, hogesi, hogert) 作ります。 通常の開発は hogedevel を使います。hogesi や hogert は テストの段階で初めて使います。 「開発者は基本的に hogedevel しか使ってはいけない」 というシバリを入れるのもよいでしょう。 各ホームディレクトリの下には src/ ソース置き場。CVS などでソース管理すること。 conf/ 手で管理する設定ファイルなどを置く場所。 bin/ バイナリ置き場。src で make install すると作成される。 lib/ バイナリ以外の設定ファイルやデータファイルなど。 src で make install すると作成されるものに限る。 log/ ログファイル置き場 dat/ 生成するデータファイル・他から送られてきたデータファイル とします。 つまり src/ で make install すると bin/, lib/ が作成される わけなので、bin/ や lib/ は消しても src/ を元に再作成する ことができます。 しかし conf/ は手動管理の設定ファイル群なので、こちらは 消してはいけません (conf/ も CVS などで管理するのがよい でしょう)。 lib/ には、プログラムで生成する雛型のファイルとか、SQL*Loader 用に喰わせるファイルなど、devel, si, rt で共用のファイルを置き ます (実行形式のバイナリではないけど、プログラムの一部と見なして よいものを置く)。 で、環境変数は /home/hogedevel/conf/env.sh /home/hogesi/conf/env.sh /home/hogert/conf/env.sh に ORACLE_SID=hogedevel HOME=/home/hogedevel PATH=/home/hogedevel/bin ORACLE_HOME=... 書きます。 これを source して各アプリが起動し、 - DB の接続先は $ORACLE_SID とする - $HOME/log/ にログを吐く - $HOME/data/ にデータファイルを作成する とします。 というわけで、基本的には > バッチ処理起動shellでsourceする環境設定ファイルにディレクトリと > OracleSIDを考えているが、これが最適なのか? それでよいと思います。 > コンパイラ等、ツールの環境(変数)設定ファイルは全て別で持つのが > 好ましいのか どういうファイルのことを指しているのかよくわかりませんが、 $ORACLE_HOME/precomp/lib/env_precomp.mk とかですか? 基本的に、この辺は共通でよいのではないでしょうか。もし、一部の プログラムで特殊なことをしたければ Makefile 内で上書きすればよい わけで。 あと、いくつか気をつけるポイントをあげておきます。 - ディレクトリやファイルは絶対に手で作成しない。 手で作成するとかならずミスするので、全て Makefile に 記述する。 - CVS などのソース管理ツールを活用する。 /home/hoge{si,rt}/src/ に手でソースを配置し、手で make install する、というやり方は極力避ける。CVS などでマスタ管理し、 毎日朝 AM6:00 に、自動的に ~hoge{si,rt}/src にソースを checkout し、make install などと、全てを自動化するのがベスト。 この他に何か質問があれば、もう少しポイントを絞って、具体例を あげてください。 >> これは何でしょうか? JP1 とかの話? > そうです。本日書籍購入しました。 非オープン系なアプリの場合、web 上からの情報収集は厳しいかと 思います。 JP1 は使ったことがないのでわかりません (わたしは cron の代替品、程度の 認識しかありませんが)。やっぱり便利なんですかねぇ。 |
>>3558 68user > しかし conf/ は手動管理の設定ファイル群なので、こちらは > 消してはいけません (conf/ も CVS などで管理するのがよい > でしょう)。 lib/ との違いがわかりづらい気がするので補足。 hoge{devel,si,rt} で異なる設定ファイルは conf/ に、そうでない ものは lib/ に置く、という意味です。 もちろん make 時に環境によって異なるファイルを lib/ にインス トールできれば conf/ などいらないのですが、それを実現するためにMakefile に複雑な細工をしなければいけないケースがあったりするので。 |
おひさしぶりです。困ったときばっかり登場してすみません。 たぶんあけましておめでとうございます。 ここ5年ぐらいメンテしてる CGI なんですが、 根本的な改革を迫られました。 A.cgi が生成するページにおいて、 ボタンを押したら(可変パラメータ付きで) B.cgi が生成するページに進み、 リンクを押したら(可変パラメータなしで) C.cgi が生成するページに進むという実装になっています。 ところが、ここで C.cgi にも A.cgi で選択入力する可変パラメータを渡さなければ ならなくなったのです。 A、B、C 非常に肥大化していて、安易な解決法が欲しい状況です。 CGI のみで解決できればうれしいですが、 場合によっては JavaScript でもかまいません。 なにかあればご教示願えれば幸甚です。よろしくお願いします。 |
>>3560 ふくし これを機にリファクタリングした方が、のちのち幸せになれると 思いますよ。 …というのは十分承知しておられると思うので、その場 しのぎな案を 2つばかり。 1. B.cgi で受けたパラメータを print qq(<input type=hidden name="param_from_a" value="$ENV{QUERY_STRING}">\n); などとまるごと C.cgi に渡す。 2. 隠しフレームを作っておいて、A.cgi で選択されたら onClick などでフォーム内容を隠しフレームに転記して おき、(B.cgi は無修正で) C.cgi がその隠しフレームを読む。 |
アクセスが遅くなり申し訳ありません。瀧上です。 丁寧なご回答ありがとうございます。 工程別のユーザの切り分けは私の方でも近い形で考えており、ご回答に近い形で定めようと思っています。→開発環境ではユーザを分けますが。 とりあえず考え方に大きなずれが無い事が判明してほっとしています。 ディレクトリですがConfの概念は無くこれはこちらを参考に構成を考えようと思います。CVSはシステム標準で構成管理ツールとして使用することが決定しています。デバッグモードの考え方は、色濃く方式に出そうです(^^;) ところで申し訳ないのですがもう少し勉強させてもらいたい事がありまして、お言葉に甘えていくつか質問させてください。 →たとえばログイン時に「.cshrc」から「環境変数設定ファイル」をSourceしたとして、この時「環境変数設定ファイル」から設定した環境変数は、サーバDOWNかそれを書き換えるまで確実に保証されるのでしょうか? →LIBがmakeInstall時に取り込まれるものだとしたら、 動的なライブラリはUNIXにおける開発ではあまり使用しないものなのですしょうか?システム共通部品等は動的ライブラリから呼び出すのが一般的かなと思っているのですが。 /COMMON/bin/xxxxx.so←拡張子も「.so」一般的なのか疑問ですが、 dllでは無いと思うので。。。 もしくは実行ファイルとしてbinに持つ? |
>>3651 68user すいません、題意を間違えて伝えたかもしれません。 これでよかったです。 A.CGI start_form(action="B.CGI"); フォーム要素1; end_form; start_form(action="C.CGI"); フォーム要素2; end_form; 要は B と C に別の可変要素を渡すのなら、これでできたんですね。 昨日それでできるんじゃないカナと思ってたんですが、 コードにバグをつくっていました。 なお、ボタンを submit にしないで、name をつけ、 name を JavaScript で読み取って切り分ける、という方法も あるようです。これならフォーム要素を共有できるな。 http://webmaster.hatena.ne.jp/1069376628 ★ 事情を説明すると、5年越しということでおわかりいただけると 思いますが、FileMaker で作っていた経理システムが 2000 年問題で 止まる(私製のテンプレートがダサくて)という話があり、 その時個人的に見積書を CGI で出していたことがバレ、 2000 年の 3 月にはちゃんとした業者ウェアを入れるから それまでそれっぽいものを動かしてよ、と言われました。 で、2000 年の 3 月に、業者ウェアの日本語対応ができないと分かり (ガイシ系なんで・・・) その年いっぱい動かすことになりました。 以下、同じことが 200年、2001年、2002年、2003年に起こりました。 いよいよ今年の5月にこのシステムが正式に引退させることが 決定した(・・・)のですが、その前にどうしても大きな山を 乗り越えるためにプログラムを改造することになったのです。 でも「どうせ5月に引退すると決まっているシステムに大金を 投じるわけにはいかない」ので、それだけに長い時間を避けないんです。 人生いろいろですね:) |
教えてください。 指定したポートを開放するために必要なinetd.confの設定方法を教えてください。また、他に必要な設定が必要でしょうか。 ご教授お願い致します。 |
>>3562 瀧上 > たとえばログイン時に「.cshrc」から「環境変数設定ファイル」を > Sourceしたとして、この時「環境変数設定ファイル」から設定した > 環境変数は、サーバDOWNかそれを書き換えるまで確実に保証される > のでしょうか? setenv で更新したら変更されます。.cshrc を更新しても、 明示的に source したり、ログインしなおさないと反映 されません。 よって、プログラムの先頭で source するか、cron であれば * * * * * . /home/hoge/env.sh && /home/hoge/bin/foo としておくのがよいでしょう (JP1 でも何かしら環境変数を 指定するような設定があるのではないかと想像します)。 > LIBがmakeInstall時に取り込まれるものだとしたら、 そういう意図ではなく、実行時に必要ないろいろなファイルの 置き場所、として書きました。 もし動的ライブラリを使うなら lib/ に置くことになる でしょうね。 でなくて、静的にリンクするなら、ライブラリは src/ の 下だけ置いて、アプリのmake install 時にリンクしmasu. ライブラリ自体は lib/ に make install しません (実行時 には必要ないので)。 で、それはそれとして > 動的なライブラリはUNIXにおける開発ではあまり使用しない > ものなのですしょうか? についてですが、わたしの場合は静的にリンクする方法を 好みますが、別に動的リンクがダメと言うほどではないです。 業務系では多少のメモリ使用量の多寡ははどうでもよいので、 構成管理のやりやすさだけを考慮すれば構わないと考えます。 で、例えば、 1. ライブラリ関数 func をプログラム A・B・C が使用している。 2. プログラム A に不具合が発生。すぐに修正版をリリース しなければならない。 3. 原因は func であることが判明。しかし func の呼び出し方の 違いから、プログラム B・C ではこの現象は発生しない。 という状況を考えます。 静的にリンクしている場合、もし人的リソースに余裕があり、 func 修正時にプログラム A・B・C のテストをすることができる なら、修正版 func のリリース時にプログラム A・B・C を再 コンパイルすることができます (これが最も望ましい)。 しかし、プログラム B・C をテストする余裕がない場合、 func を修正して再コンパイルし、プログラム A を再コンパイル とすることで、プログラム B・C に影響を与えず func を修正 するという選択肢をとることができます。 ただしこれは プログラム A が使用している func と、プログラム B・C が使用している func が異なる という管理しづらい状況になるため、次期リリース時に全てを 再コンパイルするまでの時間かせぎです。 つまり、静的リンクの場合、 目の前のリスクを少なくしたいなら → プログラム A のみを再コンパイル 構成を単純にしたいなら → プログラム A・B・C を再コンパイル と、状況に応じた選択が可能です。 しかし動的ライブラリだと、動的ライブラリを入れ替えて、 プログラム B・C に不具合が出るかもしれないリスクを負う という選択肢しかありません。 よって、わたしは静的にリンクする方を選びます。 ただし静的リンクの場合、再コンパイル忘れなどで各プログラムが 使用しているライブラリのバージョンが異なる、という状況が発生 する可能性がありますが、この対策として、定期リリース時に商用 環境の - 全ソース・全プログラムを削除 - 最新版のソースを全て再コンパイル - 全プログラムを make install とすれば OK でしょう (最上位ディレクトリで make && make install すれば全アプリ入れ替え完了)。 # 仮に動的リンクを選択したとしても、上記の「定期リリース # ごとに全部インストールしなおす」というやり方は強く # おすすめしておきます。 |
>>3564 たけ > 指定したポートを開放するために必要なinetd.confの > 設定方法を教えてください。 質問が曖昧すぎて答えられません。inetd のマニュアルと /etc/inetd.conf にある他の設定例を見てください。 それでもわからなければ、何がしたいのかを明記した上で 再度質問してください。 |
はじめまして。初心者ですが、コマンドはどこに打てばいいんですか? |
以下のようなファイルからaddとmodとdelのerrrorがある行を 取り出したいのですが、 ------ ここから ----------- ---- server1 ---- add:yamada:success add:saito:error mod:yamamoto:success mod:ikeda:error del:yamaguchi:success del:butou:error ---- server2 ----- add:yamada:success add:saito:error mod:yamamoto:success mod:ikeda:error del:yamaguchi:success del:butou:error ------ ここまで ---------- grep -v "\-\-\-" ファイル名 | grep -v success で一応とりだせるのですが、改行の2行が含まれて しまいます。空改行を含まず1回の処理でやりたいのですが どうすればよいのですか。 |
>>3568 すすむ 環境を書き忘れました。 SunOSで、Bシェルです。 |
>>3568 すすむ errorを取り出したいなら素直に grep ":error" filename とすれば良いのでは? まぁ名前にerrorが含まれる人がいると引っかかってしまうので 正規表現使うべきなんだろうけど。 |
>>3568 すすむ 賢いかはわかりませんが、 grep -v "\-----" ファイル名 | grep -v success | awk '{ if(NF != 0) print $0 }' でできませんか。 |
>>3568 すすむ 「success」と「error」と簡単に書きましたが、 成功の場合は、「success」で、失敗の場合は、エラーメッセージが でます。 「error」だけでは、引っ掛けられません。 |
>>3567 うこん あなたが置かれている状況がわからないので、回答できません。 >>3568 すすむ わたしなら egrep '^(add|mod|del):' | grep -v ':success$' とします。 |
>>3572 すすむ であれば、 egrep -v '^(-|$|.*:success$)' filename とか? |
>>3573 68user >>3574 zsh zshさん、68userさん ありがとうございます。 egrepですか。 使用したことがないのですが、 「'^(-|$|.*:success$)' 」 の使い方につてい教えてください。 |
>>3561 68user > 1. B.cgi で受けたパラメータを > print qq(<input type=hidden name="param_from_a" > value="$ENV{QUERY_STRING}">\n); > などとまるごと C.cgi に渡す。 「などと」と書いてあるので, 細かいところは省略してあるのでしょうが このままの記述ですと, パラメータの区切りが「&」という前提にて パラメータの名前が「copy」や「reg」だった時に悲しい結果が待ってます。 理由はこのへん http://www.ne.jp/asahi/minazuki/bakera/html/opinion/ampersand |
>>3565 ご回答ありがとうございます。 ライブラリの考え方は参考になります。 要件が無ければ原則禁止にしてしまおうかななんて。。。検討中です。。 ところでshellでバッチを走らせる時はユーザ設定を行わないようにするのがいいのですね。UNIXの部屋にある↓を見て気づきました。 「#!/bin/csh -f というのをよく見かけるが、その場合ユーザ独自の ~/.cshrc は読まれないので、エイリアスやシェル変数は使用できなくなる。」 なので今回はshellの構成は下記の様にするつもりです。ご報告まで。。。 ---------------------------------- #!/bin/csh -f #------------------- #shell # #------------------- source COMMON.src #→システム共通のパス(oracle等)や文字指定(LANG等) source 環境.env #→システム共通環境変数設定等 処理・・・・ ----------------------- |
Makeの環境について教えて下さい。 現在下記のディレクトリを作成して開発環境としようと考えていました。 /src /* makefileとsrcを保管 */ /obj /* make時の中間ファイルを保管 */ /bin /* 実行ファイルを保管 */ するとあるガイドに「.oと.cを別ディレクトリに置くとmake時のタイムスタンプの比較が困難になるのでやめるべきだ」、と書いてありました。 「個々の依存関係をいちいち指定しなければならない。」ともあり、「いちいち」等と書かれると非常に非効率な事の様に感じるのですが。。。 「.cと.oは同一ディレクトリに持つ」が一般開発業務で用いられる主要な方式なのでしょうか? 単体環境だと不特定多数の人間が多様なsrcファイルを作るのであまり余計なファイルを置いてごちゃごちゃさせたくないと言うのが理由で分けてるだけなので同一ディレクトリも特に問題は無いのですが。。。(消されても問題は無いファイルですし。。) 依存関係をmakefileに指定して別ディレクトリ管理と言うのはやらないのですかね? |
No.3568さんに似たような質問なんですが、 ファイルが以下のようにあったとします。 _________________________________________ aaa bb ccc 02/22 ddd e1.3 fff _________________________________________ その時に、実行するたびにe1.3の数字をe1.4、e1.5と実行 するたびに数字を0.1ずつ変更したいんですがCシェルで そのような事をしたいのですが、どうしたらいいのでしょうか。 ご教授お願いします。 |
>>3579 UNIX10ヶ月目 例えば、0.0から9.9まで表示するには以下のような方法があります。 ------ @ i = 0 while ( $i < 10 ) @ j = 0 @ n = $i * 10 while ( $j < 10 ) @ m = $n + $j set cnt = `echo "scale=1; $m/10" | bc` printf "0.1f\n" $cnt @ j++ end @ i++ end ------ ※:シェル変数cntに代入してprintfしているのは、0.0を出力するためです。 >>3575 すすむ 申し訳ありませんが、正規表現について解説された書籍を見るか Webサイト等を探してください。 自分で回答しておいてなんですが、68user様の方法が良いと思います。 自分のはコマンドを強引に1つにまとめただけですので。 |
Bシェルにつてい教えて下さい。 Bシェルで一次元配列を使用しているのですが、 HP-UX11.00で動いていたシェルスクリプトをSunOS5.8に移して 動かしたのですが上手くうごきません。 MONTHES[0]=Dec: 見つかりません。 MONTHES[1]=Jan: 見つかりません。 : 置換が正しくありません。 となります。 どうのように修正すれば、動きますか。 ------------------ #!/bin/sh # MONTHES[0]="Dec" MONTHES[1]="Jan" MONTHES[2]="Feb" MONTHES[3]="Mar" MONTHES[4]="Apr" MONTHES[5]="May" MONTHES[6]="Jun" MONTHES[7]="Jul" MONTHES[8]="Aug" MONTHES[9]="Sep" MONTHES[10]="Oct" MONTHES[11]="Nov" i=0 while [ $i -le 11 ] do echo ${MONTHES[$i]} i=`expr $i + 1` done |
これなら動く筈。(未確認) ------------------ #!/bin/sh # MONTHES0="Dec" MONTHES1="Jan" MONTHES2="Feb" MONTHES3="Mar" MONTHES4="Apr" MONTHES5="May" MONTHES6="Jun" MONTHES7="Jul" MONTHES8="Aug" MONTHES9="Sep" MONTHES10="Oct" MONTHES11="Nov" i=0 while [ $i -le 11 ] do eval echo $"MONTHES$i" i=`expr $i + 1` done |
>3582 zshさん ありがとうございます。 上手くいきました。 |
>3582 UNIXといってもHP-UXとSunOS(Solaris)で違うのだから Bシェルだからといって同じ機能jが使えるわけではない のですね。 |
>>3584 つとむ HP-UXは知らないのですが、配列使えるあたりがkshっぽいですね。 他の部分(スクリプト)がどうなっているかにもよりますが kshに変えたほうが修正が少なくて済むかも知れません。 下ののシェルだったら、 一行目を「#!/bin/ksh」に変えるだけで動きそうです。 |
はじめまして。本日暗号化について調べていたらこのホームページにたどり着きました。暗号化したいのは会社でPOPメールの受信ができないためメールを受信して暗号化し、Webメールなどに投げるようなプログラムでも作ろうかと思い立っていたため、こちらのホームページの内容は非常に役に立ちました。ありがとうございます。 |
>>3577 瀧上 > 「.oと.cを別ディレクトリに置くとmake時のタイムスタンプの > 比較が困難になるのでやめるべきだ」 かどうかは知りませんが、とりあえずわたしは .o と .c を別にするやり方を知りません。 # *BSD などは .c と .o が別になっているので、やろうと # 思えばできるとは思いますが。 で、分ける必要があるかどうかですが、 > あまり余計なファイルを置いてごちゃごちゃさせたくない という理由であれば、cvs add しなければリポジトリに 登録されないので、「*.o は cvs add してはいけない」 という教育さえしておけば十分ではないでしょうか。 時間が経つにつれソース置き場にゴミがたまるのが嫌だ ということであれば、定期的にソース置き場を削除し、 checkout することをお勧めします。 わたしは開発環境であっても、毎日ソース置き場を削除、 checkout、make、make install して、まっさらにする 方法が好みです。 # メンバ全員のアカウントをあらかじめ作成しておき、 # 開発は、各メンバのホームディレクトリで行わせる。 >>3585 zsh > HP-UXは知らないのですが、配列使えるあたりがksh > っぽいですね。 /usr/xpg4/ に POSIX 系を集めている Solaris とは 違い、HP-UX は OS 全体として POSIX を重視している ような印象を受けます。sh と ksh は別コマンドに なってはいますが、sh はかなり POSIX 寄りです。 Bourne shell は /usr/old/bin/sh にあったりします。 >>3575 すすむ > 「'^(-|$|.*:success$)' 」 'a(x|y|z)' は ax か ay か az にマッチするので、 '^(-|$|.*:success$)' は ^- か ^$ か ^.*:success$ にマッチします。後は正規表現を勉強してください。 |
>>3586 まさどん ありがとうございます。 ついでと言ってはアレですが、掲示板の名称を 「UNIX、CGI、ネットワーク、Java Servlet についての掲示板」 改め 「UNIX、CGI、ネットワーク、暗号技術についての掲示板」 としました。 ついでに今日調べたことのメモ。OpenSSL を使って RSA で暗号化 & 復号化。 --------- ここから --------- #include <stdio.h> #include <openssl/rsa.h> #include <openssl/engine.h> int main(){ unsigned char plain_str[]="hogehoge"; unsigned char crypted_str[200]; unsigned char decrypted_str[200]; char errbuf[1024]; RSA *rsa; int n; ERR_load_crypto_strings(); rsa = RSA_generate_key(1024, 65537, NULL, NULL); printf("rsa->n = 0x"); BN_print_fp(stdout, rsa->n); putchar('\n'); printf("rsa->e = 0x"); BN_print_fp(stdout, rsa->e); putchar('\n'); printf("rsa->d = 0x"); BN_print_fp(stdout, rsa->d); putchar('\n'); printf("rsa->p = 0x"); BN_print_fp(stdout, rsa->p); putchar('\n'); printf("rsa->q = 0x"); BN_print_fp(stdout, rsa->q); putchar('\n'); /* printf("RSA_size(rsa)=%d\n", RSA_size(rsa)); */ /* 暗号化 */ n = RSA_private_encrypt(strlen(plain_str), plain_str, crypted_str, rsa, RSA_PKCS1_PADDING); if ( n == -1 ){ printf("in encrypt: err=%s\n", ERR_error_string(ERR_get_error(), errbuf)); goto ERR; } /* printf("%s\n", crypted_str);*/ /* 復号化 */ n = RSA_public_decrypt(n, crypted_str, decrypted_str, rsa, RSA_PKCS1_PADDING); if ( n == -1 ){ printf("in decrypt: err=%s\n", ERR_error_string(ERR_get_error(), errbuf)); goto ERR; } /* 検証 */ if ( strncmp(plain_str, decrypted_str, n) == 0 ){ printf("OK! plain_str=[%s] decrypted_str=[%.*s]\n", plain_str, n, decrypted_str); } else { printf("NG! plain_str=[%s] decrypted_str=[%.*s]\n", plain_str, n, decrypted_str); goto ERR; } return 1; ERR: RSA_free(rsa); return 0; } --------- ここまで --------- 実行例: rsa->n = 0xCA0CBEC6C0384F0387557A9E27A60A9039AB9FAC4D4AE1DA1E08F00093632FAA734AF75E86632E7AFC660A00BF1D703902B57B64CFACD0069314A105295F7624157D3A484C6E1FEBA5A46047E6AE91161DCD51BA7D75B83358F3506D069AEB987D183C0FC21C1BE1F2DF5A0BFF991DB13EFD1E9F079E92BE25CB2BB7D7AD703F rsa->e = 0x10001 rsa->d = 0x35DA87CEF9D5085A6C6C002EBF6AA64E22D0F7D23917C87316A653321416CFD1A2C14C85C9540E43819AC0F7C9F8D2BC9F5837F77AD318EF67AC8BEE90447D7C4F705C57130095BFB51697ECB64CF686414980E1BC814F6AD3EDB3BC2232F88D32892592093E6103AAF89C23B9544254386611B145B9327AA074398D15E60A41 rsa->p = 0xE4A4D51718E83BF3CF91E0C187EB910FFAED34C37858667A6C27F83020DCF7D2DABA5D0B2CD0FAD0A075E06938420F09111F0A5DEA9B443CAAF6674C343944E7 rsa->q = 0xE2395BC32DAA75945F637F88F9BB7C05157464C99168E229E5ED86A3A1EE19498BC357E849505F3C2CA7DC868068880E14FA7ADA01B7BD9897A18FB3573336E9 OK! plain_str=[hogehoge] decrypted_str=[hogehoge] RSA_generate_key() で RSA 鍵を生成できる。 引数: 鍵の bit 数 (この例では 1024 bit)、e (3,17,65537 など)、その他 鍵長についてはよくわからない。上記の例 (平文が hogehoge) では、bit 数を 145 以上にしないと encyrypt 時にエラーになる。なぜ 145? 平文を m として、 m<n ならよいのではないの? 戻り値は typedef struct { BIGNUM *n; BIGNUM *e; BIGNUM *d; BIGNUM *p; } RSA; 的な構造体のポインタ。これが RSA 鍵。詳細は rsa(3)。 それぞれ、以下のような感じ。 e: encryption exponent (OpenSSL 的には public exponent。暗号化指数) ここでは 65537 (=0x10001)。 n: RSA-modules (OpenSSL 的には public modulus と表記) d: decryption exponent (OpenSSL 的には private exponent。復号化指数) p,q: 素数のペア 公開鍵は e,n。秘密鍵は d,n。ただし、「秘密鍵は d」と定義している web・本も散見される。どちらが正しい? まぁ n は公開するわけなので、 どっちでもいいのか? BIGNUM は OpenSSL 付属の多倍長整数ライブラリ。上記の例のように BN_print_fp などを使うことで、内容を確認できる。詳細は bn(3)。 ちなみに BIO は OpenSSL 付属の I/O 抽象化レイヤ。詳細は bio(3)。 crypto 関係のエラーコードは unsigned long ERR_get_error(void) を 使うことで取得できる。そのコードを ERR_get_string() に喰わせると error:0407006A:lib(4):func(112):reason(106) という文字列が得られるが、これではわけがわからん。そこで、あらかじめ ERR_load_crypto_strings(); としておけば、ERR_get_string() の結果が error:0407006A:rsa routines:RSA_padding_check_PKCS1_type_1:block type is not 01 という文字列になる。ちなみに % openssl errstr 0407006A error:0407006A:rsa routines:RSA_padding_check_PKCS1_type_1:block type is not 01 とすればコマンドラインからでも取得可能。 RSA の秘密鍵による暗号化は RSA_private_encrypt() を使う。 第四引数はパディング方式。ここでは RSA_PKCS1_PADDING として いるので、PKCS#1 の方式で勝手にパディングしてくれる。 RSA_NO_PADDING を選ぶとパディングが行われないので、呼び出し側が 平文を適切な長さにパディングする必要がある。RSA_private_encrypt の 戻り値は暗号文の長さ。 復号化は RSA_public_decrypt() で。戻り値は復号化した結果の 長さ。復号化されたデータの文字終端などが自動でセットされる わけではないので、printf("%.*s") などと自分で長さを管理すること。 上記の例では、暗号化した文字列を unsigned char crypted_str[200] に入れているが、正しくは RSA_size() で得た長さ分の領域を確保して おくこと。 参考: http://www.cybersyndrome.net/rsa/ |
RSA で暗号化してみよう (1)・(2) を作成しました。間違いや わかりにくい部分の指摘は大歓迎です。 http://x68000.startshop.co.jp/~68user/net/rsa-1.html http://x68000.startshop.co.jp/~68user/net/rsa-2.html しかし暗号はおもしろい。何かリクエストがあれば (わたしの レベルを見極めた上で) 書いてください。 |
暗号技術大全を持ってらしているのですね。奇遇ですね、僕もこの間 購入してしまいました。僕はハードっぽい図と数学っぽいところに惹 かれて、立ち読みじゃ飽き足らず、買ってしまいました。 #眠いときは枕代わりになるし、持って動かせば筋トレにもなるし、 #一冊三鳥にもなる、良い本です。←冗談です・・・ 今のところリクエストはありませんが、確かに暗号技術は面白いの で、そのうちあるかもしれません。その節は宜しくお願いいたします。 それに、妖精現実フェアリアルも参考にされているのですね! 僕は 双方向処理で行き着いたところは異なりますが、これも奇遇ですね。 というか、そのサイトは凄すぎです。作者は何者なんだ?と思いつつ、 読んでいます。 #全く関係ないですが、Java Servletは興味から外れたのですか? ご存知だとは思いますが、妖精現実フェアリアルから引用しますので、 ご参考までに。 このウェブサイトは、まもなく終了します。 このページに書いてあった 情報は、特に断り書きがない限り、自由に使ってください(コピー、 改変を含む)。 転載先においても転載自由にしてかまいません。 |