支持4G以上文件的MD5单元
根据网上一个流传很久的基于Delph4的MD5单元修改的, 可以支持4G以上的文件, 可以支持UNICODE字符的Delphi
恩.......对于大文件速度稍微慢了一点点, 在我自己的电脑上测试, 5.2G文件计算速度86秒...凑合了吧
如果谁能优化一下速度, 请联系我哦~~~
- (*
- -----------------------------------------------------------------------------------------------
- MD5 Message-Digest
- Delphi Unit implementing the
- RSA Data Security, Inc. MD5 Message-Digest Algorithm
- Implementation of Ronald L. Rivest's RFC 1321
- Copyright ?1997-1999 Medienagentur Fichtner & Meyer
- Written by Matthias Fichtner
- -----------------------------------------------------------------------------------------------
- 2013-11-11 堕落恶魔
- 增加对超过4G大小文件支持
- 增加对Delphi2009以及更高版本Delphi支持
- 如果有修改, 希望能够将代码同步邮件给我, 谢谢
- hs_kill_god@hotmail.com
- -----------------------------------------------------------------------------------------------
- *)
- Unit MD5;
- // -----------------------------------------------------------------------------------------------
- interface
- // -----------------------------------------------------------------------------------------------
- uses
- Windows, Classes, SysUtils;
- const
- MD5Length: Byte = ;
- type
- MD5Count = array[..] of Int64;
- MD5State = array[..] of DWORD;
- MD5Block = array[..] of DWORD;
- MD5CBits = array[..] of byte;
- MD5Digest = array[..] of byte;
- MD5Buffer = array[..] of byte;
- function MD5String(M: AnsiString): MD5Digest;
- function MD5File(N: AnsiString): MD5Digest;
- function MD5Print(D: MD5Digest): AnsiString;
- function MD5Match(D1, D2: MD5Digest): boolean;
- // -----------------------------------------------------------------------------------------------
- IMPLEMENTATION
- // -----------------------------------------------------------------------------------------------
- var
- PADDING: MD5Buffer = (
- $, $, $, $, $, $, $, $,
- $, $, $, $, $, $, $, $,
- $, $, $, $, $, $, $, $,
- $, $, $, $, $, $, $, $,
- $, $, $, $, $, $, $, $,
- $, $, $, $, $, $, $, $,
- $, $, $, $, $, $, $, $,
- $, $, $, $, $, $, $, $
- );
- type
- MD5Context = record
- State: MD5State;
- Count: MD5Count;
- Buffer: MD5Buffer;
- end;
- function F(x, y, z: DWORD): DWORD; inline;
- begin
- Result := (x and y) or ((not x) and z);
- end;
- function G(x, y, z: DWORD): DWORD; inline;
- begin
- Result := (x and z) or (y and (not z));
- end;
- function H(x, y, z: DWORD): DWORD; inline;
- begin
- Result := x xor y xor z;
- end;
- function I(x, y, z: DWORD): DWORD; inline;
- begin
- Result := y xor (x or (not z));
- end;
- procedure rot(var x: DWORD; n: BYTE); inline;
- begin
- x := (x shl n) or (x shr ( - n));
- end;
- procedure FF(var a: DWORD; b, c, d, x: DWORD; s: BYTE; ac: DWORD); inline;
- begin
- inc(a, F(b, c, d) + x + ac);
- rot(a, s);
- inc(a, b);
- end;
- procedure GG(var a: DWORD; b, c, d, x: DWORD; s: BYTE; ac: DWORD); inline;
- begin
- inc(a, G(b, c, d) + x + ac);
- rot(a, s);
- inc(a, b);
- end;
- procedure HH(var a: DWORD; b, c, d, x: DWORD; s: BYTE; ac: DWORD); inline;
- begin
- inc(a, H(b, c, d) + x + ac);
- rot(a, s);
- inc(a, b);
- end;
- procedure II(var a: DWORD; b, c, d, x: DWORD; s: BYTE; ac: DWORD); inline;
- begin
- inc(a, I(b, c, d) + x + ac);
- rot(a, s);
- inc(a, b);
- end;
- // -----------------------------------------------------------------------------------------------
- // Encode Count bytes at Source into (Count / ) DWORDs at Target
- procedure Encode(Source, Target: pointer; Count: longword);
- var
- S: PByte;
- T: PDWORD;
- I: longword;
- begin
- S := Source;
- T := Target;
- for I := to Count div do
- begin
- T^ := S^;
- inc(S);
- T^ := T^ or (S^ shl );
- inc(S);
- T^ := T^ or (S^ shl );
- inc(S);
- T^ := T^ or (S^ shl );
- inc(S);
- inc(T);
- end;
- end;
- // Decode Count DWORDs at Source into (Count * ) Bytes at Target
- procedure Decode(Source, Target: pointer; Count: longword);
- var
- S: PDWORD;
- T: PByte;
- I: longword;
- begin
- S := Source;
- T := Target;
- for I := to Count do
- begin
- T^ := S^ and $FF;
- inc(T);
- T^ := (S^ shr ) and $FF;
- inc(T);
- T^ := (S^ shr ) and $FF;
- inc(T);
- T^ := (S^ shr ) and $FF;
- inc(T);
- inc(S);
- end;
- end;
- function MP(P: Pointer; M: Integer): Pointer;
- begin
- Result := Pointer(Integer(P) + M);
- end;
- // Transform State according to first bytes at Buffer
- procedure Transform(Buffer: pointer; var State: MD5State);
- var
- a, b, c, d: DWORD;
- Block: MD5Block;
- begin
- Encode(Buffer, @Block, );
- a := State[];
- b := State[];
- c := State[];
- d := State[];
- FF (a, b, c, d, Block[ ], , $d76aa478);
- FF (d, a, b, c, Block[ ], , $e8c7b756);
- FF (c, d, a, b, Block[ ], , $242070db);
- FF (b, c, d, a, Block[ ], , $c1bdceee);
- FF (a, b, c, d, Block[ ], , $f57c0faf);
- FF (d, a, b, c, Block[ ], , $4787c62a);
- FF (c, d, a, b, Block[ ], , $a8304613);
- FF (b, c, d, a, Block[ ], , $fd469501);
- FF (a, b, c, d, Block[ ], , $698098d8);
- FF (d, a, b, c, Block[ ], , $8b44f7af);
- FF (c, d, a, b, Block[], , $ffff5bb1);
- FF (b, c, d, a, Block[], , $895cd7be);
- FF (a, b, c, d, Block[], , $6b901122);
- FF (d, a, b, c, Block[], , $fd987193);
- FF (c, d, a, b, Block[], , $a679438e);
- FF (b, c, d, a, Block[], , $49b40821);
- GG (a, b, c, d, Block[ ], , $f61e2562);
- GG (d, a, b, c, Block[ ], , $c040b340);
- GG (c, d, a, b, Block[], , $265e5a51);
- GG (b, c, d, a, Block[ ], , $e9b6c7aa);
- GG (a, b, c, d, Block[ ], , $d62f105d);
- GG (d, a, b, c, Block[], , $);
- GG (c, d, a, b, Block[], , $d8a1e681);
- GG (b, c, d, a, Block[ ], , $e7d3fbc8);
- GG (a, b, c, d, Block[ ], , $21e1cde6);
- GG (d, a, b, c, Block[], , $c33707d6);
- GG (c, d, a, b, Block[ ], , $f4d50d87);
- GG (b, c, d, a, Block[ ], , $455a14ed);
- GG (a, b, c, d, Block[], , $a9e3e905);
- GG (d, a, b, c, Block[ ], , $fcefa3f8);
- GG (c, d, a, b, Block[ ], , $676f02d9);
- GG (b, c, d, a, Block[], , $8d2a4c8a);
- HH (a, b, c, d, Block[ ], , $fffa3942);
- HH (d, a, b, c, Block[ ], , $8771f681);
- HH (c, d, a, b, Block[], , $6d9d6122);
- HH (b, c, d, a, Block[], , $fde5380c);
- HH (a, b, c, d, Block[ ], , $a4beea44);
- HH (d, a, b, c, Block[ ], , $4bdecfa9);
- HH (c, d, a, b, Block[ ], , $f6bb4b60);
- HH (b, c, d, a, Block[], , $bebfbc70);
- HH (a, b, c, d, Block[], , $289b7ec6);
- HH (d, a, b, c, Block[ ], , $eaa127fa);
- HH (c, d, a, b, Block[ ], , $d4ef3085);
- HH (b, c, d, a, Block[ ], , $4881d05);
- HH (a, b, c, d, Block[ ], , $d9d4d039);
- HH (d, a, b, c, Block[], , $e6db99e5);
- HH (c, d, a, b, Block[], , $1fa27cf8);
- HH (b, c, d, a, Block[ ], , $c4ac5665);
- II (a, b, c, d, Block[ ], , $f4292244);
- II (d, a, b, c, Block[ ], , $432aff97);
- II (c, d, a, b, Block[], , $ab9423a7);
- II (b, c, d, a, Block[ ], , $fc93a039);
- II (a, b, c, d, Block[], , $655b59c3);
- II (d, a, b, c, Block[ ], , $8f0ccc92);
- II (c, d, a, b, Block[], , $ffeff47d);
- II (b, c, d, a, Block[ ], , $85845dd1);
- II (a, b, c, d, Block[ ], , $6fa87e4f);
- II (d, a, b, c, Block[], , $fe2ce6e0);
- II (c, d, a, b, Block[ ], , $a3014314);
- II (b, c, d, a, Block[], , $4e0811a1);
- II (a, b, c, d, Block[ ], , $f7537e82);
- II (d, a, b, c, Block[], , $bd3af235);
- II (c, d, a, b, Block[ ], , $2ad7d2bb);
- II (b, c, d, a, Block[ ], , $eb86d391);
- inc(State[], a);
- inc(State[], b);
- inc(State[], c);
- inc(State[], d);
- end;
- // -----------------------------------------------------------------------------------------------
- // Initialize given Context
- procedure MD5Init(var AContext: MD5Context);
- begin
- with AContext do
- begin
- State[] := $;
- State[] := $EFCDAB89;
- State[] := $98BADCFE;
- State[] := $;
- Count[] := ;
- Count[] := ;
- FillChar(Buffer, SizeOf(MD5Buffer), );
- end;
- end;
- // Update given Context to include Length bytes of Input
- procedure MD5Update(var AContext: MD5Context; AInput: Pointer; ALength: Int64); overload;
- var
- nIndex: Int64;
- nPartLen: Int64;
- I: Int64;
- begin
- with AContext do
- begin
- nIndex := (Count[] shr ) and $3F;
- inc(Count[], ALength shl );
- if Count[] < (ALength shl ) then
- inc(Count[]);
- inc(Count[], ALength shr );
- end;
- nPartLen := - nIndex;
- if ALength >= nPartLen then
- begin
- Move(AInput^, AContext.Buffer[nIndex], nPartLen);
- Transform(@AContext.Buffer, AContext.State);
- I := nPartLen;
- while I + < ALength do
- begin
- Transform(MP(AInput, I), AContext.State);
- inc(I, );
- end;
- nIndex := ;
- end
- else
- I := ;
- Move(MP(AInput, I)^, AContext.Buffer[nIndex], ALength - i);
- end;
- procedure MD5Update(var AContext: MD5Context; AInput: TStream; ALength: Int64); overload;
- var
- nIndex: Int64;
- nPartLen: Int64;
- i: Int64;
- x, m: Integer;
- nBuff: array[..] of Byte;
- begin
- with AContext do
- begin
- nIndex := (Count[] shr ) and $3F;
- inc(Count[], ALength shl );
- if Count[] < (ALength shl ) then
- inc(Count[]);
- inc(Count[], ALength shr );
- end;
- nPartLen := - nIndex;
- if ALength >= nPartLen then
- begin
- AInput.Read(AContext.Buffer[nIndex], nPartLen);
- Transform(@AContext.Buffer, AContext.State);
- i := nPartLen;
- while i < ALength - do
- begin
- AInput.Read(nBuff, );
- for x := to do
- Transform(@(nBuff[x * ]), AContext.State);
- Inc(i, );
- end;
- m := (ALength - i) div ;
- x := m * ;
- AInput.Read(nBuff, x);
- Inc(I, x);
- for x := to m - do
- Transform(@(nBuff[x * ]), AContext.State);
- nIndex := ;
- end
- else
- i := ;
- AInput.Read(AContext.Buffer[nIndex], ALength - i);
- end;
- // Finalize given Context, create Digest and zeroize Context
- procedure MD5Final(var AContext: MD5Context; var Digest: MD5Digest);
- var
- nBits: MD5CBits;
- nIndex: longword;
- nPadLen: longword;
- begin
- Decode(@AContext.Count, @nBits, );
- nIndex := (AContext.Count[] shr ) and $3f;
- if nIndex < then
- nPadLen := - nIndex
- else
- nPadLen := - nIndex;
- MD5Update(AContext, @PADDING, nPadLen);
- MD5Update(AContext, @nBits, );
- Decode(@AContext.State, @Digest, );
- FillChar(AContext, SizeOf(MD5Context), );
- end;
- // -----------------------------------------------------------------------------------------------
- // Create digest of given Message
- function MD5String(M: AnsiString): MD5Digest;
- var
- nContext: MD5Context;
- begin
- MD5Init(nContext);
- MD5Update(nContext, pAnsiChar(M), length(M));
- MD5Final(nContext, Result);
- end;
- // Create digest of file with given Name
- function MD5File(N: AnsiString): MD5Digest;
- var
- nContext: MD5Context;
- nFS: TFileStream;
- begin
- MD5Init(nContext);
- if FileExists(N) then
- begin
- nFS := TFileStream.Create(N, fmOpenRead or fmShareDenyWrite);
- try
- nFS.Position := ;
- MD5Update(nContext, nFS, nFS.Size);
- finally
- nFS.Free;
- end;
- end;
- MD5Final(nContext, Result);
- end;
- // Create hex representation of given Digest
- function MD5Print(D: MD5Digest): AnsiString;
- var
- I, x: byte;
- const
- Digits: array[..] of AnsiChar =
- ('', '', '', '', '', '', '', '', '', '', 'a', 'b', 'c', 'd', 'e', 'f');
- begin
- SetLength(Result, );
- for I := to do
- begin
- x := i * + ;
- Result[x] := Digits[(D[I] shr ) and $0f];
- Result[x + ] := Digits[D[I] and $0f];
- end;
- end;
- // -----------------------------------------------------------------------------------------------
- // Compare two Digests
- function MD5Match(D1, D2: MD5Digest): boolean;
- var
- I: byte;
- begin
- I := ;
- Result := TRUE;
- while Result and (I < ) do
- begin
- Result := D1[I] = D2[I];
- inc(I);
- end;
- end;
- end.
支持4G以上文件的MD5单元的更多相关文章
- 谁说NTFS不支持UEFI启动的?启动U盘放不了超过4G的文件怎么办?Server2016 Win10 U盘UEFI启动制作方法
大家都知道,我们平时做启动盘,用得最多的就是UltraISO(软碟通)这个工具了.用它我们可以很简单快速的把一个空白的普通U盘制作成一个PE启动U盘或系统U盘,然后用它来安装系统非常的方便,受到了广大 ...
- 如何让U盘支持大于4G的文件
U盘通常是FAT(*)格式,不能支持大于4G的文件.为了实现这个目的,通常可以把U盘格式化成NTFS或者exFAT,这两种文件系统都支持大于4G的文件. 一.格式化成NTFS第一步首先我们把优盘插入电 ...
- U盘存放大于4G数据文件且无须格式化U盘的解决方法
现在优盘的容量越来越大了,价格越来越便宜,可是它也有个缺点,因为它默认的文件系统是"FAT32",这种文件系统最大只能保存4G的文件,超过4G的文件就不能保存在优盘上了,这样就不能 ...
- 计算文件的MD5值(Java & Rust)
Java public class TestFileMD5 { public final static String[] hexDigits = { "0", "1&qu ...
- 基础 - 32位操作系统最多只支持4G内存。
32位操作系统最多只支持4G内存. CPU能不能直接访问硬盘的数据呢, 不能. 只能通过把硬盘的数据先放到内存里, 然后再从内存里访问硬盘的数据.我们平时玩游戏碰上读图loading 进度条的这个过程 ...
- MD5介绍及Windows下对文件做md5校验。
MD5介绍参考百度百科: 摘要如下: MD5 校验和(checksum)通过对接收的传输数据执行散列运算来检查数据的正确性. 一个散列函数,比如 MD5,是一个将任意长度的数据字符串转化成短的固定长度 ...
- Vue.js实现大文件分片md5断点续传
背景 根据部门的业务需求,需要在网络状态不良的情况下上传很大的文件(1G+).其中会遇到的问题:1,文件过大,超出服务端的请求大小限制:2,请求时间过长,请求超时:3,传输中断,必须重新上传导致前功尽 ...
- Jav获取文件的MD5码,比较两个文件内容是否相同
Jav获取文件的MD5码,比较两个文件内容是否相同 代码: System.out.println(DigestUtils.md5Hex(new FileInputStream(new File(&qu ...
- python计算文件的md5值
前言 最近要开发一个基于python的合并文件夹/目录的程序,本来的想法是基于修改时间的比较,即判断文件有没有改变,比较两个文件的修改时间即可.这个想法在windows的pc端下测试没有问题. 但是当 ...
随机推荐
- 【JNI】C向C++改造
步骤: 1. 把c文件后缀名换成cpp2. Android.mk文件中的hello.c也要换成hello.cpp3. c++的使用的环境变量结构体中,访问了c使用的结构体的函数指针,函数名全部都是一样 ...
- Loadrunner请求自定义的http(json)文件and参数化
Loadrunner请求自定义的http(json)文件and参数化 研究啦好些天这个东西啦 终于出来答案啦 嘿嘿 给大家分享一下 : 请求自定义的http文件用函数:web_custom_ ...
- 找规律 SGU 126 Boxes
题目地址:http://acm.sgu.ru/problem.php?contest=0&problem=126 /* 找规律,智商不够,看了题解 详细解释:http://blog.csdn. ...
- java 文件md5+字符串md5 实现
import org.apache.commons.codec.binary.Hex; import org.apache.commons.codec.digest.DigestUtils; impo ...
- Codeforces Round #207 (Div. 2) A. Group of Students
#include <iostream> #include <vector> using namespace std; int main(){ ; cin >> m ...
- TYVJ P1026 犁田机器人 Label:水
背景 USACO OCT 09 2ND 描述 Farmer John為了让自己从无穷无尽的犁田工作中解放出来,於是买了个新机器人帮助他犁田.这个机器人可以完成犁田的任务,可惜有一个小小的缺点:这个犁田 ...
- linux用户和组管理
添加组groupadd sftp 把用户mysftp加入组sftp中:gpasswd -a mysftp sftp 把用户mysftp加入组sftp中:usermod -a -G sftp mysft ...
- vs2005中删除最近打开的项目和文件的记录
vs2005中总是保留最近打开的项目和文件的记录,甚至是以删除的它也不删,-_-!下面介绍几种删除的方法: 第一种:建立一个bat文件,以后双击即可清除,内置代码如下: @echo off@REG D ...
- hdu Pie
这道题是一道二分搜索的题,首先计算出最大的平均体积:mx=V总/f:然后去left=0,right=mx,mid=(left+right)/2进行二分搜索,当所有pi分割出的mid的个数是大于等于f时 ...
- Intent学习笔记
Intent首先字面意思大概是意图.负责activity之间或者,activity与service等(我只知道这么点)之间信息的传递.就跟快递员起的作用差不多(我这这么理解),由一下六部分组成: Co ...