MD5 and Zip Libraries
Moderator: InsideQC Admins
12 posts
• Page 1 of 1
MD5 and Zip Libraries
Does anyone know of a good MD5 function and/or zip library (>for use with files <) that would be compatible with the GPL 2 or 3?
I figure this issue has come up enough times that rather than using Google to find out, someone here probably knows the obvious best answer. I know zlib does compression stuff but I have never thought of the idea of using it with zip files (I don't know if it is any good with that ...)
(I know ezQuake utilizes a zip library, but I think that can only read zip files ... not 100%, haven't looked lately.)
I figure this issue has come up enough times that rather than using Google to find out, someone here probably knows the obvious best answer. I know zlib does compression stuff but I have never thought of the idea of using it with zip files (I don't know if it is any good with that ...)
Algorithm
As of February 2010 zlib only supports one algorithm called DEFLATE which is a variation of LZ77 (Lempel–Ziv 1977)
This algorithm provides good compression on a wide variety of data with minimal use of system resources. This is also the algorithm used in the ZIP archive format.
It is unlikely that the zlib format will ever be extended to use any other algorithms, though the header makes allowance for this possibility.
(I know ezQuake utilizes a zip library, but I think that can only read zip files ... not 100%, haven't looked lately.)
The night is young. How else can I annoy the world before sunsrise?
Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
-

Baker - Posts: 3666
- Joined: Tue Mar 14, 2006 5:15 am
Re: MD5 and Zip Libraries
By MD5 you mean the message digest algorithm (not the model format), right?
One place is in Quake3: code/qcommon/md5.c
I've written a C++ class for it:
http://edge.svn.sourceforge.net/viewvc/ ... xt%2Fplain
http://edge.svn.sourceforge.net/viewvc/ ... xt%2Fplain
For ZIP archives, LibPHYSFS is probably the best way to go, though Quake3 does have reading code (for pk3 files) in code/qcommon/unzip.cc but it's pretty hard to follow.
I've written some *very basic* C++ code to read and write ZIP files:
http://oblige.svn.sourceforge.net/viewv ... xt%2Fplain
http://oblige.svn.sourceforge.net/viewv ... xt%2Fplain
One place is in Quake3: code/qcommon/md5.c
I've written a C++ class for it:
http://edge.svn.sourceforge.net/viewvc/ ... xt%2Fplain
http://edge.svn.sourceforge.net/viewvc/ ... xt%2Fplain
For ZIP archives, LibPHYSFS is probably the best way to go, though Quake3 does have reading code (for pk3 files) in code/qcommon/unzip.cc but it's pretty hard to follow.
I've written some *very basic* C++ code to read and write ZIP files:
http://oblige.svn.sourceforge.net/viewv ... xt%2Fplain
http://oblige.svn.sourceforge.net/viewv ... xt%2Fplain
- andrewj
- Posts: 133
- Joined: Mon Aug 30, 2010 3:29 pm
- Location: Australia
Re: MD5 and Zip Libraries
andrewj wrote:By MD5 you mean the message digest algorithm (not the model format), right?
Hehe, yeah. And I checked out your C++ class ... thank you.
One place is in Quake3: code/qcommon/md5.c
For ZIP archives, LibPHYSFS is probably the best way to go, though Quake3 does have reading code (for pk3 files) in code/qcommon/unzip.cc but it's pretty hard to follow.
I've written some *very basic* C++ code to read and write ZIP files:
http://oblige.svn.sourceforge.net/viewv ... xt%2Fplain
http://oblige.svn.sourceforge.net/viewv ... xt%2Fplain
Cool ... I'll check those out too. I'm not looking to do anything except the basics with .zip, but I had an interesting idea come to mind that requires writing out a .zip.
Thanks for both of those.
OBLIGE level maker
Ah cool! Back 4 years ago I snagged some random maze creator vb6 program off the internet and made it output brushes and made it have a button to run it through txqbsp. OMG ... the mazes were damn near impossible.
The night is young. How else can I annoy the world before sunsrise?
Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
-

Baker - Posts: 3666
- Joined: Tue Mar 14, 2006 5:15 am
Re: MD5 and Zip Libraries
physfs is cool
it also handles quake1 pak files doom formats etc.
Maybe good as a general archive handler for quake ?.
Maybe good as a general archive handler for quake ?.
Productivity is a state of mind.
-

revelator - Posts: 2567
- Joined: Thu Jan 24, 2008 12:04 pm
- Location: inside tha debugger
Re: MD5 and Zip Libraries
http://7-zip.org is LGPL
Improve Quaddicted, send me a pull request: https://github.com/SpiritQuaddicted/Quaddicted-reviews
- Spirit
- Posts: 1031
- Joined: Sat Nov 20, 2004 9:00 pm
Re: MD5 and Zip Libraries
7-zip was the first one I thought of too, but I'm not certain what would be involved in integrating it into another program the way Baker wants.
I use the RSA MD5 code which is public domain. http://www.ietf.org/rfc/rfc1321.txt
I use the RSA MD5 code which is public domain. http://www.ietf.org/rfc/rfc1321.txt
We had the power, we had the space, we had a sense of time and place
We knew the words, we knew the score, we knew what we were fighting for
We knew the words, we knew the score, we knew what we were fighting for
-

mh - Posts: 2292
- Joined: Sat Jan 12, 2008 1:38 am
Re: MD5 and Zip Libraries
funzip.c --- public domain
MD5.c
- Code: Select all
/* funzip.c -- Not copyrighted 1992 by Mark Adler */
#define VERSION "2.1 of 23 October 1992"
/* You can do whatever you like with this source file, though I would
prefer that if you modify it and redistribute it that you include
comments to that effect with your name and the date. Thank you.
History:
vers date who what
---- --------- -------------- ------------------------------------
1.0 13 Aug 92 M. Adler really simple unzip filter.
1.1 13 Aug 92 M. Adler cleaned up somewhat, give help if
stdin not redirected, warn if more
zip file entries after the first.
1.2 15 Aug 92 M. Adler added check of lengths for stored
entries, added more help.
1.3 16 Aug 92 M. Adler removed redundant #define's, added
decryption.
1.4 27 Aug 92 G. Roelofs added exit(0).
1.5 1 Sep 92 K. U. Rommel changed read/write modes for OS/2.
1.6 6 Sep 92 G. Roelofs modified to use dummy crypt.c and
crypt.h instead of -DCRYPT.
1.7 23 Sep 92 G. Roelofs changed to use DOS_OS2; included
crypt.c under MS-DOS.
1.8 9 Oct 92 M. Adler improved inflation error msgs.
1.9 17 Oct 92 G. Roelofs changed ULONG/UWORD/byte to ulg/ush/uch;
renamed inflate_entry() to inflate();
adapted to use new, in-place zdecode.
2.0 22 Oct 92 M. Adler allow file name argument, prompt for
passwords and don't echo, still allow
command-line password entry, but as an
option.
2.1 23 Oct 92 J. Gailly fixed crypt/store bug,
G. Roelofs removed crypt.c under MS-DOS, fixed
decryption check to compare single byte.
*/
/*
All funzip does is take a zip file from stdin and decompress the
first entry to stdout. The entry has to be either deflated or
stored. If the entry is encrypted, then the decryption password
must be supplied on the command line as the first argument.
funzip needs to be linked with inflate.o and crypt.o compiled from
the unzip source. If decryption is desired, the full version of
crypt.c (and crypt.h) from zcrypt20.zip or later must be used.
*/
#include "unzip.h"
#include "crypt.h"
/* enforce binary i/o if recognized */
#if defined(__STDC__) || defined(DOS_OS2)
# define BINIO
#endif
#ifdef BINIO
# define FOPR "rb"
# define FOPW "wb"
#else
# define FOPR "r"
# define FOPW "w"
#endif
/* PKZIP header definitions */
#define LOCSIG 0x04034b50L /* four-byte lead-in (lsb first) */
#define LOCFLG 6 /* offset of bit flag */
#define CRPFLG 1 /* bit for encrypted entry */
#define EXTFLG 8 /* bit for extended local header */
#define LOCHOW 8 /* offset of compression method */
#define LOCTIM 10 /* file mod time (for decryption) */
#define LOCCRC 14 /* offset of crc */
#define LOCSIZ 18 /* offset of compressed size */
#define LOCLEN 22 /* offset of uncompressed length */
#define LOCFIL 26 /* offset of file name field length */
#define LOCEXT 28 /* offset of extra field length */
#define LOCHDR 30 /* size of local header, including sig */
#define EXTHDR 16 /* size of extended local header, inc sig */
/* Macros for getting two-byte and four-byte header values */
#define SH(p) ((ush)(uch)((p)[0]) | ((ush)(uch)((p)[1]) << 8))
#define LG(p) ((ulg)(SH(p)) | ((ulg)(SH((p)+2)) << 16))
/* Function prototypes */
ulg updcrc OF((uch *, int));
int inflate OF((void));
void err OF((int, char *));
void main OF((int, char **));
/* Globals */
FILE *in, *out; /* input and output files */
union work area; /* inflate sliding window */
uch *outbuf; /* malloc'ed output buffer */
uch *outptr; /* points to next byte in output buffer */
int outcnt; /* bytes in output buffer */
ulg outsiz; /* total bytes written to out */
int decrypt; /* flag to turn on decryption */
char *key; /* not used--needed to link crypt.c */
/* Masks for inflate.c */
ush mask_bits[] = {
0x0000,
0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
};
/* Table of CRC-32's of all single-byte values (made by makecrc.c) */
ulg crc_32_tab[] = {
0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
0x2d02ef8dL
};
ulg updcrc(s, n)
uch *s; /* pointer to bytes to pump through */
int n; /* number of bytes in s[] */
/* Run a set of bytes through the crc shift register. If s is a NULL
pointer, then initialize the crc shift register contents instead.
Return the current crc in either case. */
{
register ulg c; /* temporary variable */
static ulg crc = 0xffffffffL; /* shift register contents */
if (s == NULL)
c = 0xffffffffL;
else
{
c = crc;
while (n--)
c = crc_32_tab[((int)c ^ (*s++)) & 0xff] ^ (c >> 8);
}
crc = c;
return c ^ 0xffffffffL; /* (instead of ~c for 64-bit machines) */
}
void err(n, m)
int n;
char *m;
/* Exit on error with a message and a code */
{
fprintf(stderr, "funzip error: %s\n", m);
exit(n);
}
int ReadByte(b)
ush *b;
/* Used by inflate.c to get a byte (archaism from unzip) */
{
register int c = getc(in);
if (c == EOF)
return 0;
#ifdef CRYPT
if (decrypt)
zdecode(c);
#endif
*b = (ush)c;
return 8;
}
int FlushOutput()
/* Empty output buffer */
{
if (outcnt)
{
updcrc(outbuf, outcnt);
if (fwrite((char *)outbuf, 1,outcnt,out) != outcnt)
err(9, "out of space on stdout");
outsiz += outcnt;
outptr = outbuf;
outcnt = 0;
}
return 0;
}
void main(argc, argv)
int argc;
char **argv;
/* Given a zip file on stdin, decompress the first entry to stdout. */
{
uch h[LOCHDR]; /* first local header */
#ifdef CRYPT
char *s = " [-password]";
char *p; /* password */
#else /* !CRYPT */
char *s = "";
#endif /* ?CRYPT */
/* skip executable name */
argc--;
argv++;
#ifdef CRYPT
/* get the command line password, if any */
p = NULL;
if (argc && **argv == '-')
{
argc--;
p = 1 + *argv++;
}
#endif /* ?CRYPT */
/* if no file argument and stdin not redirected, give the user help */
if (argc == 0 && isatty(0))
{
fprintf(stderr, "FUnZip (Filter UnZip), version %s\n", VERSION);
fprintf(stderr, "usage: ... | funzip%s | ...\n", s);
fprintf(stderr, " ... | funzip%s > outfile\n", s);
fprintf(stderr, " funzip%s infile.zip > outfile\n", s);
fprintf(stderr,
" extracts to stdout the first zip entry of stdin.\n");
exit(3);
}
/* prepare to be a binary filter */
if ((outbuf = (uch *)malloc(OUTBUFSIZ)) == NULL)
err(1, "out of memory");
if (argc)
{
if ((in = fopen(*argv, FOPR)) == NULL)
err(2, "cannot find input file");
}
else
{
#ifdef DOS_OS2
setmode(0, O_BINARY); /* some buggy C libraries require BOTH :-( the */
#endif /* setmode() call AND the fdopen() in binary mode */
if ((in = fdopen(0, FOPR)) == NULL)
err(2, "cannot find stdin");
}
#ifdef DOS_OS2
setmode(1, O_BINARY);
#endif
if ((out = fdopen(1, FOPW)) == NULL)
err(2, "cannot write to stdout");
/* read local header, check validity, and skip name and extra fields */
if (fread((char *)h, 1, LOCHDR, in) != LOCHDR || LG(h) != LOCSIG)
err(3, "input not a zip file or empty");
if (SH(h + LOCHOW) != STORED && SH(h + LOCHOW) != DEFLATED)
err(3, "first entry not deflated or stored--can't funzip");
fseek(in, (long)(SH(h + LOCFIL)) + (long)(SH(h + LOCEXT)), 1);
/* if entry encrypted, decrypt and validate encryption header */
if ((decrypt = h[LOCFLG] & CRPFLG) != 0)
#ifdef CRYPT
{
ush i, e;
if (p == NULL)
if ((p = (char *)malloc(PWLEN+1)) == NULL)
err(1, "out of memory");
else if ((p = getp("Enter password: ", p, PWLEN+1)) == NULL)
err(1, "no tty to prompt for password");
init_keys(p);
for (i = 0; i < RAND_HEAD_LEN; i++)
ReadByte(&e);
/* if (e != (h[LOCFLG] & EXTFLG ? SH(h + LOCTIM) : SH(h + LOCCRC + 2))) */
if (e != (ush)(h[LOCFLG] & EXTFLG ? h[LOCTIM + 1] : h[LOCCRC + 3]))
err(3, "incorrect password for first entry");
}
#else /* !CRYPT */
err(3, "cannot decrypt entry (need to recompile with full crypt.c)");
#endif /* ?CRYPT */
/* prepare output buffer and crc */
outptr = outbuf;
outcnt = 0;
outsiz = 0L;
updcrc(NULL, 0);
/* decompress */
if (h[LOCHOW])
{ /* deflated entry */
int r;
if ((r = inflate()) != 0)
if (r == 3)
err(1, "out of memory");
else
err(4, "invalid compressed data--format violated");
}
else
{ /* stored entry */
register ulg n;
n = LG(h + LOCLEN);
if (n != LG(h + LOCSIZ) - (decrypt ? RAND_HEAD_LEN : 0)) {
fprintf(stderr, "len %ld, siz %ld\n", n, LG(h + LOCSIZ));
err(4, "invalid compressed data--length mismatch");
}
while (n--) {
ush c = getc(in);
#ifdef CRYPT
if (decrypt)
zdecode(c);
#endif
OUTB(c);
}
}
FlushOutput();
fflush(out);
/* if extended header, get it */
if ((h[LOCFLG] & EXTFLG) &&
fread((char *)h + LOCCRC - 4, 1, EXTHDR, in) != EXTHDR)
err(3, "zip file ended prematurely");
/* validate decompression */
if (LG(h + LOCCRC) != updcrc(outbuf, 0))
err(4, "invalid compressed data--crc error");
if (LG(h + LOCLEN) != outsiz)
err(4, "invalid compressed data--length error");
/* check if there are more entries */
if (fread((char *)h, 1, 4, in) == 4 && LG(h) == LOCSIG)
fprintf(stderr,
"funzip warning: zip file has more than one entry--rest ignored\n");
exit(0);
}
MD5.c
- Code: Select all
/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
*/
/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
rights reserved.
License to copy and use this software is granted provided that it
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
Algorithm" in all material mentioning or referencing this software
or this function.
License is also granted to make and use derivative works provided
that such works are identified as "derived from the RSA Data
Security, Inc. MD5 Message-Digest Algorithm" in all material
mentioning or referencing the derived work.
RSA Data Security, Inc. makes no representations concerning either
the merchantability of this software or the suitability of this
software for any particular purpose. It is provided "as is"
without express or implied warranty of any kind.
These notices must be retained in any copies of any part of this
documentation and/or software.
*/
/*
*/
#include "versions.h"
#pragma warning (disable: 4131)
#include "global.h"
#include "md5.h"
/* Constants for MD5Transform routine.
*/
#define S11 7
#define S12 12
#define S13 17
#define S14 22
#define S21 5
#define S22 9
#define S23 14
#define S24 20
#define S31 4
#define S32 11
#define S33 16
#define S34 23
#define S41 6
#define S42 10
#define S43 15
#define S44 21
static void MD5Transform PROTO_LIST ( (UINT4 [4], unsigned char [64]));
static void Encode PROTO_LIST
( (unsigned char *, UINT4 *, unsigned int));
static void Decode PROTO_LIST
( (UINT4 *, unsigned char *, unsigned int));
static void MD5_memcpy PROTO_LIST ( (POINTER, POINTER, unsigned int));
static void MD5_memset PROTO_LIST ( (POINTER, int, unsigned int));
static unsigned char PADDING[64] =
{
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
};
/* F, G, H and I are basic MD5 functions.
*/
#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)))
/* ROTATE_LEFT rotates x left n bits.
*/
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
Rotation is separate from addition to prevent recomputation.
*/
#define FF(a, b, c, d, x, s, ac) { \
(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define GG(a, b, c, d, x, s, ac) { \
(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define HH(a, b, c, d, x, s, ac) { \
(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define II(a, b, c, d, x, s, ac) { \
(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
/* MD5 initialization. Begins an MD5 operation, writing a new context.
*/
void MD5Init (context)
MD5_CTX *context; /* context */
{
context->count[0] = context->count[1] = 0;
/* Load magic initialization constants.
*/
context->state[0] = 0x67452301;
context->state[1] = 0xefcdab89;
context->state[2] = 0x98badcfe;
context->state[3] = 0x10325476;
}
/* MD5 block update operation. Continues an MD5 message-digest
operation, processing another message block, and updating the
context.
*/
void MD5Update (context, input, inputLen)
MD5_CTX *context; /* context */
unsigned char *input; /* input block */
unsigned int inputLen; /* length of input block */
{
unsigned int i, index, partLen;
/* Compute number of bytes mod 64 */
index = (unsigned int) ( (context->count[0] >> 3) & 0x3F);
/* Update number of bits */
if ( (context->count[0] += ( (UINT4) inputLen << 3))
< ( (UINT4) inputLen << 3))
context->count[1]++;
context->count[1] += ( (UINT4) inputLen >> 29);
partLen = 64 - index;
/* Transform as many times as possible.
*/
if (inputLen >= partLen)
{
MD5_memcpy
( (POINTER) &context->buffer[index], (POINTER) input, partLen);
MD5Transform (context->state, context->buffer);
for (i = partLen; i + 63 < inputLen; i += 64)
MD5Transform (context->state, &input[i]);
index = 0;
}
else
i = 0;
/* Buffer remaining input */
MD5_memcpy
( (POINTER) &context->buffer[index], (POINTER) &input[i],
inputLen - i);
}
/* MD5 finalization. Ends an MD5 message-digest operation, writing the
the message digest and zeroizing the context.
*/
void MD5Final (digest, context)
unsigned char digest[16]; /* message digest */
MD5_CTX *context; /* context */
{
unsigned char bits[8];
unsigned int index, padLen;
/* Save number of bits */
Encode (bits, context->count, 8);
/* Pad out to 56 mod 64.
*/
index = (unsigned int) ( (context->count[0] >> 3) & 0x3f);
padLen = (index < 56) ? (56 - index) : (120 - index);
MD5Update (context, PADDING, padLen);
/* Append length (before padding) */
MD5Update (context, bits, 8);
/* Store state in digest */
Encode (digest, context->state, 16);
/* Zeroize sensitive information.
*/
MD5_memset ( (POINTER) context, 0, sizeof (*context));
}
/* MD5 basic transformation. Transforms state based on block.
*/
static void MD5Transform (state, block)
UINT4 state[4];
unsigned char block[64];
{
UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
Decode (x, block, 64);
/* Round 1 */
FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
/* Round 2 */
GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
/* Round 3 */
HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
/* Round 4 */
II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
/* Zeroize sensitive information.
*/
MD5_memset ( (POINTER) x, 0, sizeof (x));
}
/* Encodes input (UINT4) into output (unsigned char). Assumes len is
a multiple of 4.
*/
static void Encode (output, input, len)
unsigned char *output;
UINT4 *input;
unsigned int len;
{
unsigned int i, j;
for (i = 0, j = 0; j < len; i++, j += 4)
{
output[j] = (unsigned char) (input[i] & 0xff);
output[j+1] = (unsigned char) ( (input[i] >> 8) & 0xff);
output[j+2] = (unsigned char) ( (input[i] >> 16) & 0xff);
output[j+3] = (unsigned char) ( (input[i] >> 24) & 0xff);
}
}
/* Decodes input (unsigned char) into output (UINT4). Assumes len is
a multiple of 4.
*/
static void Decode (output, input, len)
UINT4 *output;
unsigned char *input;
unsigned int len;
{
unsigned int i, j;
for (i = 0, j = 0; j < len; i++, j += 4)
output[i] = ((UINT4) input[j]) | (((UINT4) input[j + 1]) << 8) |
(((UINT4) input[j + 2]) << 16) | (((UINT4) input[j + 3]) << 24);
}
/* Note: Replace "for loop" with standard memcpy if possible.
*/
static void MD5_memcpy (output, input, len)
POINTER output;
POINTER input;
unsigned int len;
{
unsigned int i;
for (i = 0; i < len; i++)
output[i] = input[i];
}
/* Note: Replace "for loop" with standard memset if possible.
*/
static void MD5_memset (output, value, len)
POINTER output;
int value;
unsigned int len;
{
unsigned int i;
for (i = 0; i < len; i++)
( (char *) output)[i] = (char) value;
}
/*
=================
MD5_Driver
Standard driver implementation for encoding data of an arbitrary length. Both data and checksum
must be valid pointers!!!
=================
*/
#define MD_CTX MD5_CTX
#define MDInit MD5Init
#define MDUpdate MD5Update
#define MDFinal MD5Final
void MD5_Checksum (unsigned char *data, int dataLen, unsigned char *checksum)
{
MD_CTX context;
int i;
unsigned char digest[16];
MDInit (&context);
MDUpdate (&context, data, dataLen);
MDFinal (digest, &context);
// copy digest to checksum
for (i = 0; i < 16; i++)
{
checksum[i] = digest[i];
}
}
char MD5_Compare (unsigned char *digest1, unsigned char *digest2)
{
int i;
for (i = 0; i < 16; i++)
{
if (digest1[i] != digest2[i])
return 0;
}
return 1;
}
void MD5_Copy (unsigned char *srcdigest, unsigned char *dstdigest)
{
int i;
for (i = 0; i < 16; i++)
{
dstdigest[i] = srcdigest[i];
}
}
The night is young. How else can I annoy the world before sunsrise?
Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
-

Baker - Posts: 3666
- Joined: Tue Mar 14, 2006 5:15 am
Re: MD5 and Zip Libraries
the only time I've used md5 hashes was for smtp/pop3 protocol stuff...
if you're protecting passwords, you should use something else if you're not bound by compatibility.
if its just for cheat protection then I guess it makes no real difference.
sha1 is generally greatly favoured nowadays.
if you're protecting passwords, you should use something else if you're not bound by compatibility.
if its just for cheat protection then I guess it makes no real difference.
sha1 is generally greatly favoured nowadays.
- Spike
- Posts: 2892
- Joined: Fri Nov 05, 2004 3:12 am
- Location: UK
Re: MD5 and Zip Libraries
miniz is also Public Domain:
http://code.google.com/p/miniz/
On top of that if you're already using zlib all you need to do is place the source file in your project and you're set.
http://code.google.com/p/miniz/
On top of that if you're already using zlib all you need to do is place the source file in your project and you're set.
- Stroggos
- Posts: 50
- Joined: Tue Apr 14, 2009 11:40 am
- Location: Australia
Re: MD5 and Zip Libraries
Spike wrote:if its just for cheat protection then I guess it makes no real difference.
That wasn't something I was thinking or worrying about.
I'm thinking about the traditional uses of checksums, like valid validation (did file download correctly, did file change?) or texture compares and such.
The night is young. How else can I annoy the world before sunsrise?
Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
-

Baker - Posts: 3666
- Joined: Tue Mar 14, 2006 5:15 am
Re: MD5 and Zip Libraries
aye, makes no real difference then. md5 is a little faster than sha1, so still works nicely for hashes and stuff, though its not as fast as eg adler32 (commonly part of zlib).
heck, texture compares could probably be just the first four bytes of the image, though I know that zquake+ uses crcs for that.
from a quakeworld perspective, all engines already have code for md4, as well as some 16bit crc. Spoilt for choice really. The crc provides network proxy protection (supposedly), while md4 provides map verification to stop people from chopping out all the walls in the map.
Soo... As you were!
heck, texture compares could probably be just the first four bytes of the image, though I know that zquake+ uses crcs for that.
from a quakeworld perspective, all engines already have code for md4, as well as some 16bit crc. Spoilt for choice really. The crc provides network proxy protection (supposedly), while md4 provides map verification to stop people from chopping out all the walls in the map.
Soo... As you were!
- Spike
- Posts: 2892
- Joined: Fri Nov 05, 2004 3:12 am
- Location: UK
Re: MD5 and Zip Libraries
Spike wrote:md4 provides map verification to stop people from chopping out all the walls in the map.
Well, anti-wallhack means I care about this in what way exactly?
Sure particles aren't filtered, but that's rather tame stuff. I guess in my mind I consider model checking and map hacking as entirely irrelevant in this day and age. Maybe still cheaters can "see someone behind them", but if you can be silent waiting around the next corner unseen and nothing a cheater can do about it, I see that as a settled issue.
I thought even Quakeworld was using anti-wallhack now. Maybe I am wrong? If so, what is the reason QW will not use anti-wallhack?
The night is young. How else can I annoy the world before sunsrise?
Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
-

Baker - Posts: 3666
- Joined: Tue Mar 14, 2006 5:15 am
12 posts
• Page 1 of 1
Who is online
Users browsing this forum: No registered users and 1 guest