VirtualBox

source: vbox/trunk/src/VBox/Runtime/testcase/tstRTDigest.cpp@ 25614

Last change on this file since 25614 was 23507, checked in by vboxsync, 15 years ago

IPRT: Added APIs for convering digests to/from strings.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 12.7 KB
Line 
1/* $Id: tstRTDigest.cpp 23507 2009-10-02 12:02:02Z vboxsync $ */
2/** @file
3 * IPRT Testcase - RTSha*, RTMd5, RTCrc*.
4 */
5
6/*
7 * Copyright (C) 2009 Sun Microsystems, Inc.
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 *
26 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
27 * Clara, CA 95054 USA or visit http://www.sun.com if you need
28 * additional information or have any questions.
29 */
30
31
32/*******************************************************************************
33* Header Files *
34*******************************************************************************/
35#include <iprt/sha.h>
36#include <iprt/md5.h>
37#include <iprt/crc32.h>
38#include <iprt/crc64.h>
39
40#include <iprt/ctype.h>
41#include <iprt/err.h>
42#include <iprt/file.h>
43#include <iprt/getopt.h>
44#include <iprt/initterm.h>
45#include <iprt/param.h>
46#include <iprt/path.h>
47#include <iprt/process.h>
48#include <iprt/string.h>
49#include <iprt/stream.h>
50
51
52static int Error(const char *pszFormat, ...)
53{
54 char szName[RTPATH_MAX];
55 if (!RTProcGetExecutableName(szName, sizeof(szName)))
56 strcpy(szName, "tstRTDigest");
57
58 RTStrmPrintf(g_pStdErr, "%s: error: ", RTPathFilename(szName));
59 va_list va;
60 va_start(va, pszFormat);
61 RTStrmPrintfV(g_pStdErr, pszFormat, va);
62 va_end(va);
63
64 return 1;
65}
66
67
68int main(int argc, char **argv)
69{
70 RTR3Init();
71
72 enum
73 {
74 kDigestType_NotSpecified,
75 kDigestType_CRC32,
76 kDigestType_CRC64,
77 kDigestType_MD5,
78 kDigestType_SHA1,
79 kDigestType_SHA256,
80 kDigestType_SHA512
81 } enmDigestType = kDigestType_NotSpecified;
82
83 enum
84 {
85 kMethod_Full,
86 kMethod_Block,
87 kMethod_File
88 } enmMethod = kMethod_Block;
89
90 static const RTGETOPTDEF s_aOptions[] =
91 {
92 { "--type", 't', RTGETOPT_REQ_STRING },
93 { "--method", 'm', RTGETOPT_REQ_STRING },
94 { "--help", 'h', RTGETOPT_REQ_NOTHING },
95 };
96
97 int ch;
98 RTGETOPTUNION ValueUnion;
99 RTGETOPTSTATE GetState;
100 RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, 0);
101 while ((ch = RTGetOpt(&GetState, &ValueUnion)))
102 {
103 switch (ch)
104 {
105 case 't':
106 if (!RTStrICmp(ValueUnion.psz, "crc32"))
107 enmDigestType = kDigestType_CRC32;
108 else if (!RTStrICmp(ValueUnion.psz, "crc64"))
109 enmDigestType = kDigestType_CRC64;
110 else if (!RTStrICmp(ValueUnion.psz, "md5"))
111 enmDigestType = kDigestType_MD5;
112 else if (!RTStrICmp(ValueUnion.psz, "sha1"))
113 enmDigestType = kDigestType_SHA1;
114 else if (!RTStrICmp(ValueUnion.psz, "sha256"))
115 enmDigestType = kDigestType_SHA256;
116 else if (!RTStrICmp(ValueUnion.psz, "sha512"))
117 enmDigestType = kDigestType_SHA512;
118 else
119 {
120 Error("Invalid digest type: %s\n", ValueUnion.psz);
121 return 1;
122 }
123 break;
124
125 case 'm':
126 if (!RTStrICmp(ValueUnion.psz, "full"))
127 enmMethod = kMethod_Full;
128 else if (!RTStrICmp(ValueUnion.psz, "block"))
129 enmMethod = kMethod_Block;
130 else if (!RTStrICmp(ValueUnion.psz, "file"))
131 enmMethod = kMethod_File;
132 else
133 {
134 Error("Invalid digest method: %s\n", ValueUnion.psz);
135 return 1;
136 }
137 break;
138
139 case 'h':
140 RTPrintf("syntax: tstRTDigest -t <digest-type> file [file2 [..]]\n");
141 return 1;
142
143 case VINF_GETOPT_NOT_OPTION:
144 {
145 if (enmDigestType == kDigestType_NotSpecified)
146 return Error("No digest type was specified\n");
147
148 switch (enmMethod)
149 {
150 case kMethod_Full:
151 return Error("Full file method is not implemented\n");
152
153 case kMethod_File:
154 switch (enmDigestType)
155 {
156 case kDigestType_SHA1:
157 {
158 char *pszDigest;
159 int rc = RTSha1Digest(ValueUnion.psz, &pszDigest);
160 if (RT_FAILURE(rc))
161 return Error("RTSha1Digest(%s,) -> %Rrc\n", ValueUnion.psz, rc);
162 RTPrintf("%s %s\n", pszDigest, ValueUnion.psz);
163 RTStrFree(pszDigest);
164 break;
165 }
166
167 default:
168 return Error("The file method isn't implemented for this digest\n");
169 }
170 break;
171
172 case kMethod_Block:
173 {
174 RTFILE hFile;
175 int rc = RTFileOpen(&hFile, ValueUnion.psz, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE);
176 if (RT_FAILURE(rc))
177 return Error("RTFileOpen(,%s,) -> %Rrc\n", ValueUnion.psz, rc);
178
179 size_t cbRead;
180 uint8_t abBuf[_64K];
181 char *pszDigest = (char *)&abBuf[0];
182 switch (enmDigestType)
183 {
184 case kDigestType_CRC32:
185 {
186 uint32_t uCRC32 = RTCrc32Start();
187 for (;;)
188 {
189 rc = RTFileRead(hFile, abBuf, sizeof(abBuf), &cbRead);
190 if (RT_FAILURE(rc) || !cbRead)
191 break;
192 uCRC32 = RTCrc32Process(uCRC32, abBuf, cbRead);
193 }
194 uCRC32 = RTCrc32Finish(uCRC32);
195 RTStrPrintf(pszDigest, sizeof(abBuf), "%08RX32", uCRC32);
196 break;
197 }
198
199 case kDigestType_CRC64:
200 {
201 uint64_t uCRC64 = RTCrc64Start();
202 for (;;)
203 {
204 rc = RTFileRead(hFile, abBuf, sizeof(abBuf), &cbRead);
205 if (RT_FAILURE(rc) || !cbRead)
206 break;
207 uCRC64 = RTCrc64Process(uCRC64, abBuf, cbRead);
208 }
209 uCRC64 = RTCrc64Finish(uCRC64);
210 RTStrPrintf(pszDigest, sizeof(abBuf), "%016RX64", uCRC64);
211 break;
212 }
213
214 case kDigestType_MD5:
215 {
216 RTMD5CONTEXT Ctx;
217 RTMd5Init(&Ctx);
218 for (;;)
219 {
220 rc = RTFileRead(hFile, abBuf, sizeof(abBuf), &cbRead);
221 if (RT_FAILURE(rc) || !cbRead)
222 break;
223 RTMd5Update(&Ctx, abBuf, cbRead);
224 }
225 uint8_t abDigest[RTMD5HASHSIZE];
226 RTMd5Final(abDigest, &Ctx);
227 RTMd5ToString(abDigest, pszDigest, sizeof(abBuf));
228 break;
229 }
230
231 case kDigestType_SHA1:
232 {
233 RTSHA1CONTEXT Ctx;
234 RTSha1Init(&Ctx);
235 for (;;)
236 {
237 rc = RTFileRead(hFile, abBuf, sizeof(abBuf), &cbRead);
238 if (RT_FAILURE(rc) || !cbRead)
239 break;
240 RTSha1Update(&Ctx, abBuf, cbRead);
241 }
242 uint8_t abDigest[RTSHA1_HASH_SIZE];
243 RTSha1Final(&Ctx, abDigest);
244 RTSha1ToString(abDigest, pszDigest, sizeof(abBuf));
245 break;
246 }
247
248 case kDigestType_SHA256:
249 {
250 RTSHA256CONTEXT Ctx;
251 RTSha256Init(&Ctx);
252 for (;;)
253 {
254 rc = RTFileRead(hFile, abBuf, sizeof(abBuf), &cbRead);
255 if (RT_FAILURE(rc) || !cbRead)
256 break;
257 RTSha256Update(&Ctx, abBuf, cbRead);
258 }
259 uint8_t abDigest[RTSHA256_HASH_SIZE];
260 RTSha256Final(&Ctx, abDigest);
261 RTSha256ToString(abDigest, pszDigest, sizeof(abBuf));
262 break;
263 }
264
265 case kDigestType_SHA512:
266 {
267 RTSHA512CONTEXT Ctx;
268 RTSha512Init(&Ctx);
269 for (;;)
270 {
271 rc = RTFileRead(hFile, abBuf, sizeof(abBuf), &cbRead);
272 if (RT_FAILURE(rc) || !cbRead)
273 break;
274 RTSha512Update(&Ctx, abBuf, cbRead);
275 }
276 uint8_t abDigest[RTSHA512_HASH_SIZE];
277 RTSha512Final(&Ctx, abDigest);
278 RTSha512ToString(abDigest, pszDigest, sizeof(abBuf));
279 break;
280 }
281
282 default:
283 return Error("Internal error #1\n");
284 }
285 RTFileClose(hFile);
286 if (RT_FAILURE(rc) && rc != VERR_EOF)
287 {
288 RTPrintf("Partial: %s %s\n", pszDigest, ValueUnion.psz);
289 return Error("RTFileRead(%s) -> %Rrc\n", ValueUnion.psz, rc);
290 }
291 RTPrintf("%s %s\n", pszDigest, ValueUnion.psz);
292 break;
293 }
294
295 default:
296 return Error("Internal error #2\n");
297 }
298 break;
299 }
300
301 default:
302 if (ch > 0)
303 {
304 if (RT_C_IS_GRAPH(ch))
305 Error("unhandled option: -%c\n", ch);
306 else
307 Error("unhandled option: %i\n", ch);
308 }
309 else if (ch == VERR_GETOPT_UNKNOWN_OPTION)
310 Error("unknown option: %s\n", ValueUnion.psz);
311 else if (ValueUnion.pDef)
312 Error("%s: %Rrs\n", ValueUnion.pDef->pszLong, ch);
313 else
314 Error("%Rrs\n", ch);
315 return 1;
316 }
317 }
318
319 return 0;
320}
321
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette