/*!
@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
@todo
0.005
なんか上手くシグネチャが出力できないので
要因:http://d.hatena.ne.jp/studiokingyo/20040516#p1
そこを改善
よって0.004以下のソースは粗大塵に認定
0.004
file_listupperは指定フォルダ内にファイル数が多いとちと、酷な場面がある。
なので独自のfile_listup機構をfindfile_baseクラスから作ったほうが賢明かもしれない。
boost::progress みたいなの使って進行状況でも表示できるようにするか?
コマンドライン解析をつけるか?
0.003
このソースは毎回fopenしてfreadしているからちょっと効率が悪い・・・。もう少しどうにかせねば。
FileToSignature関数内部にハッシュやCRCのLoad関数を仕掛ければもっと効率が良くなるかも!?
0.002
もうこのソースは駄目だ。
scoped_file_bufferは超でかいファイルを読み込むことが出来ない。(100MBクラスのファイルとか)
メモリ上に展開なんてやってられねぇぜ!
でも、ちっこいファイルだったら使えるみたいね。
*/
#define DKUTIL_MSVC_IMPORT_LIB
#include <dkutil/include/dkutilAllInclude.h>
#include <dkutil/dkutilUtility.h>
using namespace dkutil;
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 * 512);//512KB
}
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(md5.hash_size() * 3);
//ファイルバッファ
scoped_buffer_byte buff(buffsize);
op.seek(0,SEEK_SET);
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);
}
}//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;
getSignature(filename,c);
for(LT::iterator it = c.begin();it != c.end();it++){
printf("%s\n",(*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[]){
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);
}