MD5 算法 C 实现 |
您所在的位置:网站首页 › linux如何查看文件md5值 › MD5 算法 C 实现 |
/************************************************************************ Copyright (c) 2008-2080 syna-tech.com, pepstack.com, [email protected]** ALL RIGHTS RESERVED.* * Redistribution and use in source and binary forms, with or without* modification, are permitted provided that the following conditions* are met:* * Redistributions of source code must retain the above copyright* notice, this list of conditions and the following disclaimer.* * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.***********************************************************************/ /** * MD5 implementation * md5sum("hello") == echo -n "hello" | md5sum * * md5("hello") = {5d41402abc4b2a76b9719d911017c592} * * Usage: * * char hash[MD5SUM_STRING_LEN + 1]; * char msg[] = "[email protected]"; * * md5sum_t ctx; * md5sum_init(&ctx, 0); * md5sum_updt(&ctx, msg, strlen(msg)); * md5sum_done(&ctx, ctx.digest); * * md5print(ctx.digest, hash); * * printf(">>>> {%s}\n", hash); * * >>>> {bdc0bb1f6bea9f3b546657614918bc1d} */#ifndef MD5SUM_H_INCLUDED#define MD5SUM_H_INCLUDED #if defined(__cplusplus)extern "C"{#endif #include #include #include #include /** * fix length string buffer with 32 chars */#define MD5SUM_STRING_LEN 32 /** * size in byets for read file * MUST = 64 x N (N = 8, 16, ...) */#ifndef MD5FILE_CHUNK_SIZE# define MD5FILE_CHUNK_SIZE 4096#endif typedef struct{ uint32_t count[2]; uint32_t state[4]; uint8_t buffer[64]; uint8_t digest[16];} md5sum_t; /** * private typedef and functions */ static const uint8_t __md5sum_padding__[] ={ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; #define __md5sum_F__(x,y,z) ((x & y) | (~x & z)) #define __md5sum_G__(x,y,z) ((x & z) | (y & ~z)) #define __md5sum_H__(x,y,z) (x^y^z) #define __md5sum_I__(x,y,z) (y ^ (x | ~z)) #define __md5sum_LR__(x,n) ((x > (32-n))) #define __md5sum_FF__(a,b,c,d,x,s,ac) do { \ a += __md5sum_F__(b,c,d) + x + ac; \ a = __md5sum_LR__(a,s); \ a += b; \ } while(0) #define __md5sum_GG__(a,b,c,d,x,s,ac) do { \ a += __md5sum_G__(b,c,d) + x + ac; \ a = __md5sum_LR__(a,s); \ a += b; \ } while(0) #define __md5sum_HH__(a,b,c,d,x,s,ac) do { \ a += __md5sum_H__(b,c,d) + x + ac; \ a = __md5sum_LR__(a,s); \ a += b; \ } while(0) #define __md5sum_II__(a,b,c,d,x,s,ac) do { \ a += __md5sum_I__(b,c,d) + x + ac; \ a = __md5sum_LR__(a,s); \ a += b; \ } while(0) #define __md5sum_encode__(output, input, len) do { \ uint32_t i = 0; \ uint32_t j = 0; \ while (j < len) { \ output[j] = input[i] & 0xFF; \ output[j+1] = (input[i] >> 8) & 0xFF; \ output[j+2] = (input[i] >> 16) & 0xFF; \ output[j+3] = (input[i] >> 24) & 0xFF; \ i++; \ j += 4; \ } \ } while(0) #define __md5sum_decode__(output, input, len) do { \ uint32_t i = 0; \ uint32_t j = 0; \ while (j < len) { \ output[i] = (input[j]) | (input[j+1] state[2] = 0x98BADCFE + (seed * 37); ctx->state[3] = 0x10325476 + (seed * 97);} static void md5sum_updt (md5sum_t *ctx, const uint8_t *input, uint32_t inputlen){ uint32_t i = 0, index = 0, partlen = 0; index = (ctx->count[0] >> 3) & 0x3F; partlen = 64 - index; ctx->count[0] += inputlen count[0] < (inputlen count[1]++; } ctx->count[1] += inputlen >> 29; if (inputlen >= partlen) { memcpy(&ctx->buffer[index], input, partlen); __md5sum_trans__(ctx->state, ctx->buffer); for (i = partlen; i+64 state, &input[i]); } index = 0; } else { i = 0; } memcpy(&ctx->buffer[index], &input[i], inputlen - i);} static void md5sum_done (md5sum_t *ctx, uint8_t digest[16]){ uint32_t index = 0, padlen = 0; uint8_t bits[8]; index = (ctx->count[0] >> 3) & 0x3F; padlen = (index < 56)?(56-index):(120-index); __md5sum_encode__(bits,ctx->count,8); md5sum_updt(ctx, __md5sum_padding__, padlen); md5sum_updt(ctx, bits, 8); __md5sum_encode__(digest, ctx->state, 16);} static const char * md5print (const uint8_t digest[16], char outbuf[MD5SUM_STRING_LEN + 1]){ int i; char *out = outbuf; const uint8_t *pch = digest; for (i = 0; i < 16; i++) { sprintf(out + i*2, "%2.2x", *pch++); } out[i*2] = 0;} /** * both result and speed are same with linux: * * md5sum $filename */static int md5file (const char *pathfile, uint32_t seed, uint8_t digest[16]){ FILE * fp; fp = fopen(pathfile, "rb"); if (! fp) { /* read file error */ return (-1); } else { char rdbuf[MD5FILE_CHUNK_SIZE]; size_t rcb = 0; md5sum_t ctx; md5sum_init(&ctx, seed); for (;;) { rcb = fread(rdbuf, 1, MD5FILE_CHUNK_SIZE, fp); if (rcb < MD5FILE_CHUNK_SIZE) { /* If an error occurs, or the end of the file is reached, * the return value is a short item count (or zero). */ if (feof(fp) && ! ferror(fp)) { /* read success to end of file */ if (rcb != 0) { md5sum_updt(&ctx, rdbuf, rcb); } break; } /* read file error */ fclose(fp); return (-1); } md5sum_updt(&ctx, rdbuf, rcb); } md5sum_done(&ctx, digest); /* success */ fclose(fp); return 0; }} #if defined(__cplusplus)}#endif #endif /* MD5SUM_H_INCLUDED */ |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |