blob: 461065b371f5b163fc1f41076d8e2dc0a0a69e03 [file] [log] [blame]
Emeric Vigier2f625822012-08-06 11:09:52 -04001// Copyright (C) 1999-2005 Open Source Telecom Corporation.
2// Copyright (C) 2006-2010 David Sugar, Tycho Softworks.
3//
4// This program is free software; you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation; either version 2 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program; if not, write to the Free Software
16// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17//
18// As a special exception, you may use this file as part of a free software
19// library without restriction. Specifically, if other files instantiate
20// templates or use macros or inline functions from this file, or you compile
21// this file and link it with other files to produce an executable, this
22// file does not by itself cause the resulting executable to be covered by
23// the GNU General Public License. This exception does not however
24// invalidate any other reasons why the executable file might be covered by
25// the GNU General Public License.
26//
27// This exception applies only to the code released under the name GNU
28// Common C++. If you copy code from other releases into a copy of GNU
29// Common C++, as the General Public License permits, the exception does
30// not apply to the code that you add in this way. To avoid misleading
31// anyone as to the status of such modified files, you must delete
32// this exception notice from them.
33//
34// If you write modifications of your own for GNU Common C++, it is your choice
35// whether to permit this exception to apply to your modifications.
36// If you do not wish that, delete this exception notice.
37//
38
39#include <cc++/config.h>
40#include <cc++/string.h>
41#include <cc++/exception.h>
42#include <cc++/thread.h>
43#include <cc++/export.h>
44#include <cc++/digest.h>
45
46#include <cstdio>
47#include <iomanip>
48
49#ifdef WIN32
50#include <io.h>
51#endif
52
53#ifdef CCXX_NAMESPACES
54namespace ost {
55using namespace std;
56#endif
57
58Digest::Digest() :
59streambuf()
60#ifdef HAVE_OLD_IOSTREAM
61,ostream()
62#else
63,ostream((streambuf *)this)
64#endif
65{
66#ifdef HAVE_OLD_IOSTREAM
67 init((streambuf *)this);
68#endif
69 }
70
71Digest::~Digest()
72{
73}
74
75ChecksumDigest::ChecksumDigest() :
76Digest()
77{
78 csum = 0;
79}
80
81int ChecksumDigest::overflow(int c)
82{
83 csum += c;
84 return c;
85}
86
87unsigned ChecksumDigest::getDigest(unsigned char *buffer)
88{
89 *buffer = csum;
90 return 1;
91}
92
93void ChecksumDigest::putDigest(const unsigned char *buffer, unsigned len)
94{
95 while(len--)
96 csum += *(buffer++);
97}
98
99ostream &ChecksumDigest::strDigest(ostream &os)
100{
101 char buf[3];
102
103 sprintf(buf, "%02x", csum);
104 os << buf;
105 return os;
106}
107
108CRC16Digest::CRC16Digest() : Digest()
109{
110 crc16 = 0;
111}
112
113CRC16Digest::CRC16Digest (const CRC16Digest &crc ) : Digest()
114{
115 crc16 = crc.crc16;
116}
117
118CRC16Digest& CRC16Digest::operator= ( const CRC16Digest &right )
119{
120 if ( this == &right ) return *this;
121 crc16 = right.crc16;
122 return *this;
123}
124
125int CRC16Digest::overflow ( int c )
126{
127 crc16 = ( unsigned char ) ( crc16 >> 8 ) | ( crc16 << 8 );
128 crc16 ^= ( unsigned char ) ( c );
129 crc16 ^= ( unsigned char ) ( crc16 & 0xff ) >> 4;
130 crc16 ^= ( crc16 << 8 ) << 4;
131 crc16 ^= ( ( crc16 & 0xff ) << 4 ) << 1;
132 return c;
133}
134
135unsigned CRC16Digest::getDigest ( unsigned char *buffer )
136{
137 memcpy ( buffer, &crc16, sizeof(crc16) );
138 return sizeof(crc16);
139}
140
141void CRC16Digest::putDigest ( const unsigned char *buffer, unsigned len )
142{
143 while (len--)
144 overflow (*buffer++);
145}
146
147ostream &CRC16Digest::strDigest ( ostream &os )
148{
149 return os << std::setw(4) << std::setfill('0') << std::hex << (unsigned)crc16 << std::dec;
150}
151
152
153CRC32Digest::CRC32Digest() : Digest()
154{
155 initDigest();
156 crc32 = 0;
157}
158
159CRC32Digest::CRC32Digest(const CRC32Digest &crc) : Digest()
160{
161 crc32 = crc.crc32;
162 crc_reg = crc.crc_reg;
163 register int32 i;
164 for (i = 0; i < 256; i++) {
165 crc_table[i] = crc.crc_table[i];
166 }
167}
168
169void CRC32Digest::initDigest(void)
170{
171 // the generator polynomial used here is the same as Ethernet
172 // x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1
173 const uint32 POLYNOMIAL = 0x04C11DB7;
174
175 // Initialize the accumulator to all ones
176 crc_reg = 0xFFFFFFFF;
177
178 // Initialize the lookup table
179 register int32 i,j;
180 register uint32 crc;
181
182 for (i = 0; i < 256; i++) {
183 crc = ( (uint32) i << 24 );
184 for (j = 0; j < 8; j++) {
185 if (crc & 0x80000000)
186 crc = (crc << 1) ^ POLYNOMIAL;
187 else
188 crc <<= 1;
189 }
190 crc_table[i] = crc;
191 }
192}
193
194
195unsigned char CRC32Digest::overflow(unsigned char octet)
196{
197 crc_reg = crc_table[((crc_reg >> 24) ^ octet) & 0xFF] ^ (crc_reg << 8);
198 crc32 = ~crc_reg;
199
200 return octet;
201}
202
203unsigned CRC32Digest::getDigest(unsigned char *buffer)
204{
205 memcpy(buffer, &crc32, sizeof(crc32));
206 return sizeof(crc32);
207}
208
209void CRC32Digest::putDigest(const unsigned char *buffer, unsigned len)
210{
211 while(len--)
212 overflow(*buffer++);
213}
214
215ostream& CRC32Digest::strDigest(ostream &os)
216{
217 return os << std::setw(8) << std::setfill('0') << std::hex << (unsigned)crc32 << std::dec;
218}
219
220CRC32Digest& CRC32Digest::operator= (const CRC32Digest &right)
221{
222 if ( this == &right ) return *this;
223 crc32 = right.crc32;
224 crc_reg = right.crc_reg;
225
226 register int32 i;
227 for (i = 0; i < 256; i++) {
228 crc_table[i] = right.crc_table[i];
229 }
230
231 return *this;
232}
233
234
235#ifdef CCXX_NAMESPACES
236}
237#endif
238