/*!
@file signatuan.cpp
@auther d金魚
@note

This source code licence :

Boost Licence 1.0
(See at http://www.boost.org/LICENSE_1_0.txt)
 or
NYSL

@version 0.005

@section history 更新情報
0.006

- テンポラリバッファを1MBに変更
- ハッシュバッファのサイズが少なすぎたのを改善
- boost::progressつけてみた。

0.005
- なんか上手くシグネチャが出力できないので
要因:http://d.hatena.ne.jp/studiokingyo/20040516#p1
そこを改善

よって0.004以下のソースは粗大塵に認定

@todo
0.006

0.005

- ソースコードをきれいにする。

- SHA256とSHA512の結果が同じになる原因を究明する


0.004
file_listupperは指定フォルダ内にファイル数が多いとちと、酷な場面がある。
なので独自のfile_listup機構をfindfile_baseクラスから作ったほうが賢明かもしれない。

boost::progress みたいなの使って進行状況でも表示できるようにするか?

コマンドライン解析をつけるか?

0.003
このソースは毎回fopenしてfreadしているからちょっと効率が悪い・・・。もう少しどうにかせねば。
FileToSignature関数内部にハッシュやCRCのLoad関数を仕掛ければもっと効率が良くなるかも!?

0.002
もうこのソースは駄目だ。
scoped_file_bufferは超でかいファイルを読み込むことが出来ない。(100MBクラスのファイルとか)
メモリ上に展開なんてやってられねぇぜ!
でも、ちっこいファイルだったら使えるみたいね。

*/


const double version_double = 0.005;


#define DKUTIL_MSVC_IMPORT_LIB
#include <dkutil/include/dkutilAllInclude.h>

#include <dkutil/dkutilUtility.h>
using namespace dkutil;

#include <boost/progress.hpp>




class SignatuanApp : public ConsoleApplication{
public:

  enum{
    flagMD5,
    flagSHA1,
    flagSHA256,
    flagSHA512,
    flagCRCLEFT32,
    flagCRCRIGHT32,
    flagCRCLEFT16,
    flagCRCRIGHT16,
    flagPrintf = 100,
    flagMessageBox,
  };
private:
  ///どのシグネチャを出力するかのフラグマネージメント
  dkutil::FlagManager mFlags;
  ///出力方法フラグ
  int mOutputFlag;
  ///ファイルのテンポラリバッファのサイズ
  size_t mFileBuffSize;
public:
  SignatuanApp(){
    setFlag(flagMD5,true);
    setFlag(flagSHA1,true);
    setFlag(flagSHA256,true);
    setFlag(    flagSHA512,true);
    setFlag(    flagCRCLEFT32,true);
    setFlag(    flagCRCRIGHT32,true);
    setFlag(    flagCRCLEFT16,true);
    setFlag(    flagCRCRIGHT16,true);
    setOutputFlag(flagPrintf);
    setBufferSize(1024 * 1024);//1MB
  }
  void setFlag(UINT number,bool flag){
    mFlags.setFlag(number,flag);
  }
  bool getFlag(UINT ff)const{
    return mFlags.getFlag(ff);
  }
  void setOutputFlag(int flag){
    mOutputFlag = flag;
    }
  int getOutputFlag()const{
    return mOutputFlag;
    }

  ///ファイルが見つからない時用myprintf
  void not_found_file_printf(const char *filename){
    myprintf("%sは見つかりません。\n",filename);
  }
  ///ハッシュ値をmyprintf
  void hash_printf(const char *hash_name,const unsigned char *str){
    myprintf("%s:%s\n",hash_name,str);
  }
  ///CRCをpritnf
  void crc_printf(const char *crc_name,unsigned long crc){
    myprintf("%s:%08lX\n",crc_name,crc);
  }
  ///@return ファイルが存在しないとFALSE
  bool fileoption_printf(const char *filename){
    DWORD h,l;
    if(false==GetFileSizeHighLow(filename,&h,&l)){
      return false;
    }

    ULONGLONG ull = (h << 32) + l;
    
    if(LONGLONG_MAX <= ull){
      myprintf("FileName:%s\n Size:約%d MB, 約%d KB, %d bytes \n",
        filename,
        ull / 1024 / 1024,
        ull / 1024,
        ull);
    }else{
    
      std::string mb = to_string((double)(LONGLONG)ull / 1024 / 1024);
      std::string kb = to_string((double)(LONGLONG)ull / 1024);
      myprintf("FileName:%s\n Size:%s MB, %s KB, %d bytes \n",
        filename,
        mb.c_str(),
        kb.c_str(),
        ull);
    }
    return true;
  }
  ///CRC値を取得
  static std::string crc_to_string(unsigned long crc){
    std::string buff;
    buff = boost::io::str( 
      boost::format("%08lX") % crc
    );
    return buff;
  }
  ///ハッシュ値を出力
  void hash_value_output(const char *filename,const char *title,BYTE *hashvalue,int flag){
    switch(flag){
    case flagMessageBox:
      dMB(title,"%s:\n%s:%s",filename,title,hashvalue);
      break;
    case flagPrintf:
    default:
      hash_printf(title,hashvalue);
    }
  }
  ///hash値をプリント
  void hash_print(Hash_Adapter_Interface *ptr,const char *filename,const char *title,int flag)
  {
    ///ヘナチョコユーティリティ
    //dkutilUtility ope;

    BYTE hashvalue[1024 * 2]="";
    if(false==ptr->FileToSignature(filename,hashvalue,sizeof(hashvalue)))
    {
      not_found_file_printf(filename);
      return;
    }
    hash_value_output(filename,title,hashvalue,flag);
  }
  ///crc値を出力
  void crc_value_output(const char *filename,const char *title,UINT crc,int flag){
    switch(flag){
    case flagMessageBox:
      dMB(title,"%s:\n%s:%s",
        filename,title,
        crc_to_string(crc).c_str());
      break;
    case flagPrintf:
    default:
      crc_printf(title,crc);
    }
  }
  void crc_print(CRC_Adapter_Interface *ptr,const char *filename,const char *title,int flag)
  {
    UINT crc = 0;
    
    bool r = ptr->FileToSignature(filename,(BYTE *)&crc,sizeof(crc),sizeof(crc));
    if(false==r)
    {//見つからないとき〜〜
      not_found_file_printf(filename);
      return;
    }
    crc_value_output(filename,title,crc,flag);
  }

  ///バッファのサイズを設定
  void setBufferSize(size_t size){
    mFileBuffSize = size;
  }
  ///バッファのサイズを取得
  size_t getBufferSize()const{
    return mFileBuffSize;
    }
  /*!
  @param filename[in] ファイル名
  @param c[in][out] std::string指定の入っているコンテナ 例:std::list<std::string> とかとか
  */
  ///シグネチャをゲットする。
  template<class Container__>
  bool getSignature(const char *filename,Container__ &c,bool withname=true){
    size_t buffsize = getBufferSize();
    int flag = getOutputFlag();
#  define WITH_S(s) if(withname){c.push_back(std::string(s) + " : ");}


    file_operator op(filename,"rb");
    if(false==op.open()){
      not_found_file_printf(filename);
      return false;
    }

    //シグネチャ確認オブジェクト郡
    MD5_Adapter md5;
    SHA1_Adapter sha1;
    SHA256_Adapter sha256;
    SHA512_Adapter sha512;
    policy::crc32_left cl32;
    policy::crc32_right cr32;
    policy::crc16_left cl16;
    policy::crc16_right cr16;
    //初期化
    md5.Init();
    sha1.Init();
    sha256.Init();
    sha512.Init();
    cl32.Init();
    cr32.Init();
    cl16.Init();
    cr16.Init();



    //hash値格納バッファこのくらいあれば十分だな^^;
    scoped_buffer_byte hbuf(sha512.hash_size() * 3);

    //ファイルバッファ
    scoped_buffer_byte buff(buffsize);
    op.seek(0,SEEK_SET);

    boost::progress_display prog(op.size());
    while(1){
      size_t n = op.read(buff.get(),buff.size());
      if(op.error()){
        printf("%s ファイルの読み込み中にエラーが発生しました。",filename);
        return false;
      }
      if(n==0 && op.eof()){//しっかりこう実装しないと・・・。
        break;
      }
      //hash
      if(getFlag(flagMD5)){
        md5.Load((BYTE *)buff.get(),n);
      }
      if(getFlag(flagSHA1)){
        sha1.Load((BYTE *)buff.get(),n);
      }
      if(getFlag(flagSHA256)){
        sha256.Load((BYTE *)buff.get(),n);
      }
      if(getFlag(flagSHA512)){
        sha512.Load((BYTE *)buff.get(),n);
      }
      //crc
      if(getFlag(flagCRCLEFT32)){
        cl32.Load((BYTE *)buff.get(),n);
      }
    
      if(getFlag(flagCRCRIGHT32)){
        cr32.Load((BYTE *)buff.get(),n);
      }

      if(getFlag(flagCRCLEFT16)){
        cl16.Load((BYTE *)buff.get(),n);
      }
      if(getFlag(flagCRCRIGHT16)){
        cr16.Load((BYTE *)buff.get(),n);
      }

      prog += n;

      
    }//end of while

    //hash
    if(getFlag(flagMD5)){
      md5.Final();
      md5.GetDigest(hbuf.get(),hbuf.size());
      WITH_S("md5");
      c.push_back((char *)hbuf.get());
    }
    if(getFlag(flagSHA1)){
      sha1.Final();
      sha1.GetDigest(hbuf.get(),hbuf.size());
      WITH_S("sha1");
      c.push_back((char *)hbuf.get());
    }
    if(getFlag(flagSHA256)){
      sha256.Final();
      sha256.GetDigest(hbuf.get(),hbuf.size());
      WITH_S("sha256");
      c.push_back((char *)hbuf.get());
    }
    if(getFlag(    flagSHA512)){
      sha512.Final();
      sha512.GetDigest(hbuf.get(),hbuf.size());
      WITH_S("sha512");
      c.push_back((char *)hbuf.get());
    }

    //crc

    if(getFlag(flagCRCLEFT32)){
      cl32.Final();
      WITH_S("crc32 left");
      c.push_back(crc_to_string(cl32.GetDigest()));
    }
    
    if(getFlag(flagCRCRIGHT32)){
      cr32.Final();
      WITH_S("crc32 right");
      c.push_back(crc_to_string(cr32.GetDigest()));
    }

    if(getFlag(flagCRCLEFT16)){
      cl16.Final();
      WITH_S("crc16 left");
      c.push_back(crc_to_string(cl16.GetDigest()));
    }
    if(getFlag(flagCRCRIGHT16)){
      cr16.Final();
      WITH_S("crc16 right"); 
      c.push_back(crc_to_string(cr16.GetDigest()));
      
    }
#  undef WITH_S
    return true;

  }
  void signature_print(const char *filename){//512KB
    typedef std::list<std::string> LT;
    LT c;
    if(false==getSignature(filename,c)){
      return;
    }
    printf("\n");
    
    size_t i=1;

    for(
      LT::iterator it = c.begin();
      it != c.end();
      it++,i++)
    {
      if(i % 2 == 0){
        printf("%s\n",(*it).c_str());
      }else{
        printf("%s",(*it).c_str());
      }
    }
    
    /*
    size_t buffsize = getBufferSize();
    int flag = getOutputFlag();


    file_operator op(filename,"rb");
    if(false==op.open()){
      not_found_file_printf(filename);
      return;
    }

    //シグネチャ確認オブジェクト郡
    MD5_Adapter md5;
    SHA1_Adapter sha1;
    SHA256_Adapter sha256;
    SHA512_Adapter sha512;
    policy::crc32_left cl32;
    policy::crc32_right cr32;
    policy::crc16_left cl16;
    policy::crc16_right cr16;
    //初期化
    md5.Init();
    sha1.Init();
    sha256.Init();
    sha512.Init();
    cl32.Init();
    cr32.Init();
    cl16.Init();
    cr16.Init();

    //hash値格納バッファこのくらいあれば十分だな^^;
    scoped_buffer_byte hbuf(sha512.hash_size() * 3);

    //ファイルバッファ
    scoped_buffer_byte buff(buffsize);
    while(1){
      size_t n = op.read(buff.get(),buff.size());
      if(n <= 0) break;
      feofとかferrorとか
        //hash
      if(getFlag(flagMD5)){
        md5.Load((BYTE *)buff.get(),buff.size());
      }
      if(getFlag(flagSHA1)){
        sha1.Load((BYTE *)buff.get(),buff.size());
      }
      if(getFlag(flagSHA256)){
        sha256.Load((BYTE *)buff.get(),buff.size());
      }
      if(getFlag(flagSHA512)){
        sha512.Load((BYTE *)buff.get(),buff.size());
      }
      //crc
      if(getFlag(flagCRCLEFT32)){
        cl32.Load((BYTE *)buff.get(),buff.size());
      }
    
      if(getFlag(flagCRCRIGHT32)){
        cr32.Load((BYTE *)buff.get(),buff.size());
      }

      if(getFlag(flagCRCLEFT16)){
        cl16.Load((BYTE *)buff.get(),buff.size());
      }
      if(getFlag(flagCRCRIGHT16)){
        cr16.Load((BYTE *)buff.get(),buff.size());
      }
      
    }//end of while

    //hash
    if(getFlag(flagMD5)){
      md5.Final();
      md5.GetDigest(hbuf.get(),hbuf.size());
      hash_value_output(filename,"MD5",hbuf.get(),flag);
    }
    if(getFlag(flagSHA1)){
      sha1.Final();
      sha1.GetDigest(hbuf.get(),hbuf.size());
      hash_value_output(filename,"SHA1",hbuf.get(),flag);
    }
    if(getFlag(flagSHA256)){
      sha256.Final();
      sha256.GetDigest(hbuf.get(),hbuf.size());
      hash_value_output(filename,"SHA256",hbuf.get(),flag);
    }
    if(getFlag(    flagSHA512)){
      sha512.Final();
      sha512.GetDigest(hbuf.get(),hbuf.size());
      hash_value_output(filename,"SHA512",hbuf.get(),flag);
    }

    //crc

    if(getFlag(    flagCRCLEFT32)){
      cl32.Final();
      crc_value_output(filename,"crc32_left",cl32.GetDigest(),flag);
    }
    
    if(getFlag(    flagCRCRIGHT32)){
      cr32.Final();
      crc_value_output(filename,"crc32_right",cr32.GetDigest(),flag);
    }

    if(getFlag(    flagCRCLEFT16)){
      cl16.Final();
      crc_value_output(filename,"crc16_left",cl16.GetDigest(),flag);
    }
    if(getFlag(    flagCRCRIGHT16)){
      cr16.Final();
      crc_value_output(filename,"crc16_right",cr16.GetDigest(),flag);
    }
    */

  }

  virtual int mymain(int argc,char *argv[]){
    printf("signatuan v %f\n",version_double);

    int i,result = edk_FAILED;
    if(1 >= argc)
    {//なんかファイルが指定されていないみたいですねぇ。
      for(i=0;i<1;i++)
      {
        myprintf("%s\n",argv[i]);
      }
      std::string str = "ファイル名を実行ファイル名の後に半角スペースを空けて入れてください。\n";
      str += "ファイル名に半角スペースが混じっている場合は\" \"(ダブルクォーテーション)でくくってください。\n";
      setUsage(str);
      usage();
      goto End;
    }
    for(i=1;i<argc;i++)
    {//よっしゃ!ハッシュとCRCをしらべたろかい!!ってね^^
      /*if(0==i){
        continue;
      }*/

      size_t len = strlen(argv[i]);
      if(FALSE==dkcIsNativePathString(argv[i],len))
      {//uneffective
        myprintf("OPERATION:%s\n",argv[i]);

        file_listupper up;
        if(false==up.reset(argv[i],SafeGetCurrentDirectory().c_str(),false))
        {
          error_printf("file_listupper reset():%s\n",argv[i]);
          win32lasterror_printf();
          continue;
        }
        if(false==up.find()){
          error_printf("file_listupper find():%s",argv[i]);
          win32lasterror_printf();
          continue;
        }
        file_listupper::iterator it = up.begin();
        for(;it != up.end();it++)
        {
          fileoption_printf((*it).c_str());
          signature_print((*it).c_str());
          line_printf();
        }

      }else{//effective
        fileoption_printf(argv[i]);

        signature_print(argv[i]);
        line_printf();
      }


    }





    //見事にエラー無しで終了!!
    result = 0;

  End:
  #ifdef DEBUG
    system("PAUSE");
  #endif
    return result;


  }


};


int main(int argc,char *argv[])
{
  SignatuanApp app;
  return app.mymain(argc,argv);
}
SEO [PR] 爆速!無料ブログ 無料ホームページ開設 無料ライブ放送