超大文件如何计算md5?

超大文件如何计算md5?,第1张

首先,至少没必要先把整个文件读到内存里。比如在 php 里,如果有人 md5(file_get_contents(big_file_name)) 就确实非常不妥当。因为 md5 是每 512 bit 作为一个 chunk 进行计算的。所以可以每次读取一部分的内容(最少 512 bit,比较合适是 st_blksize),进行那些 chunk 部分的计算,之后再读取下一部分内容继续计算。简单先说下,md5是有规范的,提供了现成的算法(规范的名字就是md5算法。RFC 1321 The MD5 Message-Digest Algorithm),我们只需要翻译成c、java、python、js等等代码。前端算超大文件可以取头跟尾chunk内容及整个文件的name + update 时间一起算md5值就比较快了,只是为了做唯一标识来做断点续传,从业务逻辑上应该够用了。推荐使用 js spark-md5 开源库,支持直接append各个部分然后算出md5。我做的断点续传功能就是用它在前端算的md5. 各大网盘 TB级别 md5算法应该是这样的,楼上几位都说了文件md5是文件流分块算出来的,那么网盘想获得TB级别文件的md5就必须读取整个文件的文件流才能得到,但是这么做效率十分低下,运算时间是个问题。但是大家忽略了一个问题,文件在上传的过程也是分块上传的,这些上传的碎片其实也是文件流。那么可以把计算md5的时间分摊到每一个碎片上。这样每上传一个片段就计算一点等上传完成了,文件的md5也就算出来了。okTB级别MD5不是问题了。上传完成md5自然就出来了。 不知道我的猜测大家有其他看法没有。刚才提出都传完了就还怎么秒传。秒传最基本的是先要前端算出md5然后传给后端(可能需要更多种哈希值)我研究了很久前端没有办法秒内完成超大文件MD5的,现在用html5 的api 可以算出任意大小文件的 md5 但是耗时相当长。我没有解决办法。也没有想到那些网盘怎么在前端快速获取md5的。

#ifndef MD5_H

#define MD5_H

typedef struct

{

unsigned int count[2]

unsigned int state[4]

unsigned char buffer[64]

}MD5_CTX

#define F(x,y,z) ((x &y) | (~x &z))

#define G(x,y,z) ((x &z) | (y &~z))

#define H(x,y,z) (x^y^z)

#define I(x,y,z) (y ^ (x | ~z))

#define ROTATE_LEFT(x,n) ((x <<n) | (x >>(32-n)))

#define FF(a,b,c,d,x,s,ac) \

{ \

a += F(b,c,d) + x + ac\

a = ROTATE_LEFT(a,s)\

a += b\

}

#define GG(a,b,c,d,x,s,ac) \

{ \

a += G(b,c,d) + x + ac\

a = ROTATE_LEFT(a,s)\

a += b\

}

#define HH(a,b,c,d,x,s,ac) \

{ \

a += H(b,c,d) + x + ac\

a = ROTATE_LEFT(a,s)\

a += b\

}

#define II(a,b,c,d,x,s,ac) \

{ \

a += I(b,c,d) + x + ac\

a = ROTATE_LEFT(a,s)\

a += b\

}

void MD5Init(MD5_CTX *context)

void MD5Update(MD5_CTX *context,unsigned char *input,unsigned int inputlen)

void MD5Final(MD5_CTX *context,unsigned char digest[16])

void MD5Transform(unsigned int state[4],unsigned char block[64])

void MD5Encode(unsigned char *output,unsigned int *input,unsigned int len)

void MD5Decode(unsigned int *output,unsigned char *input,unsigned int len)

#endif

源文件md5.c

#include <memory.h>

#include "md5.h"

unsigned char 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}

void MD5Init(MD5_CTX *context)

{

context->count[0] = 0

context->count[1] = 0

context->state[0] = 0x67452301

context->state[1] = 0xEFCDAB89

context->state[2] = 0x98BADCFE

context->state[3] = 0x10325476

}

void MD5Update(MD5_CTX *context,unsigned char *input,unsigned int inputlen)

{

unsigned int i = 0,index = 0,partlen = 0

index = (context->count[0] >>3) &0x3F

partlen = 64 - index

context->count[0] += inputlen <<3

if(context->count[0] <(inputlen <<3))

context->count[1]++

context->count[1] += inputlen >>29

if(inputlen >= partlen)

{

memcpy(&context->buffer[index],input,partlen)

MD5Transform(context->state,context->buffer)

for(i = partleni+64 <= inputleni+=64)

MD5Transform(context->state,&input[i])

index = 0

}

else

{

i = 0

}

memcpy(&context->buffer[index],&input[i],inputlen-i)

}

void MD5Final(MD5_CTX *context,unsigned char digest[16])

{

unsigned int index = 0,padlen = 0

unsigned char bits[8]

index = (context->count[0] >>3) &0x3F

padlen = (index <56)?(56-index):(120-index)

MD5Encode(bits,context->count,8)

MD5Update(context,PADDING,padlen)

MD5Update(context,bits,8)

MD5Encode(digest,context->state,16)

}

void MD5Encode(unsigned char *output,unsigned int *input,unsigned int len)

{

unsigned int i = 0,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

}

}

void MD5Decode(unsigned int *output,unsigned char *input,unsigned int len)

{

unsigned int i = 0,j = 0

while(j <len)

{

output[i] = (input[j]) |

(input[j+1] <<8) |

(input[j+2] <<16) |

(input[j+3] <<24)

i++

j+=4

}

}

void MD5Transform(unsigned int state[4],unsigned char block[64])

{

unsigned int a = state[0]

unsigned int b = state[1]

unsigned int c = state[2]

unsigned int d = state[3]

unsigned int x[64]

MD5Decode(x,block,64)

FF(a, b, c, d, x[ 0], 7, 0xd76aa478)/* 1 */

FF(d, a, b, c, x[ 1], 12, 0xe8c7b756)/* 2 */

FF(c, d, a, b, x[ 2], 17, 0x242070db)/* 3 */

FF(b, c, d, a, x[ 3], 22, 0xc1bdceee)/* 4 */

FF(a, b, c, d, x[ 4], 7, 0xf57c0faf)/* 5 */

FF(d, a, b, c, x[ 5], 12, 0x4787c62a)/* 6 */

FF(c, d, a, b, x[ 6], 17, 0xa8304613)/* 7 */

FF(b, c, d, a, x[ 7], 22, 0xfd469501)/* 8 */

FF(a, b, c, d, x[ 8], 7, 0x698098d8)/* 9 */

FF(d, a, b, c, x[ 9], 12, 0x8b44f7af)/* 10 */

FF(c, d, a, b, x[10], 17, 0xffff5bb1)/* 11 */

FF(b, c, d, a, x[11], 22, 0x895cd7be)/* 12 */

FF(a, b, c, d, x[12], 7, 0x6b901122)/* 13 */

FF(d, a, b, c, x[13], 12, 0xfd987193)/* 14 */

FF(c, d, a, b, x[14], 17, 0xa679438e)/* 15 */

FF(b, c, d, a, x[15], 22, 0x49b40821)/* 16 */

MD5的全称是Message-Digest Algorithm 5,它一种被广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值(hash value),用于确保信息传输完整一致。

MD5值等同于文件的ID,它的值是唯一的。 如果文件已被修改(例如嵌入式病毒,特洛伊木马等),其MD5值将发生变化。 因此,一些常规下载URL提供文件MD并且通常提供MD5值。 如果用户在下载后发现他们的MD5值与网站公告不一致,可能是文件被修改过或者下载出错。

MD5值的查看方式:

1、百度搜索MD5值查看工具“HashMyFiles”并点击进入官网:

2、进入官网后往下拉找到简体中文模式并进行下载:

3、双击打开下载的压缩包,然后找到里面的“HashMyFiles.exe”文件并双击运行:

4、将需要查看MD5值的文件拖入刚才打开的软件,然后软件里面会显示拖入文件的MD5值:


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/tougao/11515940.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-16
下一篇 2023-05-16

发表评论

登录后才能评论

评论列表(0条)

保存