電子書籍の厳選無料作品が豊富!

どなたか教えて下さい。
仕事でデータのハッシュ値を求める必要がありまして、質問致します。
ハッシュ値はマイクロソフトが提供しているfciv.exeというソフトを使い、希望のファイルのハッシュ値が、正しいことを確認しました。(正しいのは当たり前でしょうが・・・)
多少perlの知識がありましたので、perlで他の方のHPを参考にしながら、ハッシュ値を計算したところ、fcivと異なってしまって、誤った値が出ます。
何がおかしいのでしょうか?

作成したperlプログラム↓
use strict;
use Digest::SHA1 qw(sha1_hex);
open (INFILE,">c:\a_test.txt");
my %file = <INFILE>;
print sha1_hex(%file),"\n";
close(INFILE);

ちなみに開くファイルに指定したa_test.txtにはSHIFT_JISで「A」を40個入れてみました。
FCIVでは、a_test.txtの回答が5cdbb...で上記perlプログラムだとda39a3...になります。
ちなみに、a_testと名前を変え、バイナリーデータも同じように作成しましたが、
FCIVでは、回答が、5efef....上記perlプログラムではda39a3...となり、perlプログラムの方ではバイナリとテキストが同じ値になってしまいます。

ハッシュ値をよく理解してないことに問題があるのは承知ですが、どなたかプログラムの修正、ご指導宜しくお願いします。

A 回答 (3件)

ある程度時間がかかるのはしかたないです。

ハッシュを計算するのに全データを読む必要がありますから。

また、今の方法は一旦ファイルの全データをPerlの変数の収めてからハッシュの計算をしているので、大きなファイルだとたしかにメモリがたりなくなる場合があるでしょう。
こちらでメモリオーバーになるようなファイルがなかったので確認はとってませんが、次の方法はどうでしょうか。

use strict;
use Digest::SHA1 ;

open (OUTFILE,">c:\\hash.txt")|| die Fileが~";
open (INFILE,"c:\\1.m2ts")|| die "Fileが~";
binmode(INFILE);
my $hash = Digest::SHA1->new->addfile(*INFILE)->hexdigest ;
close(INFILE);
print OUTFILE $hash ;
print $hash ;
close(OUTFILE);
    • good
    • 0
この回答へのお礼

おおお!色々ファイルを試したところ、凄く調子イイです。
不思議な構文ですね。
勉強していきたいと思います。
ありがとうございました。

お礼日時:2010/06/18 22:30

> open (INFILE,">c:\a_test.txt");


これだと、a_test.txtへ出力になりますよ。

そのためにINFILEが「出力用」になっていて
> my %file = <INFILE>;
で%fileに入力できていません。

da39a3...はおそらく「長さ0のデータに対するSHA1ハッシュ」です。
こちらで長さ0のファイルを作ったところ、
da39a3ee5e6b4b0d3255bfef95601890afd80709
になりました。

use strict;
use Digest::SHA1 qw(sha1_hex);

#>を取って入力に。""の中に\を書くときは\\とエスケープするのを忘れずに
#また、エラー処理も忘れずに。
open (INFILE,"c:\\a_test.txt") || die "Fileが開けない";

# ハッシュ(%)とリスト(@)は区別しましょう。
# %でも動いてしまうのがPerlという言語なのだが。
my @file = <INFILE>;
print sha1_hex(@file),"\n";
close(INFILE);
    • good
    • 0
この回答へのお礼

返答ありがとうございました。ヘンなところを誤っていたようで、お恥ずかしい限りです。
理解できました。大変感謝しております。
更にですが、これに加えてもう一点だけご指導願えませんでしょうか?

前回ご指導頂いた部分を直し、改良して以下のようになりました。

use strict;
use Digest::SHA1 qw(sha1_hex);

open (INFILE,"c:\\1.m2ts")|| die "Fileが~";
binmode(INFILE);
open (OUTFILE,">c:\\hash.txt")|| die Fileが~";
while (my @file = <INFILE>) {
print OUTFILE sha1_hex(@file);
print sha1_hex(@file);
}
close(OUTFILE);
close(INFILE);

で、動作確認できました。
実は上記のように画面表示とファイル出力を加えたかったのです。(これがやりたくて前回”>”を間違えてました)

ここからが問題ですが、
今回の対象とした「1.m2ts」(参考動画)は600MBでして、このハッシュ値を出すとやけに時間がかかる(数分)のですが、仕方がないのでしょうか?
何故問題としているかと申しますと、会社のデータはGB単位なんです。
会社のパソコンで試験したところ、遅いどころか、時間がかかったあげく「OUT OF MEMORY」と表示が出てしまいます。

一気に読み込むと問題があるかと思い「while」を使ってみましたが、変わらないような気もしますし、良案があったら教えて頂きたく思います。
宜しくお願いします。

お礼日時:2010/06/14 23:42

単純に fciv.exe が MD5 で計算してて、perl プログラムの方は SHA1 で計算しているだけでは?

この回答への補足

fcivには引数でMD5やSHA1を選択できるので、それは間違えてません。

補足日時:2010/06/14 23:15
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!