/*!
@file signatuan.cpp
@auther d金魚
@note
This source code licence is Boost Licence 1.0
(See at http://www.boost.org/LICENSE_1_0.txt)
@version 0.003
@todo
このソースは毎回fopenしてfreadしているからちょっと効率が悪い・・・。もう少しどうにかせねば。
FileToSignature関数内部にハッシュやCRCのLoad関数を仕掛ければもっと効率が良くなるかも!?
*/
#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;
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);
}
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;
}
///ファイルが見つからない時用myprint
void not_found_file_printf(const char *filename){
myprint("%sは見つかりません。\n",filename);
}
///ハッシュ値をmyprint
void hash_printf(const char *hash_name,const unsigned char *str){
myprint("%s:%s\n",hash_name,str);
}
///CRCをpritnf
void crc_printf(const char *crc_name,unsigned long crc){
myprint("%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;
myprint("FileName:%s , Size:%d\n",filename,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;
}
///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;
}
switch(flag){
case flagMessageBox:
dMB(title,"%s:\n%s:%s",filename,title,hashvalue);
break;
case flagPrintf:
default:
hash_printf(title,hashvalue);
}
}
///dkutilに実装されているハッシュ関数をすべて通す。
void all_hash_print(const char *filename,int flag){
SHA1_Adapter sha1;
SHA256_Adapter sha256;
SHA512_Adapter sha512;
MD5_Adapter md5;
//テーブルを作る。
Hash_Adapter_Interface *table[]={
&md5,&sha1,&sha256,&sha512,NULL//番兵としてNULLを最後に入れておく
};
char *title[]={
"MD5","SHA1","SHA256","SHA512",NULL
};
///tableが終端になるまでループ
for(int i=0;table[i] != NULL;i++)
{
hash_print(table[i],filename,title[i],flag);
}
}
void crc_print(CRC_Adapter_Interface *ptr,const char *filename,const char *title,int flag)
{
UINT crc = 0;
bool r = ptr->FileToSignature(filename,&crc);
if(false==r)
{//見つからないとき〜〜
not_found_file_printf(filename);
return;
}
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);
}
}
///dkutilに実装されているすべてのcrcを通す。
void all_crc_print(const char *filename,int flag){
///ファイルをメモリ上に展開するバッファ
scoped_file_buffer<BYTE> buff(filename);
if(false==buff.isValid()){
not_found_file_printf(filename);
return;
}
using namespace dkutil::policy;
CRC_Adapter<policy::crc32_left> cl32;
CRC_Adapter<policy::crc32_right> cr32;
CRC_Adapter<policy::crc16_left> cl16;
CRC_Adapter<policy::crc16_right> cr16;
CRC_Adapter_Interface *table[]={
&cl32,&cr32,&cl16,&cr16,NULL
};
char *title[]={
"crc32_left","crc32_right","crc16_left","crc16_right",NULL
};
/*{
scoped_file_buffer<BYTE> buf(filename);
DKUTIL_NOT_ASSERT(false==buf.isValid());
crc1 ccc;
myprint("crc1() = %08lX\n", ccc.crc(buf.size(),buf.get()));
file_operator op(filename,"rb");
if(false==op.open()) return false;
inte->Init();
scoped_buffer buff(buffsize);
while(1){
size_t n = op.read(buff.get(),buff.size());
if(n <= 0) break;
inte->Load((BYTE *)buff.get(),buff.size());
}
}*/
///tableが終端になるまでループ
for(int i=0;table[i] != NULL;i++){
crc_print(table[i],filename,title[i],flag);
}
}
void signature_print(const char *filename){
int flag;
flag = getOutputFlag();
//hash
if(getFlag(flagMD5)){
MD5_Adapter md5;
hash_print(&md5,filename,"MD5",flag);
}
if(getFlag(flagSHA1)){
SHA1_Adapter sha1;
hash_print(&sha1,filename,"SHA1",flag);
}
if(getFlag(flagSHA256)){
SHA256_Adapter sha256;
hash_print(&sha256,filename,"SHA256",flag);
}
if(getFlag( flagSHA512)){
SHA512_Adapter sha512;
hash_print(&sha512,filename,"SHA512",flag);
}
//crc
if(getFlag( flagCRCLEFT32)){
CRC_Adapter<policy::crc32_left> cl32;
crc_print(&cl32,filename,"crc32_left",flag);
}
if(getFlag( flagCRCRIGHT32)){
CRC_Adapter<policy::crc32_right> cr32;
crc_print(&cr32,filename,"crc32_right",flag);
}
if(getFlag( flagCRCLEFT16)){
CRC_Adapter<policy::crc16_left> cl16;
crc_print(&cl16,filename,"crc16_left",flag);
}
if(getFlag( flagCRCRIGHT16)){
CRC_Adapter<policy::crc16_right> cr16;
crc_print(&cr16,filename, "crc16_right",flag);
}
}
virtual int mymain(int argc,char *argv[]){
int i,result = edk_FAILED;
if(1 >= argc)
{//なんかファイルが指定されていないみたいですねぇ。
for(i=0;i<1;i++)
{
myprint("%s",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
myprint("OPERATION:%s\n",argv[i]);
file_listupper up;
if(false==up.reset(argv[i],SafeGetCurrentDirectory().c_str(),false))
{
myprint("Error:%s",argv[i]);
continue;
}
if(false==up.find()){
myprint("Error:%s",argv[i]);
continue;
}
file_listupper::iterator it = up.begin();
for(;it != up.end();it++)
{
fileoption_printf((*it).c_str());
signature_print((*it).c_str());
line_print();
}
}else{//effective
fileoption_printf(argv[i]);
signature_print(argv[i]);
line_print();
}
}
//見事にエラー無しで終了!!
result = 0;
End:
#ifdef DEBUG
Sleep(5000);
#endif
return result;
}
};
int main(int argc,char *argv[])
{
SignatuanApp app;
return app.mymain(argc,argv);
}