Міністерство освіти та науки України
Національний університет „Львівська політехніка”
кафедра ЕОМ
Звіт
про виконання лабораторної роботи № 4
На тему „Хеш функція. Алгоритм хешування MD5.”
Виконав:
ст. гр. КІ-4
Львів – 2005
Мета роботи: закріпити навики освоєння хеш функції, та алгоритму хешування MD5.
Завдання: За допомогою алгоритму хешування MD5 перетворити вхідну стрічку в хеш.
Вхідний текст для хешування:
This document specifies an Internet standards track protocol.
Фрагмент декодованого тексту:
D:\IV KYRS\Zaxust inf\md5vfp>md5.exe in.txt
MD5 (in.txt) = a9ecad671e2083a058105b60968104ec
Текст програми:
Файл main.c:
#define VERSION "2.0 (2003-04-15)"
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#ifdef _WIN32
#include <fcntl.h>
#include <io.h>
#endif
#include "md5.h"
#define FALSE0
#define TRUE1
#define EOS '\0'
/* Main program */
int main(argc, argv)
int argc; char *argv[];
{
int i, j, opt, cdata = FALSE, docheck = FALSE, showfile = TRUE, f = 0;
unsigned int bp;
char *cp, *clabel, *ifname, *hexfmt = "%02X";
FILE *in = stdin, *out = stdout;
unsigned char buffer[16384], signature[16], csig[16];
struct MD5Context md5c;
for (i = 1; i < argc; i++) {
cp = argv[i];
if (*cp == '-') {
if (strlen(cp) == 1) {
i++;
break; /* - -- Mark end of options; balance are files */
}
opt = *(++cp);
if (islower(opt)) {
opt = toupper(opt);
}
switch (opt) {
case 'C': /* -Csignature -- Check signature, set return code */
docheck = TRUE;
if (strlen(cp + 1) != 32) {
docheck = FALSE;
}
memset(csig, 0, 16);
clabel = cp + 1;
for (j = 0; j < 16; j++) {
if (isxdigit((int) clabel[0]) && isxdigit((int) clabel[1]) &&
sscanf((cp + 1 + (j * 2)), hexfmt, &bp) == 1) {
csig[j] = (unsigned char) bp;
} else {
docheck = FALSE;
break;
}
clabel += 2;
}
if (!docheck) {
fprintf(stderr, "Error in signature specification. Must be 32 hex digits.\n");
return 2;
}
break;
case 'D': /* -Dtext -- Compute signature of given text */
MD5Init(&md5c);
MD5Update(&md5c, (unsigned char *) (cp + 1), strlen(cp + 1));
cdata = TRUE;
f++; /* Mark no infile argument needed */
break;
case 'L': /* -L -- Use lower case letters as hex digits */
hexfmt = "%02x";
break;
case 'N': /* -N -- Don't show file name after sum */
showfile = FALSE;
break;
case 'O': /* -Ofname -- Write output to fname (- = stdout) */
cp++;
if (strcmp(cp, "-") != 0) {
if (out != stdout) {
fprintf(stderr, "Redundant output file specification.\n");
return 2;
}
if ((out = fopen(cp, "w")) == NULL) {
fprintf(stderr, "Cannot open output file %s\n", cp);
return 2;
}
}
break;
case '?': /* -U, -? -H -- Print how to call information. */
case 'H':
case 'U':
printf("\nMD5 -- Calculate MD5 signature of file. Call");
printf(
"\n with md5 [ options ] [file ...]");
printf("\n");
printf("\n Options:");
printf("\n -csig Check against sig, set exit status 0 = OK");
printf("\n -dtext Compute signature of text argument");
printf("\n -l Use lower case letters for hexadecimal digits");
printf("\n -n Do not show file name after sum");
printf("\n -ofname Write output to fname (- = stdout)");
printf("\n -u Print this message");
printf("\n -v Print version information");
printf("\n");
printf("\nby John Walker -- http://www.fourmilab.ch/");
printf("\nVersion %s\n", VERSION);
printf("\nThis program is in the public domain.\n");
printf("\n");
return 0;
case 'V': /* -V -- Print version number */
printf("%s\n", VERSION);
return 0;
}
} else {
break;
}
}
if (cdata && (i < argc)) {
fprintf(stderr, "Cannot specify both -d option and input file.\n");
return 2;
}
if ((i >= argc) && (f == 0)) {
f++;
}
for (; (f > 0) || (i < argc); i++) {
if ((!cdata) && (f > 0)) {
ifname = "-";
} else {
ifname = argv[i];
}f = 0;
if (!cdata) {
/* If the data weren't supplied on the command line with
the "-d" option, read it now from the input file. */
if (strcmp(ifname, "-") != 0) {
if ((in = fopen(ifname, "rb")) == NULL) {
fprintf(stderr, "Cannot open input file %s\n", ifname);
return 2;
}
} else {
in = stdin;
}
#ifdef _WIN32
_setmode(_fileno(in), _O_BINARY);
#endif
MD5Init(&md5c);
while ((j = (int) fread(buffer, 1, sizeof buffer, in)) > 0) {
MD5Update(&md5c, buffer, (unsigned) j);
}
}
MD5Final(signature, &md5c);
if (docheck) {
docheck = 0;
for (j = 0; j < sizeof signature; j++) {
if (signature[j] != csig[j]) {
docheck = 1;
break;
}
}
if (i < (argc - 1)) {
fprintf(stderr, "Only one file may be tested with the -c option.\n");
return 2;
}
} else {
for (j = 0; j < sizeof signature; j++) {
fprintf(out, hexfmt, signature[j]);
}
if ((!cdata) && showfile) {
fprintf(out, " %s", (in == stdin) ? "-" : ifname);
}
fprintf(out, "\n");
} }
return docheck;
}
Файл md5.h:
#ifndef MD5_H
#define MD5_H
#ifdef __alpha
typedef unsigned int uint32;
#else
typedef unsigned long uint32;
#endif
struct MD5Context {
uint32 buf[4];
uint32 bits[2];
unsigned char in[64];
};
extern void MD5Init();
extern void MD5Update();
extern void MD5Final();
extern void MD5Transform();
/*
* This is needed to make RSAREF happy on some MS-DOS compilers.
*/
typedef struct MD5Context MD5_CTX;
#endif /* !MD5_H */
Висновок: в ході даної лабораторної роботи ми навчились за допомогою алгоритму хешування MD5 створювати хеш для будь-якої вхідної послідовності.