/* Md5.HC Toby Betts Public domain. Like any other piece of software (and information generally), this software comes with NO WARRANTY. This is version 20240208 of Md5.HC. The MD5 algorithm is documented in several places, including the following places used for reference: - Wikipedia - RFC 1321 - OpenBSD CVSWeb Example: #include "Md5"; // get the MD5 checksum of "/Kernel.BIN.C" and use it in a string U8 *digest; digest = Md5("/Kernel.BIN.C"); "MD5 checksum is: %s\n", digest; // print only the MD5 checksum of "/Kernel.BIN.C" Md5("/Kernel.BIN.C",TRUE); // print the MD5 checksum and filename of "~/Once.HC" Md5Sum("~/Once.HC"); // print checksums and names of files in "::/Home" (non-recursive) Md5Sum("::/Home"); // get the number of files in "C:/Doc" and print their checksums I64 cnt; cnt = Md5Sum("C:/Doc"); // get the checksums in "~" and write them to a file called "md5.TXT" Md5Sum("~","md5.TXT"); // get the checksums in "/Downloads" and write them to a file called // "md5.TXT" without printing the checksums to screen Md5Sum("/Downloads","md5.TXT",FALSE); */ #define MD5_BLK_SIZE 64 class Md5Context { U32 state[4]; U64 cnt; U8 buf[MD5_BLK_SIZE]; }; U8 shift[MD5_BLK_SIZE/4] = { 7,12,17,22, 5, 9,14,20, 4,11,16,23, 6,10,15,21 }; U32 BigEndian(U32 in) { return EndianU32(EndianU32(in)); } U0 Md5Init(Md5Context *ctx) { ctx->cnt=0; ctx->state[0]=0x67452301; ctx->state[1]=0xefcdab89; ctx->state[2]=0x98badcfe; ctx->state[3]=0x10325476; } U0 Md5Transform(Md5Context *ctx) { U32 buf[MD5_BLK_SIZE/4]; U32 a,b,c,d,F,g,s; U64 i; for(i=0;ibuf[i*4](U32); } a=ctx->state[0]; b=ctx->state[1]; c=ctx->state[2]; d=ctx->state[3]; for(i=0;i>(32-s); } ctx->state[0]+=a; ctx->state[1]+=b; ctx->state[2]+=c; ctx->state[3]+=d; MemSet(buf,0,sizeof(buf)); } U0 Md5Update(Md5Context *ctx,U8 *in,U64 len) { while (MD5_BLK_SIZE<=len) { MemCpy(ctx->buf+(ctx->cnt%MD5_BLK_SIZE),in,MD5_BLK_SIZE); ctx->cnt+=MD5_BLK_SIZE; Md5Transform(ctx); in += MD5_BLK_SIZE; len -= MD5_BLK_SIZE; } if (len) { MemCpy(ctx->buf+(ctx->cnt%MD5_BLK_SIZE),in,len); ctx->cnt+=len; } } U8 *Md5Final(Md5Context *ctx) { U64 i; i=ctx->cnt%MD5_BLK_SIZE; ctx->buf[i++]=0x80; if (i>56) { for(;ibuf[i]=0; } Md5Transform(ctx); i=0; } for(;ibuf[i]=0; } ctx->buf[56](U64)=ctx->cnt<<3; Md5Transform(ctx); return MStrPrint( "%08x%08x%08x%08x", EndianU32(ctx->state[0]), EndianU32(ctx->state[1]), EndianU32(ctx->state[2]), EndianU32(ctx->state[3])); } U8 *Md5(U8 *filename=NULL,Bool verbose=FALSE) { CFile *cf; I64 fsize; U8 *buf,*digest; Md5Context ctx; if (!FileFind(filename)) { "Md5: usage: Md5(\"filename\");\n"; return NULL; } Md5Init(&ctx); cf=FOpen(filename,"rb"); fsize=FSize(cf); buf=MAlloc(BLK_SIZE); while (0flags |= DOCF_NO_CURSOR; // no 0x5 cursor char while (tmpde1) { res++; digest=MStrPrint("%s %s\n", Md5(tmpde1->full_name), tmpde1->name); if (outfile) { DocPrint(cd,digest); } if (verbose) { "%s",digest; } Free(digest); tmpde2=tmpde1->next; tmpde1=tmpde2; Free(tmpde2); } Free(tmpde1); if (outfile) { DocWrite(cd); } Free(cd); return res; }