ハッシュ値計算の問題についての質問

このQ&Aのポイント
  • 仕事でデータのハッシュ値を求める必要があり、perlプログラムを使用して計算していますが、正しい値が得られません。
  • 具体的には、マイクロソフトのfciv.exeを使用してハッシュ値を求めると正しい値が得られるのに対して、perlプログラムでは異なる値が得られます。
  • バイナリーデータとテキストデータのハッシュ値も異なってしまいます。プログラムの修正方法を教えてください。
回答を見る
  • ベストアンサー

どなたか教えて下さい。

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

  • dogu7
  • お礼率36% (4/11)
  • Perl
  • 回答数3
  • ありがとう数23

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

  • ベストアンサー
  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.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);

dogu7
質問者

お礼

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

その他の回答 (2)

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.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);

dogu7
質問者

お礼

返答ありがとうございました。ヘンなところを誤っていたようで、お恥ずかしい限りです。 理解できました。大変感謝しております。 更にですが、これに加えてもう一点だけご指導願えませんでしょうか? 前回ご指導頂いた部分を直し、改良して以下のようになりました。 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」を使ってみましたが、変わらないような気もしますし、良案があったら教えて頂きたく思います。 宜しくお願いします。

  • koko_u_u
  • ベストアンサー率18% (216/1139)
回答No.1

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

dogu7
質問者

補足

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

関連するQ&A

  • ハッシュ値 のファイル

    あるファイルfile1.txt のハッシュ値を計算してその結果を記載したファイル file2.txt のデータは、 Hash SHA1 hashsize=20 C1 14 ...... 4F のように、 先頭に、方式 1行あけて、サイズ 次の行に、計算したハッシュ値 となっているのでしょうか? 参考になる資料がありましたらよろしくお願いします。 なお、上の値は、 RFC6234 にある、ソフトを動かした結果です。 よろしくお願いします。

  • 区切りファイルの列ソートについて

    僭越ながら、質問させていただきます。 タブ記号で区切られたTSVファイルというものを扱っているのですが、まずtest.tsvファイルを配列に格納して、そこから2列目の値すべてを降順にソートし、 (列をソートした結果の行は、ちゃんと最初のまま保持され、バラけずに出力されるようにしたい) その結果をresult.txtに表示させるプログラムを作りたいと思っております。 ですが、自分が書いたプログラムではまったく動かず、どこが悪いのかも情けないことにわかりません…。  かれこれ何時間も悩んでいますが、まったく方策が見出せません。どこをどう直せばいいのか、ヒントだけでも構いませんので、教えてくださいませんでしょうか。 プログラムは以下です。 #!/usr/bin/perl use strict; use warnings; use Fatal qw/ open /; my @values; my $tsv_file = "test.tsv"; my @tsv = &readtsvfile($tsv_file); @values = sort { $a->[1] cmp $b->[1] } @tsv; open(DATAFILE, '>>result.txt') or die("error :$!"); foreach(@tsv){ print DATAFILE; } sub readtsvfile { open(IN, $_[0]); while(<IN>) { chomp; push @tsv, [ split(/\t/) ]; } close(IN); return @tsv; } close DATAFILE; このプログラムの手直しでも新しい方法でもなんでも構いません、何か教えてくだされば、本当にありがたいです。よろしくお願いします。

    • ベストアンサー
    • Perl
  • Cでバイナリデータを変換

    今持っているバイナリファイルfile1.x86をテキストファイルfile1.txtに変換したいんですけどうまくいきません。fopenとfreadでバイナリファイルを読み込むところまで入っていると思うんですけど、テキストファイルとして書き出すことができません。 #include <stdio.h> main() { short a[32000]; FILE *infile, *outfile; infile = fopen("iroha.x86", "r"); outfile = fopen("iroha.dat", "w+"); fread( a, sizeof(short), 32000, infile ); fwrite( a, sizeof(short), 32000, outfile ); fclose(infile); fclose(outfile); } これだとそのまんま出力されるんです。当たり前なんですけど... どこをどう変えればいいか教えてください。 よろしくお願いします。

  • PHPとJavaでSHA256の結果を同じにしたい

    PHPから JavaServletにアクセスするシステムを作っています。 その際にパラメーターの改ざん対策にハッシュを渡すようにしたいのですが PHPでSHA-256でハッシュ化した値と JavaでSHA-256でハッシュかした値が異なってしまいます。 PHPだとハッシュ化する際の秘密鍵を指定する項目がありますが Javaでは見つかりませんでしたので この項目が違うために結果が違うのだと予想していますが Javaが内部的に使っている秘密鍵はどこか取得できるのでしょうか? やりたいこととしてはPHPとJavaで同じハッシュが取得できるようにしたいのですが 良い案とかやり方あったら教えてください。 ◆php string hash_hmac ( string $algo , string $data , string $key [, bool $raw_output = false ] ) ◆Java DigestUtils.sha256Hex(string data) わかる方いましたら教えてください。よろしくお願いいたします。

    • ベストアンサー
    • Java
  • perlで指定範囲を複数ファイルに分割する方法は?

    お世話になります。 perlを使用して、 下記の元ファイル[infile.txt]よりstart~endの範囲を各テキストファイルに 分割出力する方法をご教授いただけないでしょうか。  ※出力ファイル名は元のファイル名 (infile) + 1行目の文字列(単語)にします。   例>>infile_1111.txt , infile_333.txt よろしくお願いいたします。 [infile.txt] aaaa bbbb start 1111 2222 end dddd eeee start 3333 4444 end

  • 文字数の短いユニークなID生成

    以下のようにして文字数の短いユニークなID生成をしようとしていますが、Digest::SHA1を使って生成したものをsubstrで先頭から任意の文字数でカットしてしまったものは「ユニークなID」という資質を保っているのでしょうか? メール本文にURLを記載することを前提としているので、Digest::SHA1で生成した段階のものでは文字数が長過ぎてURLとして認識されないため、このように生成されたものをカットしています。 use Digest::SHA1 qw(sha1_hex); $yourid = substr(&genUniqID,0,15); sub genUniqID{ my $word = shift || 'anyone'; my $id = join('' , $ENV{'HTTP_USER_AGENT'} , time , rand(9999) , $word ); return(sha1_hex($id)); }

    • ベストアンサー
    • Perl
  • perl 5.8.8 日本語マッチ

    perl5.8.8を使っています。 日本語にマッチする正規表現を書きたいのですが、どうしてもマッチしません。 例えば、以下のファイルtest.txtから「さしすせそ」だけを抽出し、表示させたいです。 ---------test.txt-------------------------------- あいうえお かきくけこ さしすせそ たちつてと -------------------------------------------------- ----------test.pl-------------------------------- use strict; use warnings; open(FILE, 'test.txt') or die "$!"; my @file = <FILE>; close(FILE); foreach my $line (@file){ if($line =~ /^さ/){ print "$line\n"; } } ------------------------------------------------ このtest.plを実行しても「さしすせそ」を抽出することが できません。 どうしたらよいのでしょうか? 自宅の新しいバージョンのperlだとできるのですが 会社のperlは5.8.8で顧客環境でもあるのでバージョンアップも できません。 すみませんが、よろしくお願いいたします。

    • ベストアンサー
    • Perl
  • Perlで作成したCGIについて

    Perlで作成したCGIについて Perlで作成したCGIについて質問させていただきます。 #################### ##(1)system.cgi ## #################### #!c:/Perl/bin/perl.exe use strict; use warnings; use CGI; use CGI::Carp('fatalsToBrowser'); use CGI qw(:standard); print "Content-type:text/html;charset=utf8\n\n"; system('C:\\test.txt'); ##################################################### C直下にあるtest.txtの中身は「abcd」など 簡単なものです。 ##################################################### ################### ##(2)win32.cgi ## ################### #!c:/Perl/bin/perl.exe use strict; use warnings; use CGI; use CGI::Carp('fatalsToBrowser'); use CGI qw(:standard); use Win32::API; print "Content-type:text/html;charset=utf8\n\n"; my $MessageBox = Win::API -> new("user32","MessageBoxA","NPPN","N"); $MessageBox -> Call(0,"HelloWorld","Message",0); ##################################################### ##################################################### 以下にスペックを書きます。 Microsoft Windows XP Professional version2002 Service Pack2 Genuine Intel(R)CPU L2300 @1.50GHz 1.50GHz,1.49GB RAM ・ActivePerl ver5.10.1 built for MSWin32-x86-multi-thread ・Apache Apache 2.2.14(Win32) ##################################################### 上記の(1)、(2)のプログラムをエクスプローラ上(ローカル)で実行させて(1)ではテキストファイルを、 (2)ではメッセージボックスを表示させたいです。 結果は時間がかかるだけでTimeOutの設定である5分で切れてしまい何も起こりません。 しかし、全く同じプログラムで拡張子を.plに変更してコマンドプロンプトで実行すると、 期待通り(1)はテキストファイルが開かれ、(2)ではメッセージボックスが出てきます。 (1)、(2)ともCGIではsystemおよびMessageBoxの部分をコメントアウトして print文などを書けば普通にエクスプローラに表示されます。 (かなりhtmlとしては不備があると思いますが・・・) どうすればCGIで(1)、(2)のプログラムが期待通りの動きをするのか どうぞご教授のほどよろしくお願いいたします。 何か足りない情報や意味の分かりづらい個所がありましたら、仰ってください。 ちなみにこのプログラムは公開するために作成しているのではありません。 下手な説明、長文すみません。

  • C言語

    ファイルデータ(11,22,33,0,44)を読み込んで表示することを5回繰り返すプログラムを作りたいのですが分かりません。 さらに出来ればファイルデータが0でなければ表示し、0を読み込んだら終了するwhile文でのプログラムも教えてください。 途中経過 #include <stdlib.h> #include <stdio.h> int main(void) { int x = 0,i; FILE *infile; infile = fopen ("test.txt", "r"); if(infile == NULL) { fprintf(stderr, "test.txtが開けません\n"); exit(1); } i = 0 while(1){ i++; fscanf(infile, "%d", &x); printf("%d\n", x); if(i = 5)break; } fclose(infile); return 0; } ここまでで実行すると11しか表示されません。 これまでの質問分かるかたどなたか教えてくださいお願いします。

  • SHA1ハッシュの生成結果が異なる理由とは

    Windows で Digest::SHA1 というモジュールを使って 文字列のSHA1ハッシュを生成するプログラムを作ったのですが、 $x = <STDIN>; と書き、100 と入力して生成したハッシュと、 あらかじめ $x = 100; のように設定しておいて生成したハッシュとでは、内容が異なっています。 前者は 310b86......、後者は 6a2903...... と出ます。 これはなぜでしょうか? 一致させるにはどうすれば良いのでしょうか。 ご教示ください。よろしくお願いいたします。

    • ベストアンサー
    • Perl

専門家に質問してみよう