132
|
1 /******************************************************************************
|
|
2
|
|
3 copyright: Copyright (c) 2006 Tango. All rights reserved
|
|
4
|
|
5 license: BSD style: see doc/license.txt for details
|
|
6
|
|
7 version: Initial release: Feb 2006
|
|
8
|
|
9 author: Regan Heath, Oskar Linde
|
|
10
|
|
11 This module defines the Digest interface.
|
|
12
|
|
13 ******************************************************************************/
|
|
14
|
|
15 module tango.io.digest.Digest;
|
|
16
|
|
17 private import tango.stdc.stdlib : alloca;
|
|
18
|
|
19 /*******************************************************************************
|
|
20
|
|
21 The DigestTransform interface defines the interface of message
|
|
22 digest algorithms, such as MD5 and SHA. Message digests are
|
|
23 secure hash functions that take a message of arbitrary length
|
|
24 and produce a fix length digest as output.
|
|
25
|
|
26 A object implementing the DigestTransform should start out initialized.
|
|
27 The data is processed though calls to the update method. Once all data
|
|
28 has been sent to the algorithm, the digest is finalized and computed
|
|
29 with the digest method.
|
|
30
|
|
31 The digest method may only be called once. After the digest
|
|
32 method has been called, the algorithm is reset to its initial
|
|
33 state.
|
|
34
|
|
35 Using the update method, data may be processed piece by piece,
|
|
36 which is useful for cases involving streams of data.
|
|
37
|
|
38 For example:
|
|
39 ---
|
|
40 // create an MD5 hash algorithm
|
|
41 Md5 hash = new Md5();
|
|
42
|
|
43 // process some data
|
|
44 hash.update("The quick brown fox");
|
|
45
|
|
46 // process some more data
|
|
47 hash.update(" jumps over the lazy dog");
|
|
48
|
|
49 // conclude algorithm and produce digest
|
|
50 ubyte[] digest = hash.binaryDigest();
|
|
51 ---
|
|
52
|
|
53 ******************************************************************************/
|
|
54
|
|
55 abstract class Digest
|
|
56 {
|
|
57 /*********************************************************************
|
|
58
|
|
59 Processes data
|
|
60
|
|
61 Remarks:
|
|
62 Updates the hash algorithm state with new data
|
|
63
|
|
64 *********************************************************************/
|
|
65
|
|
66 abstract void update(void[] data);
|
|
67
|
|
68 /********************************************************************
|
|
69
|
|
70 Computes the digest and resets the state
|
|
71
|
|
72 Params:
|
|
73 buffer = a buffer can be supplied for the digest to be
|
|
74 written to
|
|
75
|
|
76 Remarks:
|
|
77 If the buffer is not large enough to hold the
|
|
78 digest, a new buffer is allocated and returned.
|
|
79 The algorithm state is always reset after a call to
|
|
80 binaryDigest. Use the digestSize method to find out how
|
|
81 large the buffer has to be.
|
|
82
|
|
83 *********************************************************************/
|
|
84
|
|
85 abstract ubyte[] binaryDigest(ubyte[] buffer = null);
|
|
86
|
|
87 /********************************************************************
|
|
88
|
|
89 Returns the size in bytes of the digest
|
|
90
|
|
91 Returns:
|
|
92 the size of the digest in bytes
|
|
93
|
|
94 Remarks:
|
|
95 Returns the size of the digest.
|
|
96
|
|
97 *********************************************************************/
|
|
98
|
|
99 abstract uint digestSize();
|
|
100
|
|
101 /*********************************************************************
|
|
102
|
|
103 Computes the digest as a hex string and resets the state
|
|
104
|
|
105 Params:
|
|
106 buffer = a buffer can be supplied in which the digest
|
|
107 will be written. It needs to be able to hold
|
|
108 2 * digestSize chars
|
|
109
|
|
110 Remarks:
|
|
111 If the buffer is not large enough to hold the hex digest,
|
|
112 a new buffer is allocated and returned. The algorithm
|
|
113 state is always reset after a call to hexDigest.
|
|
114
|
|
115 *********************************************************************/
|
|
116
|
|
117 char[] hexDigest (char[] buffer = null)
|
|
118 {
|
|
119 uint ds = digestSize();
|
|
120
|
|
121 if (buffer.length < ds * 2)
|
|
122 buffer.length = ds * 2;
|
|
123
|
|
124 ubyte[] buf = (cast(ubyte *) alloca(ds))[0..ds];
|
|
125 ubyte[] ret = binaryDigest(buf);
|
|
126 assert(ret.ptr == buf.ptr);
|
|
127
|
|
128 static char[] hexdigits = "0123456789abcdef";
|
|
129 int i = 0;
|
|
130
|
|
131 foreach (b; buf)
|
|
132 {
|
|
133 buffer[i++] = hexdigits[b >> 4];
|
|
134 buffer[i++] = hexdigits[b & 0xf];
|
|
135 }
|
|
136
|
|
137 return buffer;
|
|
138 }
|
|
139 }
|
|
140
|