md5.c revision 22990
1/*
2 * $Id$
3 *
4 * Derived from:
5 */
6
7/*
8 * MDDRIVER.C - test driver for MD2, MD4 and MD5
9 */
10
11/*
12 *  Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All
13 *  rights reserved.
14 *
15 *  RSA Data Security, Inc. makes no representations concerning either
16 *  the merchantability of this software or the suitability of this
17 *  software for any particular purpose. It is provided "as is"
18 *  without express or implied warranty of any kind.
19 *
20 *  These notices must be retained in any copies of any part of this
21 *  documentation and/or software.
22 */
23
24#include <sys/types.h>
25#include <md5.h>
26
27#include <stdio.h>
28#include <string.h>
29#include <time.h>
30
31#include "global.h"
32
33/*
34 * Length of test block, number of test blocks.
35 */
36#define TEST_BLOCK_LEN 1000
37#define TEST_BLOCK_COUNT 1000
38
39static void MDString PROTO_LIST((char *));
40static void MDTimeTrial PROTO_LIST((void));
41static void MDTestSuite PROTO_LIST((void));
42static void MDFilter PROTO_LIST((int));
43
44/* Main driver.
45
46Arguments (may be any combination):
47  -sstring - digests string
48  -t       - runs time trial
49  -x       - runs test script
50  filename - digests file
51  (none)   - digests standard input
52 */
53int
54main(argc, argv)
55	int     argc;
56	char   *argv[];
57{
58	int     i;
59	char   *p;
60	char	buf[33];
61
62	if (argc > 1)
63		for (i = 1; i < argc; i++)
64			if (argv[i][0] == '-' && argv[i][1] == 's')
65				MDString(argv[i] + 2);
66			else if (strcmp(argv[i], "-t") == 0)
67				MDTimeTrial();
68			else if (strcmp(argv[i], "-p") == 0)
69				MDFilter(1);
70			else if (strcmp(argv[i], "-x") == 0)
71				MDTestSuite();
72			else {
73				p = MD5File(argv[i],buf);
74				if (!p)
75					perror(argv[i]);
76				else
77					printf("MD5 (%s) = %s\n", argv[i], p);
78			}
79	else
80		MDFilter(0);
81
82	return (0);
83}
84/*
85 * Digests a string and prints the result.
86 */
87static void
88MDString(string)
89	char   *string;
90{
91	unsigned int len = strlen(string);
92	char buf[33];
93
94	printf("MD5 (\"%s\") = %s\n", string, MD5Data(string, len, buf));
95}
96/*
97 * Measures the time to digest TEST_BLOCK_COUNT TEST_BLOCK_LEN-byte blocks.
98 */
99static void
100MDTimeTrial()
101{
102	MD5_CTX context;
103	time_t  endTime, startTime;
104	unsigned char block[TEST_BLOCK_LEN];
105	unsigned int i;
106	char   *p, buf[33];
107
108	printf
109	    ("MD5 time trial. Digesting %d %d-byte blocks ...",
110	    TEST_BLOCK_COUNT, TEST_BLOCK_LEN);
111
112	/* Initialize block */
113	for (i = 0; i < TEST_BLOCK_LEN; i++)
114		block[i] = (unsigned char) (i & 0xff);
115
116	/* Start timer */
117	time(&startTime);
118
119	/* Digest blocks */
120	MD5Init(&context);
121	for (i = 0; i < TEST_BLOCK_COUNT; i++)
122		MD5Update(&context, block, TEST_BLOCK_LEN);
123	p = MD5End(&context,buf);
124
125	/* Stop timer */
126	time(&endTime);
127
128	printf(" done\n");
129	printf("Digest = %s", p);
130	printf("\nTime = %ld seconds\n", (long) (endTime - startTime));
131	/* Be careful that endTime-startTime is not zero. (Bug fix from Ric
132	 * Anderson, ric@Artisoft.COM.) */
133	printf
134	    ("Speed = %ld bytes/second\n",
135	    (long) TEST_BLOCK_LEN * (long) TEST_BLOCK_COUNT / ((endTime - startTime) != 0 ? (endTime - startTime) : 1));
136}
137/*
138 * Digests a reference suite of strings and prints the results.
139 */
140static void
141MDTestSuite()
142{
143	printf("MD5 test suite:\n");
144
145	MDString("");
146	MDString("a");
147	MDString("abc");
148	MDString("message digest");
149	MDString("abcdefghijklmnopqrstuvwxyz");
150	MDString
151	    ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
152	MDString
153	    ("1234567890123456789012345678901234567890\
1541234567890123456789012345678901234567890");
155}
156
157/*
158 * Digests the standard input and prints the result.
159 */
160static void
161MDFilter(int pipe)
162{
163	MD5_CTX context;
164	int     len;
165	unsigned char buffer[BUFSIZ], digest[16];
166	char buf[33];
167
168	MD5Init(&context);
169	while (len = fread(buffer, 1, BUFSIZ, stdin)) {
170		if(pipe && (len != fwrite(buffer, 1, len, stdout))) {
171			perror("stdout");
172			exit(1);
173		}
174		MD5Update(&context, buffer, len);
175	}
176	printf("%s\n", MD5End(&context,buf));
177}
178