当前位置:首页 > 通信资讯 > 正文

linux下载ed2k链接(linux ed2k)

本程序依赖 c99, 只支持终端“标准输入”,转换成的链接以”标准输出“而输出,错误以”标出错误输出“而输出。

md4 编码代码来自网络。

编译命令:gcc -std=c99 -o ed2k md4.c ed2k.c utils.c
用户命令:ed2k <File...>
产生的链是最简短的形式:ed2k://|file|<FileName>|<FileSize>|<FileHash>|/

c++版本:

编译命令:g++ -o ed2k ed2k.cpp utils.cpp MD4Hash.cpp ED2KHash.cpp
用户命令:ed2k <File...> (虽然--help可以看到其它选项,但都没实现)

defs.h

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 #ifndef MYCODE_DEFS_H #define MYCODE_DEFS_H #include <stdint.h> /* uint32_t ... */ #include <stddef.h> /* size_t, ssize_t */ #include <stdbool.h> #endif #if __cplusplus # define BEGIN_NAMESPACE_MYCODE namespace mc { # define END_NAMESPACE_MYCODE } # if __cplusplus < 201103L # define nullptr ((void*)0) # endif #endif /* __cplusplus */ #endif /* MYCODE_DEFS_H */

utils.h

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 #ifndef MYCODE_UTILS_H #define MYCODE_UTILS_H #include <stdio.h> #if __cplusplus # include <utility> # include <string> # include <fstream> #endif /* __cplusplus */ #include "defs.h" #if __cplusplus extern "C" { #endif #undef byteswap32 #define byteswap32(x) \ ( (((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \ (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24) ) #undef htobe32 #undef htole32 #if __BYTE_ORDER == __LITTLE_ENDIAN # define htobe32(x) byteswap32(x) # define htole32(x) (x) #else # define htobe32(x) (x) # define htole32(x) byteswap32(x) #endif enum { string_npos = (size_t)-1 }; /* 查找字符串 str 中第一个与 c 匹配的字符,返回该字符在字符串中的下标, 失败返回 string_npos */ size_t string_find(const char *str, size_t size, char c); /* 逆向查找*/ size_t string_rfind(const char *str, size_t size, char c); void setBigEndian_uint32(uint32_t *data, size_t n); char* toHexString_uint32(char *buf, size_t bufSize, const uint32_t *data, size_t n); char* createShortFileName(char *buf, size_t bufSize, const char *fullName, size_t size); /* 成功时返回指针 fullName 某部分的地址, 失败时返回 NULL */ const char* getShortFileName(const char* fullName, size_t size); /* 当返回0大小时, 需要检查state, state == 0 表示失败 */ size_t getFileSize(FILE *in, int *state); #if __cplusplus } /* extern "C" */ #endif /****************************************************************************** * c++ *****************************************************************************/ #if __cplusplus BEGIN_NAMESPACE_MYCODE # if __cplusplus >= 201103L # define mc_move(x) std::move(x) # else # define mc_move(x) (x); # endif /////////////////////////////////////////////////////////////////////////////// template<class T> void setBigEndian(T*, size_t); template<> inline void setBigEndian<uint32_t>(uint32_t *p, size_t n) { setBigEndian_uint32(p, n); } /////////////////////////////////////////////////////////////////////////////// template<class T> std::string toHexString(T*, size_t); template<> inline std::string toHexString<uint32_t>(uint32_t *p, size_t n) { std::string strHex; char buf[9]; for (size_t i = 0; i < n; ++i) { sprintf(buf, "%08X", p[i]); strHex += buf; } return mc_move(strHex); } /////////////////////////////////////////////////////////////////////////////// std::string getShortFileName(const std::string& fullName); void getShortFileName(std::string *shortName, const std::string& fullName); size_t getFileSize(std::ifstream& f); END_NAMESPACE_MYCODE #endif /* __cplusplus */ #endif /* MYCODE_UTILS_H */

utils.c

?
1 #include "utils.cpp"

utils.cpp

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 #include <string.h> #include "utils.h" #if __cplusplus extern "C" { #endif void setBigEndian_uint32(uint32_t *data, size_t n) { for (size_t i = 0; i < n; ++i) data[i] = htobe32(data[i]); } char* toHexString_uint32(char *buf, size_t bufSize, const uint32_t *data, size_t n) { char *p = buf; size_t i = 0; size_t one_uint32_size = sizeof(uint32_t); if ( one_uint32_size * n < bufSize ) { while (i < n) { sprintf(p, "%08X", data[i++]); p += 8; } } *p = '\0'; return buf; } size_t string_find(const char *str, size_t size, char c) { size_t pos = 0; while (pos < size) { if (str[pos] == c) return pos; ++pos; } return string_npos; } size_t string_rfind(const char *str, size_t size, char c) { while (size) { if (str[--size] == c) return size; } return string_npos; } char* createShortFileName(char *buf, size_t bufSize, const char *fullName, size_t size) { const char * p = getShortFileName(fullName, size); buf[0] = '\0'; if (p) { size_t len = strlen(p); if (bufSize > len) memcpy(buf, p, len + 1); } return buf; } const char* getShortFileName(const char *fileName, size_t size) { #if _WIN32 char c = '\\'; #else char c = '/'; #endif size_t pos = string_rfind(fileName, size, c); if (pos == string_npos) return NULL; else return fileName + (pos + 1); } size_t getFileSize(FILE *in, int *state) { *state = 0; if (!in) return 0; size_t curpos = ftell(in); if (fseek(in, 0, SEEK_END) == -1) return 0; size_t fileSize = ftell(in); if (fseek(in, curpos, SEEK_SET) == -1) return 0; *state = 1; return fileSize; } #if __cplusplus } /* extern "C" */ #endif /****************************************************************************** * c++ *****************************************************************************/ #if __cplusplus BEGIN_NAMESPACE_MYCODE void getShortFileName(std::string *shortName, const std::string& fullName) { # if _WIN32 char c = '\\'; # else char c = '/'; # endif size_t pos = fullName.rfind(c); if (pos == std::string::npos) shortName->assign(fullName); else shortName->assign(fullName.begin() + pos + 1, fullName.end()); } std::string getShortFileName(const std::string& fullName) { std::string shortName; getShortFileName(&shortName, fullName); return mc_move(shortName); } size_t getFileSize(std::ifstream& f) { f.seekg(0, f.end); size_t fileSize = f.tellg(); f.seekg(0); return fileSize; } END_NAMESPACE_MYCODE #endif /* __cplusplus */

md4.h

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 #ifndef MYCODE_MD4_H #define MYCODE_MD4_H #include "defs.h" #if __cplusplus extern "C" { #endif enum { MD4_COUNT_SIZE = 8, MD4_STATE_SIZE = 16, MD4_BUFFER_SIZE = 64 }; typedef struct { uint32_t count[2]; uint32_t state[4]; uint8_t buffer[MD4_BUFFER_SIZE]; } md4_t; #define md4_data(md4_ptr) ((char*)((md4_ptr)->state)) #define md4_cdata(md4_ptr) ((const char*)((md4_ptr)->state)) #define md4_dataSize() (MD4_STATE_SIZE) void md4_reset(md4_t *md4); void md4_update(md4_t *md4, const char *src, size_t srcSize); void md4_finish(md4_t *md4); void md4_setBigEndian(md4_t *md4); char* md4_toHashString(char dest[33], const md4_t *md4); #if __cplusplus } #endif #endif /* MYCODE_MD4_H */

md4.c

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 /* #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 # define md4_htole32_4(buf) /* empty */ # define md4_htole32_14(buf) /* empty */ # define md4_htole32_16(buf) /* empty */ #else # define md4_htole32_4(buf) \ (buf)[ 0] = htole32((buf)[ 0]); \ (buf)[ 1] = htole32((buf)[ 1]); \ (buf)[ 2] = htole32((buf)[ 2]); \ (buf)[ 3] = htole32((buf)[ 3]) # define md4_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]) # define md4_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 /* #define F1(x, y, z) (x & y | ~x & z) */ #define F1(x, y, z) (z ^ (x & (y ^ z))) #define F2(x, y, z) ((x & y) | (x & z) | (y & z)) #define F3(x, y, z) (x ^ y ^ z) /* This is the central step in the MD4 algorithm. */ #define MD4STEP(f, w, x, y, z, data, s) \ ( w += f(x, y, z) + data, w = w<<s | w>>(32-s) ) static void md4_transform(uint32_t *state, const uint8_t *buffer) { uint32_t a, b, c, d; const uint32_t *src = (const uint32_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; } void md4_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; } void md4_update(md4_t *md4, const char *src, size_t srcSize) { uint32_t count = (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_t partSize = 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); } void md4_finish(md4_t *md4) { uint32_t count = (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); /* Append bit count and transform */ ((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); } void md4_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(char dest[33], const md4_t *md4) { return toHexString_uint32(dest, 33, md4->state, 4); } #if __cplusplus } #endif

ed2k.c

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 #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 }; bool printEd2kLink(const char *fileName) { FILE *in = fopen(fileName, "rb"); if (!in) { fprintf(stderr, "error: Open file failed.\n"); return false; } size_t fileSize; { int state; if ((fileSize = getFileSize(in, &state)) == 0) { if (state == 0) fprintf(stderr, "error: get fileSize of \'%s\' failed\n", fileName); else fprintf(stderr, "error: \'%s\' is empty.\n", fileName); fclose(in); return false; } } const char *shortFileName = getShortFileName(fileName, strlen(fileName)); if (shortFileName == NULL) { fprintf(stderr, "error: createNewFilename().\n"); fclose(in); return false; } static md4_t md4HashSet, md4FileHash; md4_reset(&md4FileHash); static char chunk[CHUNK_SIZE]; size_t readCount; bool bContinue = true; int chunkCount = 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: Read file failed.\n"); fclose(in); return false; } } md4_reset(&md4HashSet); md4_update(&md4HashSet, chunk, readCount); md4_finish(&md4HashSet); md4_update(&md4FileHash, md4_data(&md4HashSet), md4_dataSize()); chunkCount++; } static char strHash[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); return true; } int main(int argc, const char *argv[]) { if (argc < 2) { fprintf(stderr, "error: argc < 2\n"); exit(EXIT_FAILURE); } int linkCount = 0; for (int i = 1; i < argc; ++i) { if (!printEd2kLink(argv[i])) { fprintf(stderr, "Created %d links.\n",linkCount); exit(EXIT_FAILURE); } linkCount++; } exit(EXIT_SUCCESS); }

MD4Hash.h

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 #ifndef MYCODE_MD4HASH_H #define MYCODE_MD4HASH_H #include <string> #include <utility> #include "md4.h" #include "defs.h" BEGIN_NAMESPACE_MYCODE class MD4Hash { friend class MD4HashAlgo; struct Data{ uint32_t d[4]; }; public: MD4Hash(); MD4Hash(const MD4Hash& o); #if __cplusplus >= 201103L MD4Hash(MD4Hash&& o); MD4Hash& operator=(MD4Hash&& o); #endif ~MD4Hash(); MD4Hash& operator=(const MD4Hash& o); void setBigEndian(); std::string toString(); void swap(MD4Hash& o) { std::swap(m_data, o.m_data); } private: Data m_data; MD4Hash(uint32_t *data); }; class MD4HashAlgo { md4_t m_md4; public: MD4HashAlgo(); MD4HashAlgo(const MD4HashAlgo& o); #if __cplusplus >= 201103L MD4HashAlgo(MD4HashAlgo&& o); MD4HashAlgo& operator=(MD4HashAlgo&& o); #endif ~MD4HashAlgo(); MD4HashAlgo& operator=(const MD4HashAlgo& o); void reset() { md4_reset(&m_md4); } void update(const char *data, size_t size) { md4_update(&m_md4, data, size); } void update(const MD4Hash& hash) { md4_update(&m_md4, (const char*)(hash.m_data.d), 16); } void finish() { md4_finish(&m_md4); } MD4Hash getHash() { return MD4Hash(m_md4.state); } size_t hashSize() { return md4_dataSize(); } void swap(MD4HashAlgo& o) { std::swap(m_md4, o.m_md4); } }; END_NAMESPACE_MYCODE #endif /* MYCODE_MD4HASH_H */

ED2KHash.h

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 #ifndef MYCODE_ED2KHASH_H #define MYCODE_ED2KHASH_H #include <string> #include <iostream> #include "defs.h" BEGIN_NAMESPACE_MYCODE class ED2KHash { public: enum mode { FileHash = 0x01, PartHash = 0x10, RootHash = 0x20, Default = FileHash }; ED2KHash(int mode = ED2KHash::Default); ED2KHash(const ED2KHash& o); ~ED2KHash(); ED2KHash& operator=(const ED2KHash& o); #if __cplusplus >= 201103L ED2KHash(ED2KHash&& o); ED2KHash& operator=(ED2KHash&& o); #endif void exec(const char* fileName); void swap(ED2KHash& o); std::string getFileHash(); friend std::ostream& operator<<(std::ostream& out, const ED2KHash& v); private: int m_mode; size_t m_fileSize; std::string m_fileName; std::string m_fileHash; void copy(const ED2KHash& o); #if __cplusplus >= 201103L void move(ED2KHash& o); #endif }; END_NAMESPACE_MYCODE #endif /* MYCODE_ED2KHASH_H */

ED2KHash.cpp

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 #include <cstring> #include <fstream> #include <utility> #include "utils.h" #include "MD4Hash.h" #include "ED2KHash.h" BEGIN_NAMESPACE_MYCODE /////////////////////////////////////////////////////////////////////////////// // ED2KHash // /////////////////////////////////////////////////////////////////////////////// ED2KHash::ED2KHash(int mode) : m_mode(mode), m_fileSize(0) { /* empty */ } void ED2KHash::copy(const ED2KHash& o) { m_mode = o.m_mode; m_fileSize = o.m_fileSize; m_fileName = o.m_fileName; m_fileHash = o.m_fileHash; } ED2KHash::ED2KHash(const ED2KHash& o) { copy(o); } ED2KHash& ED2KHash::operator=(const ED2KHash& o) { copy(o); return *this; } #if __cplusplus >= 201103L void ED2KHash::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 */ } void ED2KHash::swap(ED2KHash& o) { std::swap(*this, o); } std::string ED2KHash::getFileHash() { return m_fileHash; } enum { CHUNK_SIZE = 9728000 }; enum { BLOCK_180K = 184320, BLOCK_140K = 143360 }; void ED2KHash::exec(const char* fileName) { std::string msg("error: "); std::ifstream in(fileName, std::ios_base::binary | std::ios_base::in); if (!in.is_open()) throw msg = msg + "Open \'" + fileName + "\' failed."; if ((m_fileSize = mc::getFileSize(in)) == 0) throw msg = msg + fileName + " is empty."; mc::getShortFileName(&m_fileName, fileName); static mc::MD4Hash md4Hash; static mc::MD4HashAlgo partHashMD4Algo, fileHashMD4Algo; fileHashMD4Algo.reset(); static char chunk[CHUNK_SIZE]; size_t readCount; size_t chunkCount = 0; bool bContinue = 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 { throw msg += "Read file failed."; } } 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, const ED2KHash& v) { out << "ed2k://|file|" << v.m_fileName << '|' << v.m_fileSize << '|' << v.m_fileHash << '|'; /*if (v.m_mode | ED2KHash::PartHash) { size_t n = m_listPartHash.size(); m_listPartHash.iterator it = 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 << '|'; return out << '/'; } END_NAMESPACE_MYCODE

ed2k.cpp

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 #include <cstdlib> #include <cstring> #include <string> #include <iostream> #include <fstream> #include "utils.h" #include "ED2KHash.h" #include "defs.h" void usage(bool b) { 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); } bool parsed(int argc, const char *argv[], int *opt, int *pos) { if (argc < 2) return false; 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; int len = strlen(argv[*pos]); for(int j = 1; j < len; ++j) { if ('p' == argv[*pos][j]) *opt |= mc::ED2KHash::PartHash; else if ('r' == argv[*pos][j]) *opt |= mc::ED2KHash::RootHash; else { std::cerr << "error: \'" << argv[*pos] << "\' is not a option." << " Enter '--help' veiw usage." << std::endl; return false; } } } if (*pos == argc) { std::cerr << "error: no parameter." << " Enter '--help' veiw usage." << std::endl; return false; } return true; } int main(int argc, const char *argv[]) { int opt, pos; if (!parsed(argc, argv, &opt, &pos)) exit(EXIT_FAILURE); int linkCount = 0; mc::ED2KHash ed2k(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链的代码了,希望大家能够喜欢。

如果您对该产品感兴趣,请填写办理(客服微信:xiaoxiongyidong)

为您推荐:

发表评论

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。