Linux编程实现制作文件的ed2k链
本程序依赖c99,只支持终端“标准输入”,转换成的链接以”标准输出“而输出,错误以”标出错误输出“而输出。
md4编码代码来自网络。
编译命令:gcc-std=c99-oed2kmd4.c ed2k.c utils.c
用户命令:ed2k<File...>
产生的链是最简短的形式:ed2k://|file|<FileName>|<FileSize>|<FileHash>|/
c++版本:
编译命令:g++-oed2ked2k.cpputils.cppMD4Hash.cppED2KHash.cpp
用户命令:ed2k<File...> (虽然--help可以看到其它选项,但都没实现)
defs.h
#ifndefMYCODE_DEFS_H
#defineMYCODE_DEFS_H
#include<stdint.h>/*uint32_t...*/
#include<stddef.h>/*size_t,ssize_t*/
#include<stdbool.h>
#endif
#if__cplusplus
#defineBEGIN_NAMESPACE_MYCODEnamespacemc{
#defineEND_NAMESPACE_MYCODE}
#if__cplusplus<201103L
#definenullptr((void*)0)
#endif
#endif/*__cplusplus*/
#endif/*MYCODE_DEFS_H*/
utils.h
#ifndefMYCODE_UTILS_H
#defineMYCODE_UTILS_H
#include<stdio.h>
#if__cplusplus
#include<utility>
#include<string>
#include<fstream>
#endif/*__cplusplus*/
#include"defs.h"
#if__cplusplus
extern"C"{
#endif
#undefbyteswap32
#definebyteswap32(x)\
((((x)&0xff000000)>>24)|(((x)&0x00ff0000)>>8)|\
(((x)&0x0000ff00)<<8)|(((x)&0x000000ff)<<24))
#undefhtobe32
#undefhtole32
#if__BYTE_ORDER==__LITTLE_ENDIAN
#definehtobe32(x)byteswap32(x)
#definehtole32(x)(x)
#else
#definehtobe32(x)(x)
#definehtole32(x)byteswap32(x)
#endif
enum{string_npos=(size_t)-1};
/*查找字符串str中第一个与c匹配的字符,返回该字符在字符串中的下标,失败返回string_npos*/
size_tstring_find(constchar*str,size_tsize,charc);
/*逆向查找*/
size_tstring_rfind(constchar*str,size_tsize,charc);
voidsetBigEndian_uint32(uint32_t*data,size_tn);
char*toHexString_uint32(char*buf,size_tbufSize,
constuint32_t*data,size_tn);
char*createShortFileName(char*buf,size_tbufSize,
constchar*fullName,size_tsize);
/*成功时返回指针fullName某部分的地址,失败时返回NULL*/
constchar*getShortFileName(constchar*fullName,size_tsize);
/*当返回0大小时,需要检查state,state==0表示失败*/
size_tgetFileSize(FILE*in,int*state);
#if__cplusplus
}/*extern"C"*/
#endif
/******************************************************************************
*c++
*****************************************************************************/
#if__cplusplus
BEGIN_NAMESPACE_MYCODE
#if__cplusplus>=201103L
#definemc_move(x)std::move(x)
#else
#definemc_move(x)(x);
#endif
///////////////////////////////////////////////////////////////////////////////
template<classT>
voidsetBigEndian(T*,size_t);
template<>
inlinevoidsetBigEndian<uint32_t>(uint32_t*p,size_tn)
{setBigEndian_uint32(p,n);}
///////////////////////////////////////////////////////////////////////////////
template<classT>
std::stringtoHexString(T*,size_t);
template<>
inlinestd::stringtoHexString<uint32_t>(uint32_t*p,size_tn)
{
std::stringstrHex;
charbuf[9];
for(size_ti=0;i<n;++i){
sprintf(buf,"%08X",p[i]);
strHex+=buf;
}
returnmc_move(strHex);
}
///////////////////////////////////////////////////////////////////////////////
std::stringgetShortFileName(conststd::string&fullName);
voidgetShortFileName(std::string*shortName,conststd::string&fullName);
size_tgetFileSize(std::ifstream&f);
END_NAMESPACE_MYCODE
#endif/*__cplusplus*/
#endif/*MYCODE_UTILS_H*/
utils.c
#include"utils.cpp"
utils.cpp
#include<string.h>
#include"utils.h"
#if__cplusplus
extern"C"{
#endif
voidsetBigEndian_uint32(uint32_t*data,size_tn)
{
for(size_ti=0;i<n;++i)
data[i]=htobe32(data[i]);
}
char*toHexString_uint32(char*buf,size_tbufSize,constuint32_t*data,size_tn)
{
char*p=buf;
size_ti=0;
size_tone_uint32_size=sizeof(uint32_t);
if(one_uint32_size*n<bufSize)
{
while(i<n){
sprintf(p,"%08X",data[i++]);
p+=8;
}
}
*p='\0';
returnbuf;
}
size_tstring_find(constchar*str,size_tsize,charc)
{
size_tpos=0;
while(pos<size){
if(str[pos]==c)
returnpos;
++pos;
}
returnstring_npos;
}
size_tstring_rfind(constchar*str,size_tsize,charc)
{
while(size){
if(str[--size]==c)
returnsize;
}
returnstring_npos;
}
char*createShortFileName(char*buf,size_tbufSize,
constchar*fullName,size_tsize)
{
constchar*p=getShortFileName(fullName,size);
buf[0]='\0';
if(p)
{
size_tlen=strlen(p);
if(bufSize>len)
memcpy(buf,p,len+1);
}
returnbuf;
}
constchar*getShortFileName(constchar*fileName,size_tsize)
{
#if_WIN32
charc='\\';
#else
charc='/';
#endif
size_tpos=string_rfind(fileName,size,c);
if(pos==string_npos)
returnNULL;
else
returnfileName+(pos+1);
}
size_tgetFileSize(FILE*in,int*state)
{
*state=0;
if(!in)
return0;
size_tcurpos=ftell(in);
if(fseek(in,0,SEEK_END)==-1)
return0;
size_tfileSize=ftell(in);
if(fseek(in,curpos,SEEK_SET)==-1)
return0;
*state=1;
returnfileSize;
}
#if__cplusplus
}/*extern"C"*/
#endif
/******************************************************************************
*c++
*****************************************************************************/
#if__cplusplus
BEGIN_NAMESPACE_MYCODE
voidgetShortFileName(std::string*shortName,conststd::string&fullName)
{
#if_WIN32
charc='\\';
#else
charc='/';
#endif
size_tpos=fullName.rfind(c);
if(pos==std::string::npos)
shortName->assign(fullName);
else
shortName->assign(fullName.begin()+pos+1,fullName.end());
}
std::stringgetShortFileName(conststd::string&fullName)
{
std::stringshortName;
getShortFileName(&shortName,fullName);
returnmc_move(shortName);
}
size_tgetFileSize(std::ifstream&f)
{
f.seekg(0,f.end);
size_tfileSize=f.tellg();
f.seekg(0);
returnfileSize;
}
END_NAMESPACE_MYCODE
#endif/*__cplusplus*/
md4.h
#ifndefMYCODE_MD4_H
#defineMYCODE_MD4_H
#include"defs.h"
#if__cplusplus
extern"C"{
#endif
enum{MD4_COUNT_SIZE=8,MD4_STATE_SIZE=16,MD4_BUFFER_SIZE=64};
typedefstruct{
uint32_tcount[2];
uint32_tstate[4];
uint8_tbuffer[MD4_BUFFER_SIZE];
}md4_t;
#definemd4_data(md4_ptr)((char*)((md4_ptr)->state))
#definemd4_cdata(md4_ptr)((constchar*)((md4_ptr)->state))
#definemd4_dataSize()(MD4_STATE_SIZE)
voidmd4_reset(md4_t*md4);
voidmd4_update(md4_t*md4,constchar*src,size_tsrcSize);
voidmd4_finish(md4_t*md4);
voidmd4_setBigEndian(md4_t*md4);
char*md4_toHashString(chardest[33],constmd4_t*md4);
#if__cplusplus
}
#endif
#endif/*MYCODE_MD4_H*/
md4.c
/*#include<endian.h>*/
#include<stdio.h>
#include<string.h>
#include"utils.h"
#include"md4.h"
#if__cplusplus
extern"C"{
#endif
#if__BYTE_ORDER==__LITTLE_ENDIAN
#definemd4_htole32_4(buf)/*empty*/
#definemd4_htole32_14(buf)/*empty*/
#definemd4_htole32_16(buf)/*empty*/
#else
#definemd4_htole32_4(buf)\
(buf)[0]=htole32((buf)[0]);\
(buf)[1]=htole32((buf)[1]);\
(buf)[2]=htole32((buf)[2]);\
(buf)[3]=htole32((buf)[3])
#definemd4_htole32_14(buf)\
(buf)[0]=htole32((buf)[0]);\
(buf)[1]=htole32((buf)[1]);\
(buf)[2]=htole32((buf)[2]);\
(buf)[3]=htole32((buf)[3]);\
(buf)[4]=htole32((buf)[4]);\
(buf)[5]=htole32((buf)[5]);\
(buf)[6]=htole32((buf)[6]);\
(buf)[7]=htole32((buf)[7]);\
(buf)[8]=htole32((buf)[8]);\
(buf)[9]=htole32((buf)[9]);\
(buf)[10]=htole32((buf)[10]);\
(buf)[11]=htole32((buf)[11]);\
(buf)[12]=htole32((buf)[12]);\
(buf)[13]=htole32((buf)[13])
#definemd4_htole32_16(buf)\
(buf)[0]=htole32((buf)[0]);\
(buf)[1]=htole32((buf)[1]);\
(buf)[2]=htole32((buf)[2]);\
(buf)[3]=htole32((buf)[3]);\
(buf)[4]=htole32((buf)[4]);\
(buf)[5]=htole32((buf)[5]);\
(buf)[6]=htole32((buf)[6]);\
(buf)[7]=htole32((buf)[7]);\
(buf)[8]=htole32((buf)[8]);\
(buf)[9]=htole32((buf)[9]);\
(buf)[10]=htole32((buf)[10]);\
(buf)[11]=htole32((buf)[11]);\
(buf)[12]=htole32((buf)[12]);\
(buf)[13]=htole32((buf)[13]);\
(buf)[14]=htole32((buf)[14]);\
(buf)[15]=htole32((buf)[15])
#endif
/*#defineF1(x,y,z)(x&y|~x&z)*/
#defineF1(x,y,z)(z^(x&(y^z)))
#defineF2(x,y,z)((x&y)|(x&z)|(y&z))
#defineF3(x,y,z)(x^y^z)
/*ThisisthecentralstepintheMD4algorithm.*/
#defineMD4STEP(f,w,x,y,z,data,s)\
(w+=f(x,y,z)+data,w=w<<s|w>>(32-s))
staticvoidmd4_transform(uint32_t*state,constuint8_t*buffer)
{
uint32_ta,b,c,d;
constuint32_t*src=(constuint32_t*)buffer;
a=state[0];
b=state[1];
c=state[2];
d=state[3];
MD4STEP(F1,a,b,c,d,src[0],3);
MD4STEP(F1,d,a,b,c,src[1],7);
MD4STEP(F1,c,d,a,b,src[2],11);
MD4STEP(F1,b,c,d,a,src[3],19);
MD4STEP(F1,a,b,c,d,src[4],3);
MD4STEP(F1,d,a,b,c,src[5],7);
MD4STEP(F1,c,d,a,b,src[6],11);
MD4STEP(F1,b,c,d,a,src[7],19);
MD4STEP(F1,a,b,c,d,src[8],3);
MD4STEP(F1,d,a,b,c,src[9],7);
MD4STEP(F1,c,d,a,b,src[10],11);
MD4STEP(F1,b,c,d,a,src[11],19);
MD4STEP(F1,a,b,c,d,src[12],3);
MD4STEP(F1,d,a,b,c,src[13],7);
MD4STEP(F1,c,d,a,b,src[14],11);
MD4STEP(F1,b,c,d,a,src[15],19);
MD4STEP(F2,a,b,c,d,src[0]+0x5a827999,3);
MD4STEP(F2,d,a,b,c,src[4]+0x5a827999,5);
MD4STEP(F2,c,d,a,b,src[8]+0x5a827999,9);
MD4STEP(F2,b,c,d,a,src[12]+0x5a827999,13);
MD4STEP(F2,a,b,c,d,src[1]+0x5a827999,3);
MD4STEP(F2,d,a,b,c,src[5]+0x5a827999,5);
MD4STEP(F2,c,d,a,b,src[9]+0x5a827999,9);
MD4STEP(F2,b,c,d,a,src[13]+0x5a827999,13);
MD4STEP(F2,a,b,c,d,src[2]+0x5a827999,3);
MD4STEP(F2,d,a,b,c,src[6]+0x5a827999,5);
MD4STEP(F2,c,d,a,b,src[10]+0x5a827999,9);
MD4STEP(F2,b,c,d,a,src[14]+0x5a827999,13);
MD4STEP(F2,a,b,c,d,src[3]+0x5a827999,3);
MD4STEP(F2,d,a,b,c,src[7]+0x5a827999,5);
MD4STEP(F2,c,d,a,b,src[11]+0x5a827999,9);
MD4STEP(F2,b,c,d,a,src[15]+0x5a827999,13);
MD4STEP(F3,a,b,c,d,src[0]+0x6ed9eba1,3);
MD4STEP(F3,d,a,b,c,src[8]+0x6ed9eba1,9);
MD4STEP(F3,c,d,a,b,src[4]+0x6ed9eba1,11);
MD4STEP(F3,b,c,d,a,src[12]+0x6ed9eba1,15);
MD4STEP(F3,a,b,c,d,src[2]+0x6ed9eba1,3);
MD4STEP(F3,d,a,b,c,src[10]+0x6ed9eba1,9);
MD4STEP(F3,c,d,a,b,src[6]+0x6ed9eba1,11);
MD4STEP(F3,b,c,d,a,src[14]+0x6ed9eba1,15);
MD4STEP(F3,a,b,c,d,src[1]+0x6ed9eba1,3);
MD4STEP(F3,d,a,b,c,src[9]+0x6ed9eba1,9);
MD4STEP(F3,c,d,a,b,src[5]+0x6ed9eba1,11);
MD4STEP(F3,b,c,d,a,src[13]+0x6ed9eba1,15);
MD4STEP(F3,a,b,c,d,src[3]+0x6ed9eba1,3);
MD4STEP(F3,d,a,b,c,src[11]+0x6ed9eba1,9);
MD4STEP(F3,c,d,a,b,src[7]+0x6ed9eba1,11);
MD4STEP(F3,b,c,d,a,src[15]+0x6ed9eba1,15);
state[0]+=a;
state[1]+=b;
state[2]+=c;
state[3]+=d;
}
voidmd4_reset(md4_t*md4)
{
md4->count[0]=0;
md4->count[1]=0;
md4->state[0]=0x67452301;
md4->state[1]=0xEFCDAB89;
md4->state[2]=0x98BADCFE;
md4->state[3]=0x10325476;
}
voidmd4_update(md4_t*md4,constchar*src,size_tsrcSize)
{
uint32_tcount=(uint32_t)((md4->count[0]>>3)&0x3f);
if((md4->count[0]+=(srcSize<<3))<(srcSize<<3))
++(md4->count[1]);
md4->count[1]+=(srcSize>>29);
if(count>0)
{
size_tpartSize=MD4_BUFFER_SIZE-count;
if(srcSize<partSize)
{
memcpy(md4->buffer+count,src,srcSize);
return;
}
memcpy(md4->buffer+count,src,partSize);
md4_htole32_16((uint32_t*)md4->buffer);
md4_transform(md4->state,md4->buffer);
src+=partSize;
srcSize-=partSize;
}
while(srcSize>=MD4_BUFFER_SIZE)
{
memcpy(md4->buffer,src,MD4_BUFFER_SIZE);
md4_transform(md4->state,md4->buffer);
md4_htole32_16((uint32_t*)md4->buffer);
src+=MD4_BUFFER_SIZE;
srcSize-=MD4_BUFFER_SIZE;
}
memcpy(md4->buffer,src,srcSize);
}
voidmd4_finish(md4_t*md4)
{
uint32_tcount=(uint32_t)((md4->count[0]>>3)&0x3f);
uint8_t*p=md4->buffer+count;
*p++=0x80;
count=MD4_BUFFER_SIZE-1-count;
if(count<8)
{
memset(p,0,count);
md4_htole32_16((uint32_t*)md4->buffer);
md4_transform(md4->state,md4->buffer);
memset(md4->buffer,0,56);
}
else
{
memset(p,0,count-8);
}
md4_htole32_14((uint32_t*)md4->buffer);
/*Appendbitcountandtransform*/
((uint32_t*)md4->buffer)[14]=md4->count[0];
((uint32_t*)md4->buffer)[15]=md4->count[1];
md4_transform(md4->state,md4->buffer);
md4_htole32_4(md4->state);
memset(md4->buffer,0,MD4_BUFFER_SIZE);
}
voidmd4_setBigEndian(md4_t*md4)
{
uint32_t*p=md4->state;
p[0]=htobe32(p[0]);
p[1]=htobe32(p[1]);
p[2]=htobe32(p[2]);
p[3]=htobe32(p[3]);
}
char*md4_toHashString(chardest[33],constmd4_t*md4)
{
returntoHexString_uint32(dest,33,md4->state,4);
}
#if__cplusplus
}
#endif
ed2k.c
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include"defs.h"
#include"utils.h"
#include"md4.h"
enum{CHUNK_SIZE=9728000,BUFFER_MAX_SIZE=256};
boolprintEd2kLink(constchar*fileName)
{
FILE*in=fopen(fileName,"rb");
if(!in)
{
fprintf(stderr,"error:Openfilefailed.\n");
returnfalse;
}
size_tfileSize;
{
intstate;
if((fileSize=getFileSize(in,&state))==0)
{
if(state==0)
fprintf(stderr,"error:getfileSizeof\'%s\'failed\n",fileName);
else
fprintf(stderr,"error:\'%s\'isempty.\n",fileName);
fclose(in);
returnfalse;
}
}
constchar*shortFileName=getShortFileName(fileName,strlen(fileName));
if(shortFileName==NULL)
{
fprintf(stderr,"error:createNewFilename().\n");
fclose(in);
returnfalse;
}
staticmd4_tmd4HashSet,md4FileHash;
md4_reset(&md4FileHash);
staticcharchunk[CHUNK_SIZE];
size_treadCount;
boolbContinue=true;
intchunkCount=0;
while(bContinue)
{
readCount=fread(chunk,sizeof(chunk[0]),CHUNK_SIZE,in);
if(readCount<CHUNK_SIZE)
{
if(feof(in)){
if(0==readCount)
break;
bContinue=false;
/*memset(chunk+readCount,0,CHUNK_SIZE-readCount);*/
}else{
fprintf(stderr,"error:Readfilefailed.\n");
fclose(in);
returnfalse;
}
}
md4_reset(&md4HashSet);
md4_update(&md4HashSet,chunk,readCount);
md4_finish(&md4HashSet);
md4_update(&md4FileHash,md4_data(&md4HashSet),md4_dataSize());
chunkCount++;
}
staticcharstrHash[33];
if(chunkCount>1){
md4_finish(&md4FileHash);
md4_setBigEndian(&md4FileHash);
md4_toHashString(strHash,&md4FileHash);
}else{
md4_setBigEndian(&md4HashSet);
md4_toHashString(strHash,&md4HashSet);
}
fprintf(stdout,"ed2k://|file|%s|%ld|%s|/\n",shortFileName,fileSize,strHash);
md4_reset(&md4FileHash);
fclose(in);
returntrue;
}
intmain(intargc,constchar*argv[])
{
if(argc<2)
{
fprintf(stderr,"error:argc<2\n");
exit(EXIT_FAILURE);
}
intlinkCount=0;
for(inti=1;i<argc;++i)
{
if(!printEd2kLink(argv[i]))
{
fprintf(stderr,"Created%dlinks.\n",linkCount);
exit(EXIT_FAILURE);
}
linkCount++;
}
exit(EXIT_SUCCESS);
}
MD4Hash.h
#ifndefMYCODE_MD4HASH_H
#defineMYCODE_MD4HASH_H
#include<string>
#include<utility>
#include"md4.h"
#include"defs.h"
BEGIN_NAMESPACE_MYCODE
classMD4Hash
{
friendclassMD4HashAlgo;
structData{uint32_td[4];};
public:
MD4Hash();
MD4Hash(constMD4Hash&o);
#if__cplusplus>=201103L
MD4Hash(MD4Hash&&o);
MD4Hash&operator=(MD4Hash&&o);
#endif
~MD4Hash();
MD4Hash&operator=(constMD4Hash&o);
voidsetBigEndian();
std::stringtoString();
voidswap(MD4Hash&o){std::swap(m_data,o.m_data);}
private:
Datam_data;
MD4Hash(uint32_t*data);
};
classMD4HashAlgo
{
md4_tm_md4;
public:
MD4HashAlgo();
MD4HashAlgo(constMD4HashAlgo&o);
#if__cplusplus>=201103L
MD4HashAlgo(MD4HashAlgo&&o);
MD4HashAlgo&operator=(MD4HashAlgo&&o);
#endif
~MD4HashAlgo();
MD4HashAlgo&operator=(constMD4HashAlgo&o);
voidreset(){md4_reset(&m_md4);}
voidupdate(constchar*data,size_tsize){md4_update(&m_md4,data,size);}
voidupdate(constMD4Hash&hash){md4_update(&m_md4,(constchar*)(hash.m_data.d),16);}
voidfinish(){md4_finish(&m_md4);}
MD4HashgetHash(){returnMD4Hash(m_md4.state);}
size_thashSize(){returnmd4_dataSize();}
voidswap(MD4HashAlgo&o){std::swap(m_md4,o.m_md4);}
};
END_NAMESPACE_MYCODE
#endif/*MYCODE_MD4HASH_H*/
ED2KHash.h
#ifndefMYCODE_ED2KHASH_H
#defineMYCODE_ED2KHASH_H
#include<string>
#include<iostream>
#include"defs.h"
BEGIN_NAMESPACE_MYCODE
classED2KHash
{
public:
enummode{
FileHash=0x01,
PartHash=0x10,
RootHash=0x20,
Default=FileHash
};
ED2KHash(intmode=ED2KHash::Default);
ED2KHash(constED2KHash&o);
~ED2KHash();
ED2KHash&operator=(constED2KHash&o);
#if__cplusplus>=201103L
ED2KHash(ED2KHash&&o);
ED2KHash&operator=(ED2KHash&&o);
#endif
voidexec(constchar*fileName);
voidswap(ED2KHash&o);
std::stringgetFileHash();
friendstd::ostream&operator<<(std::ostream&out,constED2KHash&v);
private:
intm_mode;
size_tm_fileSize;
std::stringm_fileName;
std::stringm_fileHash;
voidcopy(constED2KHash&o);
#if__cplusplus>=201103L
voidmove(ED2KHash&o);
#endif
};
END_NAMESPACE_MYCODE
#endif/*MYCODE_ED2KHASH_H*/
ED2KHash.cpp
#include<cstring>
#include<fstream>
#include<utility>
#include"utils.h"
#include"MD4Hash.h"
#include"ED2KHash.h"
BEGIN_NAMESPACE_MYCODE
///////////////////////////////////////////////////////////////////////////////
//ED2KHash//
///////////////////////////////////////////////////////////////////////////////
ED2KHash::ED2KHash(intmode)
:m_mode(mode),m_fileSize(0)
{/*empty*/}
voidED2KHash::copy(constED2KHash&o)
{
m_mode=o.m_mode;
m_fileSize=o.m_fileSize;
m_fileName=o.m_fileName;
m_fileHash=o.m_fileHash;
}
ED2KHash::ED2KHash(constED2KHash&o)
{
copy(o);
}
ED2KHash&ED2KHash::operator=(constED2KHash&o)
{
copy(o);
return*this;
}
#if__cplusplus>=201103L
voidED2KHash::move(ED2KHash&o)
{
m_mode=o.m_mode;
m_fileSize=o.m_fileSize;
m_fileName=std::move(o.m_fileName);
m_fileHash=std::move(o.m_fileHash);
}
ED2KHash::ED2KHash(ED2KHash&&o)
{
this->move(o);
}
ED2KHash&ED2KHash::operator=(ED2KHash&&o)
{
this->move(o);
return*this;
}
#endif
ED2KHash::~ED2KHash()
{/*empty*/}
voidED2KHash::swap(ED2KHash&o)
{
std::swap(*this,o);
}
std::stringED2KHash::getFileHash()
{
returnm_fileHash;
}
enum{CHUNK_SIZE=9728000};
enum{BLOCK_180K=184320,BLOCK_140K=143360};
voidED2KHash::exec(constchar*fileName)
{
std::stringmsg("error:");
std::ifstreamin(fileName,std::ios_base::binary|std::ios_base::in);
if(!in.is_open())
throwmsg=msg+"Open\'"+fileName+"\'failed.";
if((m_fileSize=mc::getFileSize(in))==0)
throwmsg=msg+fileName+"isempty.";
mc::getShortFileName(&m_fileName,fileName);
staticmc::MD4Hashmd4Hash;
staticmc::MD4HashAlgopartHashMD4Algo,fileHashMD4Algo;
fileHashMD4Algo.reset();
staticcharchunk[CHUNK_SIZE];
size_treadCount;
size_tchunkCount=0;
boolbContinue=true;
while(bContinue)
{
in.read(chunk,CHUNK_SIZE);
if((readCount=in.gcount())<CHUNK_SIZE)
{
if(in.eof()){
if(0==readCount)
break;
bContinue=false;
memset(chunk+readCount,0,CHUNK_SIZE-readCount);
}else{
throwmsg+="Readfilefailed.";
}
}
partHashMD4Algo.reset();
partHashMD4Algo.update(chunk,readCount);
partHashMD4Algo.finish();
md4Hash=mc_move(partHashMD4Algo.getHash());
fileHashMD4Algo.update(md4Hash);
/*if(m_mode&PartHash){
if(bWriteToData)
;//
else{
md4Hash.setBigEndian();
m_listPartHash.push_back(md4Hash);
}
}*/
if(m_mode&RootHash){
//
}
chunkCount++;
}
if(chunkCount>1){
fileHashMD4Algo.finish();
md4Hash=mc_move(fileHashMD4Algo.getHash());
md4Hash.setBigEndian();
m_fileHash=mc_move(md4Hash.toString());
}else{
md4Hash=mc_move(partHashMD4Algo.getHash());
md4Hash.setBigEndian();
m_fileHash=mc_move(md4Hash.toString());
}
}
std::ostream&operator<<(std::ostream&out,constED2KHash&v)
{
out<<"ed2k://|file|"<<v.m_fileName<<'|'<<v.m_fileSize<<'|'
<<v.m_fileHash<<'|';
/*if(v.m_mode|ED2KHash::PartHash){
size_tn=m_listPartHash.size();
m_listPartHash.iteratorit=m_listPartHash.begin();
if(n>0)do{
cout<<it->getHash().toString();
if(--n==0)
break;
++it;
cout<<':';
}while(1);
out<<'|';
}*/
//if(v.m_mode|ED2KHash::RootHash)
//out<<'|';
returnout<<'/';
}
END_NAMESPACE_MYCODE
ed2k.cpp
#include<cstdlib>
#include<cstring>
#include<string>
#include<iostream>
#include<fstream>
#include"utils.h"
#include"ED2KHash.h"
#include"defs.h"
voidusage(boolb)
{
std::cout
<<"command:ed2k[Option...]<File...>\n"
<<"ed2k<File...>(1)\n"
<<"ed2k-r<File...>(2)\n"
<<"ed2k-p<File...>(3)\n"
<<"ed2k-p-r<File...>(4)\n"
<<"ed2k-pr<File...>(4)\n\n"
<<"(1)ed2k://|file|<FileName>|<FileSize>|<FileHash>|/\n"
<<"(2)ed2k://|file|<FileName>|<FileSize>|<FileHash>|<h=RootHash>|/\n"
<<"(3)ed2k://|file|<FileName>|<FileSize>|<FileHash>|<p=PartHash>|/\n"
<<"(4)ed2k://|file|<FileName>|<FileSize>|<FileHash>|<p=PartHash>|<h=RootHash>|/"
<<std::endl;
if(b)
exit(EXIT_SUCCESS);
}
boolparsed(intargc,constchar*argv[],int*opt,int*pos)
{
if(argc<2)
returnfalse;
if(strcmp("--help",argv[1])==0)
usage(true);
if(strcmp("--version",argv[1])==0)
{
std::cout<<"0.1v"<<std::endl;
exit(EXIT_SUCCESS);
}
*opt=mc::ED2KHash::FileHash;
*pos=1;
for(;*pos<argc;++(*pos))
{
if('-'!=argv[*pos][0])
break;
intlen=strlen(argv[*pos]);
for(intj=1;j<len;++j)
{
if('p'==argv[*pos][j])
*opt|=mc::ED2KHash::PartHash;
elseif('r'==argv[*pos][j])
*opt|=mc::ED2KHash::RootHash;
else{
std::cerr<<"error:\'"<<argv[*pos]<<"\'isnotaoption."
<<"Enter'--help'veiwusage."<<std::endl;
returnfalse;
}
}
}
if(*pos==argc)
{
std::cerr<<"error:noparameter."
<<"Enter'--help'veiwusage."<<std::endl;
returnfalse;
}
returntrue;
}
intmain(intargc,constchar*argv[])
{
intopt,pos;
if(!parsed(argc,argv,&opt,&pos))
exit(EXIT_FAILURE);
intlinkCount=0;
mc::ED2KHashed2k(opt);
for(;pos<argc;++pos)
{
try{
ed2k.exec(argv[pos]);
std::cout<<ed2k<<std::endl;
}catch(std::string&e){
std::cerr<<e<<"\ncreated"<<linkCount<<"links."<<std::endl;
exit(EXIT_FAILURE);
}
linkCount++;
}
std::cerr<<"\ncreated"<<linkCount<<"links."<<std::endl;
exit(EXIT_SUCCESS);
}
以上所述就是本文给大家分享的制作ed2k链的代码了,希望大家能够喜欢。