md5.c revision 6725
1234353Sdim/*
2218885Sdim * $Id: md5.c,v 1.2 1995/02/20 00:48:50 phk Exp $
3218885Sdim *
4218885Sdim * Derived from:
5218885Sdim */
6218885Sdim
7218885Sdim/*
8218885Sdim * MDDRIVER.C - test driver for MD2, MD4 and MD5
9218885Sdim */
10218885Sdim
11218885Sdim/*
12218885Sdim *  Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All
13218885Sdim *  rights reserved.
14218885Sdim *
15218885Sdim *  RSA Data Security, Inc. makes no representations concerning either
16218885Sdim *  the merchantability of this software or the suitability of this
17218885Sdim *  software for any particular purpose. It is provided "as is"
18218885Sdim *  without express or implied warranty of any kind.
19218885Sdim *
20218885Sdim *  These notices must be retained in any copies of any part of this
21234353Sdim *  documentation and/or software.
22226633Sdim */
23263508Sdim
24249423Sdim#include <stdio.h>
25249423Sdim#include <time.h>
26263508Sdim#include <string.h>
27249423Sdim#include "global.h"
28249423Sdim#include <md5.h>
29249423Sdim
30218885Sdim/*
31218885Sdim * Length of test block, number of test blocks.
32218885Sdim */
33218885Sdim#define TEST_BLOCK_LEN 1000
34218885Sdim#define TEST_BLOCK_COUNT 1000
35218885Sdim
36218885Sdimstatic void MDString PROTO_LIST((char *));
37249423Sdimstatic void MDTimeTrial PROTO_LIST((void));
38249423Sdimstatic void MDTestSuite PROTO_LIST((void));
39249423Sdimstatic void MDFilter PROTO_LIST((int));
40249423Sdim
41218885Sdim/* Main driver.
42218885Sdim
43218885SdimArguments (may be any combination):
44218885Sdim  -sstring - digests string
45249423Sdim  -t       - runs time trial
46249423Sdim  -x       - runs test script
47218885Sdim  filename - digests file
48218885Sdim  (none)   - digests standard input
49218885Sdim */
50218885Sdimint
51218885Sdimmain(argc, argv)
52249423Sdim	int     argc;
53249423Sdim	char   *argv[];
54218885Sdim{
55226633Sdim	int     i;
56218885Sdim	char   *p;
57249423Sdim
58249423Sdim	if (argc > 1)
59249423Sdim		for (i = 1; i < argc; i++)
60249423Sdim			if (argv[i][0] == '-' && argv[i][1] == 's')
61218885Sdim				MDString(argv[i] + 2);
62218885Sdim			else if (strcmp(argv[i], "-t") == 0)
63218885Sdim				MDTimeTrial();
64218885Sdim			else if (strcmp(argv[i], "-p") == 0)
65218885Sdim				MDFilter(1);
66243830Sdim			else if (strcmp(argv[i], "-x") == 0)
67218885Sdim				MDTestSuite();
68218885Sdim			else {
69218885Sdim				p = MD5File(argv[i]);
70218885Sdim				if (!p)
71218885Sdim					perror(argv[i]);
72218885Sdim				else
73218885Sdim					printf("MD5 (%s) = %s\n", argv[i], p);
74218885Sdim			}
75218885Sdim	else
76218885Sdim		MDFilter(0);
77218885Sdim
78249423Sdim	return (0);
79218885Sdim}
80218885Sdim/*
81218885Sdim * Digests a string and prints the result.
82218885Sdim */
83218885Sdimstatic void
84218885SdimMDString(string)
85218885Sdim	char   *string;
86218885Sdim{
87218885Sdim	unsigned int len = strlen(string);
88218885Sdim
89218885Sdim	printf("MD5 (\"%s\") = %s\n", string, MD5Data(string, len));
90218885Sdim}
91218885Sdim/*
92218885Sdim * Measures the time to digest TEST_BLOCK_COUNT TEST_BLOCK_LEN-byte blocks.
93218885Sdim */
94218885Sdimstatic void
95218885SdimMDTimeTrial()
96218885Sdim{
97218885Sdim	MD5_CTX context;
98218885Sdim	time_t  endTime, startTime;
99218885Sdim	unsigned char block[TEST_BLOCK_LEN];
100218885Sdim	unsigned int i;
101218885Sdim	char   *p;
102218885Sdim
103218885Sdim	printf
104218885Sdim	    ("MD5 time trial. Digesting %d %d-byte blocks ...",
105243830Sdim	    TEST_BLOCK_LEN, TEST_BLOCK_COUNT);
106243830Sdim
107218885Sdim	/* Initialize block */
108218885Sdim	for (i = 0; i < TEST_BLOCK_LEN; i++)
109218885Sdim		block[i] = (unsigned char) (i & 0xff);
110218885Sdim
111218885Sdim	/* Start timer */
112218885Sdim	time(&startTime);
113218885Sdim
114218885Sdim	/* Digest blocks */
115218885Sdim	MD5Init(&context);
116218885Sdim	for (i = 0; i < TEST_BLOCK_COUNT; i++)
117218885Sdim		MD5Update(&context, block, TEST_BLOCK_LEN);
118218885Sdim	p = MD5End(&context);
119218885Sdim
120218885Sdim	/* Stop timer */
121218885Sdim	time(&endTime);
122218885Sdim
123218885Sdim	printf(" done\n");
124218885Sdim	printf("Digest = %s", p);
125218885Sdim	printf("\nTime = %ld seconds\n", (long) (endTime - startTime));
126218885Sdim	/* Be careful that endTime-startTime is not zero. (Bug fix from Ric
127218885Sdim	 * Anderson, ric@Artisoft.COM.) */
128218885Sdim	printf
129218885Sdim	    ("Speed = %ld bytes/second\n",
130218885Sdim	    (long) TEST_BLOCK_LEN * (long) TEST_BLOCK_COUNT / ((endTime - startTime) != 0 ? (endTime - startTime) : 1));
131218885Sdim}
132218885Sdim/*
133218885Sdim * Digests a reference suite of strings and prints the results.
134218885Sdim */
135218885Sdimstatic void
136218885SdimMDTestSuite()
137218885Sdim{
138218885Sdim	printf("MD5 test suite:\n");
139218885Sdim
140218885Sdim	MDString("");
141218885Sdim	MDString("a");
142218885Sdim	MDString("abc");
143218885Sdim	MDString("message digest");
144218885Sdim	MDString("abcdefghijklmnopqrstuvwxyz");
145218885Sdim	MDString
146218885Sdim	    ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
147218885Sdim	MDString
148218885Sdim	    ("1234567890123456789012345678901234567890\
149218885Sdim1234567890123456789012345678901234567890");
150218885Sdim}
151218885Sdim
152218885Sdim/*
153218885Sdim * Digests the standard input and prints the result.
154218885Sdim */
155218885Sdimstatic void
156218885SdimMDFilter(int pipe)
157218885Sdim{
158218885Sdim	MD5_CTX context;
159218885Sdim	int     len;
160218885Sdim	unsigned char buffer[BUFSIZ], digest[16];
161218885Sdim
162218885Sdim	MD5Init(&context);
163218885Sdim	while (len = fread(buffer, 1, BUFSIZ, stdin)) {
164218885Sdim		if(pipe && (len != fwrite(buffer, 1, len, stdout)))
165218885Sdim			perror(stdout);
166218885Sdim		MD5Update(&context, buffer, len);
167218885Sdim	}
168218885Sdim	printf("%s\n", MD5End(&context));
169218885Sdim}
170218885Sdim