164660f81818005d840f4487c96b9d1d6f490730
[profile/ivi/qtbase.git] / src / corelib / tools / qcryptographichash.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtCore module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include <qcryptographichash.h>
43
44 #include "../../3rdparty/md5/md5.h"
45 #include "../../3rdparty/md5/md5.cpp"
46 #include "../../3rdparty/md4/md4.h"
47 #include "../../3rdparty/md4/md4.cpp"
48 #include "../../3rdparty/sha1/sha1.cpp"
49 #include <qiodevice.h>
50
51
52 QT_BEGIN_NAMESPACE
53
54 class QCryptographicHashPrivate
55 {
56 public:
57     QCryptographicHash::Algorithm method;
58     union {
59         MD5Context md5Context;
60         md4_context md4Context;
61         Sha1State sha1Context;
62     };
63     QByteArray result;
64 };
65
66 /*!
67   \class QCryptographicHash
68
69   \brief The QCryptographicHash class provides a way to generate cryptographic hashes.
70
71   \since 4.3
72
73   \ingroup tools
74   \reentrant
75
76   QCryptographicHash can be used to generate cryptographic hashes of binary or text data.
77
78   Currently MD4, MD5, and SHA-1 are supported.
79 */
80
81 /*!
82   \enum QCryptographicHash::Algorithm
83
84   \value Md4 Generate an MD4 hash sum
85   \value Md5 Generate an MD5 hash sum
86   \value Sha1 Generate an SHA1 hash sum
87 */
88
89 /*!
90   Constructs an object that can be used to create a cryptographic hash from data using \a method.
91 */
92 QCryptographicHash::QCryptographicHash(Algorithm method)
93     : d(new QCryptographicHashPrivate)
94 {
95     d->method = method;
96     reset();
97 }
98
99 /*!
100   Destroys the object.
101 */
102 QCryptographicHash::~QCryptographicHash()
103 {
104     delete d;
105 }
106
107 /*!
108   Resets the object.
109 */
110 void QCryptographicHash::reset()
111 {
112     switch (d->method) {
113     case Md4:
114         md4_init(&d->md4Context);
115         break;
116     case Md5:
117         MD5Init(&d->md5Context);
118         break;
119     case Sha1:
120         sha1InitState(&d->sha1Context);
121         break;
122     }
123     d->result.clear();
124 }
125
126 /*!
127     Adds the first \a length chars of \a data to the cryptographic
128     hash.
129 */
130 void QCryptographicHash::addData(const char *data, int length)
131 {
132     switch (d->method) {
133     case Md4:
134         md4_update(&d->md4Context, (const unsigned char *)data, length);
135         break;
136     case Md5:
137         MD5Update(&d->md5Context, (const unsigned char *)data, length);
138         break;
139     case Sha1:
140         sha1Update(&d->sha1Context, (const unsigned char *)data, length);
141         break;
142     }    
143     d->result.clear();
144 }
145
146 /*!
147   \overload addData()
148 */
149 void QCryptographicHash::addData(const QByteArray &data)
150 {
151     addData(data.constData(), data.length());
152 }
153
154 /*!
155   Reads the data from the open QIODevice \a device until it ends
156   and hashes it. Returns true if reading was successful.
157  */
158 bool QCryptographicHash::addData(QIODevice* device)
159 {
160     if (!device->isReadable())
161         return false;
162
163     if (!device->isOpen())
164         return false;
165
166     char buffer[1024];
167     int length;
168
169     while ((length = device->read(buffer,sizeof(buffer))) > 0)
170         addData(buffer,length);
171
172     return device->atEnd();
173 }
174
175
176 /*!
177   Returns the final hash value.
178
179   \sa QByteArray::toHex()
180 */
181 QByteArray QCryptographicHash::result() const
182 {
183     if (!d->result.isEmpty()) 
184         return d->result;
185
186     switch (d->method) {
187     case Md4: {
188         md4_context copy = d->md4Context;
189         d->result.resize(MD4_RESULTLEN);
190         md4_final(&copy, (unsigned char *)d->result.data());
191         break;
192     }
193     case Md5: {
194         MD5Context copy = d->md5Context;
195         d->result.resize(16);
196         MD5Final(&copy, (unsigned char *)d->result.data());
197         break;
198     }
199     case Sha1: {
200         Sha1State copy = d->sha1Context;
201         d->result.resize(20);
202         sha1FinalizeState(&copy);
203         sha1ToHash(&copy, (unsigned char *)d->result.data());
204     }
205     }
206     return d->result;
207 }
208
209 /*!
210   Returns the hash of \a data using \a method.
211 */
212 QByteArray QCryptographicHash::hash(const QByteArray &data, Algorithm method)
213 {
214     QCryptographicHash hash(method);
215     hash.addData(data);
216     return hash.result();
217 }
218
219 QT_END_NAMESPACE