トップページ⇒php
1001コメント404KB

Perlコーディング初心者質問スレ Part 60

■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん2009/09/03(木) 23:51:12ID:???
Perlのコーディングで困ってる人のスレです。

【投稿する際の注意】
質問するときは内容をよく吟味してから投稿してください。
「コマンドの意味がわかんない」とかはマニュアル見ましょう。
回答者さんは何でも屋じゃありません。

1: 自分はこういう事がしたい。
2: それでこんな風にやってみたが・・・
3: こんなエラーが出て上手く行かなかった。

最低でも1と3が無いと誰も答えられないよ。
良い回答は良い質問から。一緒に勉強しましょう。

お勧めサイトは >2 以降

前スレ http://pc11.2ch.net/test/read.cgi/php/1234752149/
0784nobodyさん2010/04/06(火) 18:55:48ID:???
そ、そんなのが用意されてたのか
無事、期待度通りの動作になりました。
0785nobodyさん2010/04/07(水) 23:42:24ID:???
use threads;

にて
Software error:
This Perl not built to support threads
とのメッセージ

さくらのレンタルサーバーなんですがthreadsはサポートしてないのでしょうか・・・
0786nobodyさん2010/04/08(木) 00:04:18ID:???
>>785
そう書いてあるようにしか見えないが
07877852010/04/08(木) 00:20:24ID:???
>>786

ありがとうございます。
0788nobodyさん2010/04/14(水) 01:52:36ID:???
CGI::Applicationにてチェックボックスの値を受け取るのに苦戦しています。

my @check = $self->query->param('check');
foreach $temp(@check){
print $temp;
}

チェックボックスを何箇所チェックしようが、一つ目の値しか取り出せません。
URLにはキチンと &check=xxx&check=yyy〜 と渡ってきているように見えるのですが、、、
0789nobodyさん2010/04/14(水) 01:53:37ID:???
[]
07907882010/04/14(水) 02:06:40ID:???
>>789
どういうことでしょうか?

foreach $temp(@check)の部分で配列から1要素取り出せてるので[]は必要ないという認識なんですが、
間違ってますか?
0791nobodyさん2010/04/14(水) 02:20:18ID:???
name属性に[]つけるんだっけか
07927882010/04/14(水) 02:30:47ID:???
&check[0]=xxx&check[1]=yyy〜

という形で渡せればいいということでしょうか?
試してみましたが、
my @check = $self->query->param('check')
で値がひとつも取れなくなりました。。。

というか、基本的なことなんでしょうがググっても情報得られず。。。
調べ方が悪いのかな・・
0793nobodyさん2010/04/14(水) 02:49:00ID:???
Perlはエスパーじゃないからパラメタが配列かそうじゃないかは解らない
0794nobodyさん2010/04/14(水) 02:58:53ID:???
>>792
ごめん、name="check[]"とやるのはPHPだったかも
07957882010/04/14(水) 03:23:59ID:???
うーん、、、もうお手上げでございます。。

my @check = $self->query->param('check');
print "@check";

見事に一つ目しか取れてませんね。。。
0796nobodyさん2010/04/14(水) 03:56:01ID:???
use CGI;

my $q = new CGI;
my @check = $q->param('check');

foreach $a(@check) {
print $a . "<br>\n";
}

とりあえずこれは動くんだけど、CGI::Applicationだとだめなんかね
07977882010/04/14(水) 04:00:45ID:???
>>796
うーん、、、一つ目しかとれないっすね。。。

HTML部分が悪いんでしょうか?

<input type="checkbox" value="xxx" name="check"/>
<input type="checkbox" value="yyy" name="check"/>

HTML部分はこんな感じです。
0798nobodyさん2010/04/14(水) 04:17:49ID:???
〜.cgi?check=a&check=b
でやってんでしょ?
なんでいまさらHTMLを疑うのか。。
07997882010/04/14(水) 04:22:31ID:???
>>798

仰るとおり、、申し訳ない。
0800nobodyさん2010/04/14(水) 04:27:42ID:???
>>796でもだめだったんだよね?
久しぶりにPerlインスコして書いてみたら動いたというだけなので、これ以上はサポートできず申し訳ない
環境はWS2003+IIS6+Perlis.dll
08017882010/04/14(水) 04:33:19ID:???
>>800他、アドバイスしてくださった皆さん

どうにもならなかったので力業ですが解決させました。

name要素をcheck_1,check_2に変更した上で、
my $i = 0;
while ($self->query->param("check_$i")) {
# 処理
$i = $i + 1;
}

とすることで無事に取り出せました。

解決しましたが頭の中は?でいっぱいでございます。。。

ありがとうございました。
0802nobodyさん2010/04/14(水) 22:49:50ID:???
CGI::Application のparam()とCGI.pmのpara()が違ってて、
CGI::Applicationの方はhashにしか対応してないからじゃない??
Applicationは使ったことないからどういう使い方をするのかあまり知らないが、
そもそも重複したparam名を使用すべきではないとか。。

CGI::Application こっちのsub array はハッシュのみ。
http://cpansearch.perl.org/src/MARKSTOS/CGI-Application-4.31/lib/CGI/Application.pm

CGI.pm こっちのsub paramは、arrayに対応。
http://cpansearch.perl.org/src/LDS/CGI.pm-3.49/lib/CGI.pm
0803nobodyさん2010/04/14(水) 23:02:13ID:???
俺も使ったことないんだけど、CGI.pmでもだめらしいからね
>>796がうまく動かないらしい。

まぁ何かの間違いだと思うけど
0804nobodyさん2010/04/23(金) 00:45:52ID:???
配列A と 配列B があって
それぞれ先頭から順番に値がセットになるような感じで並んでいたとします
また、それぞれに同じ値はないものとします

配列Aから条件式でマッチングを行い
必要なデータを取り出します

この条件式は配列Bでは使えないのですが
同じ条件で配列Bから抜き出すにはどうしたらいいでしょうか?

@a = (あ,い,う,え,お);
@b = (1,2,3,4,5);

@aのみ条件式でマッチング

最終的に
あ&1、う&3、お&5
みたいな感じで取り出したいんです
0805nobodyさん2010/04/23(金) 01:01:20ID:???
@results = map { $a[$_] =~ /あ|う|お/ ? "$a[$_]&$b[$_]" : () } 0..$#a
0806nobodyさん2010/04/23(金) 01:04:47ID:???
SQL だったら WHERE a.id = b.id と書くところだな
マッチング時に要素番号と要素をセットにした連想配列を作って
さらにその連想配列のkeyでループを回せばいいんじゃないかな
0807nobodyさん2010/04/23(金) 01:06:19ID:???
s/WHERE/JOIN b WHERE/
0808nobodyさん2010/04/24(土) 20:33:36ID:???
use 5.010;
my @array = qw(1 2 3 4 5);
say "found!(1)" if 3 ~~ @array;
say "found!(2)" if @array ~~ 3;

上記で「found!(1)」しか出力されません。
スマートマッチは可換ではないのでしょうか?
0809nobodyさん2010/04/24(土) 23:01:11ID:???
勝手に仕組みを変えるなw
08108082010/04/25(日) 14:09:14ID:???
あるPerlの入門書には「可換」と書いてあるのですが。

ttp://perldoc.jp/docs/perl/5.10.0/perlsyn.pod
ここにも。

use 5.010;
my @array = qw(1 2 3 4 5);
my $number = 3;
say "found!(1)" if $number ~~ @array;
say "found!(2)" if @array ~~ $number;
say "found!(3)" if grep $_ == $number, @array;
0811nobodyさん2010/04/25(日) 14:27:40ID:???
スマートマッチを今はじめて知った。
演算子が増えるとわくわくするよねw
0812nobodyさん2010/04/25(日) 19:23:39ID:???
>>808
> Any Any string equality $a eq $b

これに引っかかってるのでは?
0813nobodyさん2010/04/25(日) 19:58:29ID:???
>>808
それ普通に実行されるけど・・・

ちなみにうちの環境

v5.10.0 built for MSWin32-x86-multi-thread
Binary build 1004 [287188] provided by ActiveState
Built Sep 3 2008 13:16:37
08148122010/04/25(日) 21:00:28ID:???
私のところはv5.10.1だったので、5.10.1deltaを調べてみたら、あったよ。

http://search.cpan.org/~dapm/perl-5.10.1/pod/perl5101delta.pod#Changes_to_type-based_dispatch
> Changes to type-based dispatch
> The smart match operator ~~ is no longer commutative.
0815nobodyさん2010/04/25(日) 21:50:33ID:???
DBD:OracleとDBI使ったタイムアウトの実装ってどうやってますか?例えばSELECT文実行して10秒返ってこなかったらエラーみたいな。
evalで囲っただけじゃOracleの戻りを待っちゃってうまい実装を探してます。
0816nobodyさん2010/04/26(月) 00:42:37ID:???
「evalで囲っただけ」ってのは定番のこの処理のこと?

eval {
  local $SIG{ALRM} = sub { die 'timeout'; };
  alarm 10;
  # ディスパッチ
  alarm 0;
};
unless ($@ =~ /timeout/) {
}
08178082010/04/26(月) 03:49:45ID:???
>>812
>>813
>>814

ありがとうございます。
スッキリしました。( ^ー゚)bグッ!

ちなみに私のは、
v5.10.1 built for MSWin32-x86-multi-thread
Binary build 1007 [291969] provided by ActiveState
Built Jan 26 2010 23:15:11
です。
0818nobodyさん2010/04/26(月) 12:44:34ID:???
>816さん
そです。
でもその実装だと10秒でdieしてくれなくてOrcleから処理が戻ってきてからじゃないとハンドリングできないんですよ。
0819nobodyさん2010/04/26(月) 13:04:32ID:???
>>815
DBIのマニュアルにまさしくDBD::Oracleだとうまくいかないからこうしろってのが
書いてあるのでためすといいよ。
0820nobodyさん2010/04/30(金) 10:50:25ID:???
掲示板でタグの入力を単純化するために、独自のタグを使っています。
内容的には非常に単純で
<hoge>テスト</hoge>
とすると、
<font style="font-size:x-large">テスト</font>
のように置換するだけです。

ここでみなさんにお伺いしたいことは
テストの文字を取得して加工する
というものです。
以下のような式を考えましたが、

($art) = $mes =~ /<hoge>(.*?)<\/hoge>/;
if($art){
$mes =~ s/<hoge>(.*?)<\/hoge>/<span style=\"font-size:140%;\">$art<\/span><span style=\"font-size:180%;\">$art<\/span>/g;
}

一回の書き込みの中で2回使用しようとすると、
2回目の方まで一回目の内容で適用されてしまいます。
↑よくよく考えてみれば、当たり前ですが。
なんとか、一回の書き込みの中で複数回使用できるようにしたいのですが、
どのようにすればよろしいでしょうか?

宜しくお願い致します。
0821nobodyさん2010/04/30(金) 10:58:23ID:???
$mes =~ s#<hoge>(.*?)</hoge>#<span style="font-size:140%;">$1</span><span style="font-size:180%;">$1</span>#g;
0822nobodyさん2010/04/30(金) 11:28:59ID:???
>>821
早速のレスありがとうございました。
大変助かりました!
0823nobodyさん2010/04/30(金) 22:13:35ID:???
余計なお世話だけど、変換する前の内容も
表示用とは別に保存しておくといいよ
0824nobodyさん2010/05/01(土) 04:35:43ID:???
画像のContent-Typeを取得したいのですが、
下記で取得が行えません。

my $q = new CGI();
my $fh = $q->upload($fieldname);
my $mime =uploadInfo($fh)->{'Content-Type'};

エラーログには下記がはかれていました。
Premature end of script headers:
Can't use an undefined value as a HASH reference at /image line 82, <DATA>

他にもContent-Typeを取得する方法があればそれでもいいのですが、
このエラーも解決してみたく持ってますので、ご教示いただけますと
幸いです。
0825nobodyさん2010/05/01(土) 05:00:33ID:???
uploadInfoに$q->がない?
0826nobodyさん2010/05/01(土) 05:16:37ID:???
>>825
早急なご返答感謝です。

状況ですが、変わりませんでした。。
0827nobodyさん2010/05/01(土) 07:52:23ID:???
my $info = uploadInfo($fh);
my $mime = $info->{'Content-Type'};

ようわからんけど uploadInfo から帰ってきた値が undef だと言われてるみたいだけど
0828nobodyさん2010/05/01(土) 09:41:14ID:???
>>824
moduleのドキュメント見てみたけど、
uploadInfoに渡すのはfile handleじゃなくファイル名じゃないとダメなんじゃない?

[module doc]
$filename = $q->param('uploaded_file');
$type = $q->uploadInfo($filename)->{'Content-Type'};
unless ($type eq 'text/html') {
die "HTML FILES ONLY!";
}
08298242010/05/01(土) 18:35:17ID:???
皆様有難うございました。

これってフォームからアップロードされた画像を対象にContent-typeの
取得を行うんですね。。根本的に間違えてました。。

指定した画像のContent-Typeを取得する簡単な方法はないもので
しょうか。
拡張子がgifなのに実際はpngであったりとするケースがあるため、
Content-Typeで判定をしたいのですが、ご存知でしたらどうか
教えてください。
0830nobodyさん2010/05/01(土) 19:30:27ID:3heBO4S1
>>829
それってUploader云々ではなくて、例えばローカルとかに保存してあるファイルのことかい?
だったらGDでもImage::Magicでも使って、画像を判定すればいいんでね。
まあヘッダの数十〜百バイト程度の判定で済むから、自前でバイナリ読んで解析するとかもあり。
(GDではWindows-bmpに未対応なので、以前自分で書いた)
0831nobodyさん2010/05/01(土) 20:59:59ID:???
>>830
はい、そうです。
Image::Magickはサーバに入れられなかったので、GDで
できる方法があれば教えていただけますと幸いです。

よろしくお願いいたします。
0832nobodyさん2010/05/01(土) 21:32:17ID:???
ファイルの先頭8バイトだけで画像のフォーマットを調べる
ttp://labs.gmo.jp/blog/ku/2007/05/8.html

phpだがperlに応用可能だろう
0833nobodyさん2010/05/01(土) 22:50:54ID:???
Windows だったら Apache の conf ディレクトリにある magic.default を使うのも
ただ、PNG が無いっていうw
0834nobodyさん2010/05/01(土) 23:06:47ID:???
http://perldoc.jp/docs/modules/File-MMagic-1.21/MMagic.pod
モジュールあるのね

そこそこ設定の揃ってるマジックファイルって、誰か配布して無いっすかね
0835nobodyさん2010/05/02(日) 02:25:22ID:???
>>832-834
ありがとうございます。
勉強になりました。

最終的には、MMagicを使用させていただきました。
これ便利ですね。

この場をお借りし御礼申し上げます。
0836nobodyさん2010/05/10(月) 14:42:47ID:???
use CGI;
$q = new CGI;
@hoge = $q->param('hoge');

@hoge = ("hoge", "hogehoge")

と同じ方法をCGI.PMをもちいらないで出来ませんか?

read(STDIN, $q, $ENV{'CONTENT_LENGTH'});
@pairs = split(/&/, $q);
foreach $pair (@pairs) {
($name, $value) = split(/=/, $pair);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
@FORM{$name} = $value;
}
@FORM{$name} = ("hoge", "hogehoge")
みたいな感じで
0837nobodyさん2010/05/10(月) 14:45:58ID:???
頑張ってプログラム書けばできるよ。
08388362010/05/10(月) 18:06:05ID:???
read(STDIN, $q, $ENV{'CONTENT_LENGTH'});
@pairs = split(/&/, $q);
foreach $pair (@pairs) {
($name, $value) = split(/=/, $pair);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
push(@hoge, $val) if $key =~ /hoge/;
@FORM{$name} = $value;
}
で自己解決しました。
お邪魔しました。
08398362010/05/10(月) 18:07:53ID:???
push(@hoge, $value) if $name =~ /hoge/;

だった。
0840nobodyさん2010/05/10(月) 20:01:30ID:???
そもそも form の値が不明の時点で、行儀のいいスクリプトなのかな・・・
0841nobodyさん2010/05/12(水) 14:33:57ID:l5g8HUnE
フォームから入力した「漢字データ」をtxtファイルに出力したら、
文字化けしています。どうすれば良いのでしょうか。

Perlのソースに記述した漢字は、パソコンのテキストエディタ表示、
IE上のフォーム表示、サーバのファイル上のいずれでも文字化けして
いません。
フォームを表示するhtmlの<meta>タグではShift-JISを指定しています。

よろしくお願いします。
0842nobodyさん2010/05/12(水) 21:13:03ID:???
それだけの情報だと
ソースが無いことにはなんとも
0843nobodyさん2010/05/13(木) 09:22:25ID:???
use Encode;
使っててダメなのなら>>842に同じ。
0844nobodyさん2010/05/14(金) 23:42:43ID:???
LWP で取得した JPEG を扱うときって なんちゃら blob とかで
変換?してたような気がするんですけど、なんでしたっけ?

ちなみに GD 使ってます
0845nobodyさん2010/05/15(土) 00:20:02ID:???
>>844
ImageMagik?
0846nobodyさん2010/05/15(土) 00:26:24ID:???
あ〜、ImageMagick でしたねw

GD にメモリの中にあるバイナリを GD と結びつける方法は無いのかしら?
一旦ファイルに書き出さないと駄目な感じなんですかね・・・
0847nobodyさん2010/05/15(土) 00:35:15ID:???
>>846
SEE GD Manpage
>Alternatively, you may create a GD::Image object based on an existing image by providing an open filehandle, a filename, or the image data itself.
0848nobodyさん2010/05/15(土) 00:52:53ID:???
英語読めないけどニュアンスで読むと
「ファイルから読め」
って事っすね orz
0849nobodyさん2010/05/15(土) 02:58:47ID:???
my ($tmp_fh, $tmp_filename) = tempfile(DIR => $config->{'dir_temp'});
〜 ファイル名 $tmp_filename で画像を作る処理 〜 省略 〜
my $imgbin = GD::Image->new($tmp_filename);

こうやるとエラーログに

[Sat May 15 02:42:21 2010] index.cgi: Use of uninitialized value $pkg in concatenation (.) or string at /perl/lib/Symbol.pm line 129.

が出てきます。

Symbol.pm の 129 行目を含む関数は qualify なんですが、 GD.pm のソースを見ても qualify が有るわけも無く、デバッグしようにも負えません。

GD::Image->new($tmp_filename); に必要な引数があるのかと思って、CPAN の GD とこを見ても、サンプル自体がこういう記述の仕方。

コレって解決方法無いんでしょうか?
0850nobodyさん2010/05/15(土) 13:25:56ID:???
GD::Image->new($data);
これでファイルの読み込みしなくて済むようになった
ImageToBlobみたいのがあるかと思ったら、そのままGDに投げてよかったんですね
0851nobodyさん2010/05/15(土) 17:41:13ID:???
>>850
ニュアンスで読むからそうなる
0852nobodyさん2010/05/15(土) 20:30:59ID:???
or the image data
↑
これか!
言われて今気が付いたw
0853nobodyさん2010/05/15(土) 23:27:44ID:???
HTTP::REQUEST を使って、例えば、xmlをポストすると、どうして、url ENCODE が必要なのでしょうか?普通に、POST コマンドを使ってxmlをポストするときは、URLエンコードが必要ないです。

なぜURLエンコードが必要が教えて下さい
0854nobodyさん2010/05/16(日) 02:50:47ID:???
え?
0855nobodyさん2010/05/16(日) 08:07:46ID:???
>>853
教えてgoo@韓国とかないの
0856nobodyさん2010/05/16(日) 08:23:36ID:???
>>855
あるよ↓

OK World - ?? ???? ?? ?? ??
http://world.okwave.jp/korean/
0857nobodyさん2010/05/16(日) 18:26:33ID:GMFXnF2I
現在、下記のようなpgをかいています。
my $method = 'POST';
$request = HTTP::Request->new( $method, $uri,$header,$xml); --�@


POSTする際に、BASIC認証が必要なのですが、
別のモジュールでいう、
$req->authorization_basic("username","password");
的なことを、
use HTTP::Request;
を使って行いたいと思っています。つまり、�@に追加して認証を行わせたいと思っています。
http://search.cpan.org/~gaas/libwww-perl-5.836/lib/HTTP/Request.pm

何か方法はありますでしょうか?
0858nobodyさん2010/05/16(日) 19:17:21ID:???
>>857
http://search.cpan.org/~gaas/libwww-perl-5.836/lwpcook.pod#ACCESS_TO_PROTECTED_DOCUMENTS
0859nobodyさん2010/05/16(日) 22:43:32ID:GMFXnF2I
A(CLIENT )
B(AP SERVER)

A-B 間は、HTTPプロトコルでXMLをやり取りするシステムだとします。
この際、AからBに何らかのXMLを送られてきたときHTTP GET で、

Bには、http://www.geekpage.jp/programming/perl-network/lwp-useragent-0.php
のプログラムがあり、BのAPサーバー上で 上のプログラム.pl とすると、期待通り、htmlファイルを
すべて画面に表示します。

さて、クライアントAから上のCGIにアクセスがあったとき GET でhoge.cgi としてクライアントからサーバーにアクセスします。上の結果をA(クライアント)に帰してやりたいと考えています。

具体的には、AからのレスポンスのXML内に埋め込んでやりたいと考えています。
どうやれればいいでしょうか?
もう少し言うと、
APからのサーバのレスポンスは、
HTTPレスポンスヘッダと、
<XML1>
ここに取得した情報を書きたい
<XM1>

このレスポンスを返したいと思います。
0860nobodyさん2010/05/17(月) 04:32:17ID:???
blog とかで画像を保存する場合、多すぎるなるであろうファイル数の対策として

/img/5/a/7/d/20304495.jp

みたいにすることがありますが、これって技術的な名前ってあるんでしょうか?

ディレクトリ 分散化 でググっても知識として手に入れる例とかが出てこないので・・・
0861nobodyさん2010/05/17(月) 10:48:50ID:???
「データ正規化」でググって。
例えば、はてなブックマークのスクリーンショットはSHA-1で正規化したコードを
ディレクトリとファイル名に使ってる。
0862nobodyさん2010/05/17(月) 11:04:55ID:???
>>859-861
>>1
0863nobodyさん2010/05/17(月) 12:40:45ID:???
言葉が足りなかったですね

自分が作るサービスに数万ものユーザーが来るわけではないですが、それを見越した設計をするのが良いのかなと思ってたとこでの質問でした。


1時間に数百ものファイルが投稿されたら、1つのディレクトリに1万ものファイルとか余裕でたまるわけで、
全てのサーバーが新しいファイルシステムを採用してるわけではないので、1つのディレクトリあたりのファイル数を
1万未満に制限し、あふれたファイルは別のサブディレクトリというのを考えてます。

純粋に http://〜.com/files/2010/05/17/hh_xxxxxx.xxx の様にしてもいいのかなと思いましたが、
記念日の0時、例えば正月なんてそれで足りるとは思えませんしw
だったら http://〜.com/[a-z]/[a-z]/[a-z]/[a-z]/[a-z]/ のようなディレクトリを先に作ってしまい、偏らないように分散出来ないものかな?

などなど思ってたりするわけです。


ここまで書いて思ったけど、perl の話じゃなかった・・・
0864nobodyさん2010/05/17(月) 17:36:43ID:???
通じてねええええええ
すごく・・・ガッカリです・・・
0865nobodyさん2010/05/17(月) 23:55:28ID:OKXaqr1F
すいません、普通にATOMをテキストの行として扱えるモジュールいいのないでしょうか?
XML::ATOMって多くのモジュール入れるみたいで、エラーになります。環境は普通のWinXPです。
0866nobodyさん2010/05/18(火) 01:44:50ID:???
異常なWinXPってあるのか?
0867nobodyさん2010/05/18(火) 01:49:44ID:???
あるよ。中華版。
0868nobodyさん2010/05/18(火) 06:45:19ID:???
XML-Atomはppmに無いからめんどくさいんだよな
だから俺は使ってない
あとこいつマルチだな
0869nobodyさん2010/05/18(火) 07:30:05ID:???
>>864
SHA-1として生成した文字列があった場合、色んなディレクトリにバラけると思うが、
SHA-1から得たディレクトリに収めようとして、そのディレクトリがすでに10000を超えようとしてたら
どうやって違うSHA-1の文字列を得るの?

再生成事態があってはならない事だと思うのだけど?
0870nobodyさん2010/05/18(火) 14:02:13ID:???
桁を分割しろよ
頭から一桁ずつ6階層のフォルダを作るだけで16777215通りにバラけるだろ
必要に応じてもっと深くしてもいい

なんでそんなことも思いつかないの?
0871nobodyさん2010/05/18(火) 19:28:59ID:???
いやそれぐらい思い付く

それだと、特定のディレクトリに一定数 (今回は1万) 以上溜まらない。 って事になるでしょう。

しかもファイルから保存場所を求めるわけだから、別の値を求められるわけではない。
0872nobodyさん2010/05/18(火) 22:03:00ID:???
>>871
ただ単にディレクトリをDBで管理すればいいだけじゃないの?
ランダム文字列/3桁数値
ファイル名とディレクトリ・数値をDBで紐付け

いまいち論点が掴めない
0873nobodyさん2010/05/19(水) 00:40:36ID:???
こういう破天荒な事を質問するような事態はどこかで何かを間違えている
0874nobodyさん2010/05/19(水) 06:25:00ID:???
>>871
なんで別の値を求めようとするわけ?
やっぱり分かってねえなコイツ
0875nobodyさん2010/05/19(水) 08:17:09ID:???
ファイル数が少なすぎる例えですが、
ディレクトリあたり2までしか保存させないとする。

ファイルのデータからSHA1を求めて、求めた文字列から保存するディレクトリを決める。

(めんどくさいので文字列は短め&単純にしてます)

ファイル   SHA1     保存先
aaa.jpg  123456789 -> 1/2/3/456789.dat
aab.jpg  123456890 -> 1/2/3/456890.dat
acd.jpg  123456000 -> 1/2/3/456000.dat

例えばこうなった場合、3つめのファイル acd.jpg の保存先はどうなるのかなと。
実際の得られる文字列はもっと長いから、ディレクトリ自体を深く掘ればいいでしょうが、
それだけではファイルが溢れないという約束は得られないですよね?
0876nobodyさん2010/05/19(水) 09:13:26ID:???
どんなに深くなってもよければファイル名はuniqueにつけてるとして
ファイル名を2文字ずつぐらいに区切ったディレクトリをずんどこ掘って
格納すれば絶対に大丈夫ではある。

たとえば

aaa.jpg → aa/a./jp/aaa.jpg
0877nobodyさん2010/05/19(水) 09:15:14ID:???
約束はもちろん得られる。
最終的なディレクトリに置くファイル数が二つまでなら、1ビットになるまで桁を分割すればいい。

サブディレクトリ数1万までという前提で話すが、
SHA-1で得られる文字列は16進数なので、3桁ずつ使えばサブディレクトリ数は4095個に制限できる。
fff/fff/fff/fff/fff/fff/fff/fff/fff/fff/fff/fff/fff/f.dat

最終的なファイル数を二つに制限したい場合はこうなるな。
000/000/000/000/000/000/000/000/000/000/000/000/000/0/0.dat から
fff/fff/fff/fff/fff/fff/fff/fff/fff/fff/fff/fff/fff/7/1.dat まで

これでもまだ分からないようなら俺は降参するよ。
0878nobodyさん2010/05/19(水) 09:32:00ID:???
いやハッシュ値は衝突があるから衝突したファイルがたくさんあったら終わるのよ。
SHA-1は160bit(=20バイト)しかないんだから、100文字ぐらいのファイル名なら
いくらでも衝突させられるよ。狙ってファイル名を決めない限り現実にはそうそう
起きないけどね。
0879nobodyさん2010/05/19(水) 10:35:56ID:???
ファイル名?

[hoge@foo ~]$ openssl sha1 -c a.txt
SHA1(a.txt)= 5f:e4:3b:0e:3e:95:d4:3c:1f:a4:8b:35:cf:39:e6:9c:62:83:42:81
[hoge@foo ~]$ openssl sha1 -c b.txt
SHA1(b.txt)= 5f:e4:3b:0e:3e:95:d4:3c:1f:a4:8b:35:cf:39:e6:9c:62:83:42:81

試しに2つくらい狙って衝突させてみてくれないか?
0880nobodyさん2010/05/19(水) 10:48:02ID:???
狙って起こすのはたいへんだけど偶然には起きるもんだからなぁ。
0881nobodyさん2010/05/19(水) 11:04:11ID:???
ファイル名からハッシュ求めたらいくらでも衝突するだろ
普通中身で求めるもんだと思うけどな
0882nobodyさん2010/05/19(水) 11:15:49ID:???
ファイルの中身でハッシュ求めるのは改ざん防止とかそっちの方の
目的だよ。単にファイルをディレクトリに分散して置きたいだけなのに
中身のハッシュとるのは重過ぎる。
0883nobodyさん2010/05/19(水) 11:41:02ID:???
1万のファイル数制限をかけたいのに4000物ディレクトリなんて使いたくないよママンw

データに対してハッシュを取るのは確かに重いですね。
WEB サービスでなければ全然問題ないですが、、、


そう考えると「readme.txt」 をアップする人なんてたくさん出てくる可能性もあるし、
a.avi をアップしようとする人はたくさんいると思う。
みんながみんな、毎回毎回違うファイル名を使ってくれるとは思わない。

どう考えても衝突しますよね・・・
■ このスレッドは過去ログ倉庫に格納されています