こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

どなたか教えて下さい。

どなたか教えて下さい。
仕事でデータのハッシュ値を求める必要がありまして、質問致します。
ハッシュ値はマイクロソフトが提供している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プログラムの方ではバイナリとテキストが同じ値になってしまいます。

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

投稿日時 - 2010-06-14 00:20:12

QNo.5966922

困ってます

質問者が選んだベストアンサー

ある程度時間がかかるのはしかたないです。ハッシュを計算するのに全データを読む必要がありますから。

また、今の方法は一旦ファイルの全データを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);

投稿日時 - 2010-06-15 09:47:21

お礼

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

投稿日時 - 2010-06-18 22:30:38

ANo.3

このQ&Aは役に立ちましたか?

21人が「このQ&Aが役に立った」と投票しています

回答(3)

ANo.2

> 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);

投稿日時 - 2010-06-14 04:08:02

お礼

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

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

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:41

ANo.1

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

投稿日時 - 2010-06-14 00:26:59

補足

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

投稿日時 - 2010-06-14 23:15:43

あなたにオススメの質問