/commoncpp2-1.8.1/src/digest.cpp

# · C++ · 238 lines · 159 code · 38 blank · 41 comment · 12 complexity · ab494353eb706b19a3f5b3e9b24d4038 MD5 · raw file

  1. // 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. #include <cc++/config.h>
  39. #include <cc++/string.h>
  40. #include <cc++/exception.h>
  41. #include <cc++/thread.h>
  42. #include <cc++/export.h>
  43. #include <cc++/digest.h>
  44. #include <cstdio>
  45. #include <iomanip>
  46. #ifdef WIN32
  47. #include <io.h>
  48. #endif
  49. #ifdef CCXX_NAMESPACES
  50. namespace ost {
  51. using namespace std;
  52. #endif
  53. Digest::Digest() :
  54. streambuf()
  55. #ifdef HAVE_OLD_IOSTREAM
  56. ,ostream()
  57. #else
  58. ,ostream((streambuf *)this)
  59. #endif
  60. {
  61. #ifdef HAVE_OLD_IOSTREAM
  62. init((streambuf *)this);
  63. #endif
  64. }
  65. Digest::~Digest()
  66. {
  67. }
  68. ChecksumDigest::ChecksumDigest() :
  69. Digest()
  70. {
  71. csum = 0;
  72. }
  73. int ChecksumDigest::overflow(int c)
  74. {
  75. csum += c;
  76. return c;
  77. }
  78. unsigned ChecksumDigest::getDigest(unsigned char *buffer)
  79. {
  80. *buffer = csum;
  81. return 1;
  82. }
  83. void ChecksumDigest::putDigest(const unsigned char *buffer, unsigned len)
  84. {
  85. while(len--)
  86. csum += *(buffer++);
  87. }
  88. ostream &ChecksumDigest::strDigest(ostream &os)
  89. {
  90. char buf[3];
  91. sprintf(buf, "%02x", csum);
  92. os << buf;
  93. return os;
  94. }
  95. CRC16Digest::CRC16Digest() : Digest()
  96. {
  97. crc16 = 0;
  98. }
  99. CRC16Digest::CRC16Digest (const CRC16Digest &crc ) : Digest()
  100. {
  101. crc16 = crc.crc16;
  102. }
  103. CRC16Digest& CRC16Digest::operator= ( const CRC16Digest &right )
  104. {
  105. if ( this == &right ) return *this;
  106. crc16 = right.crc16;
  107. return *this;
  108. }
  109. int CRC16Digest::overflow ( int c )
  110. {
  111. crc16 = ( unsigned char ) ( crc16 >> 8 ) | ( crc16 << 8 );
  112. crc16 ^= ( unsigned char ) ( c );
  113. crc16 ^= ( unsigned char ) ( crc16 & 0xff ) >> 4;
  114. crc16 ^= ( crc16 << 8 ) << 4;
  115. crc16 ^= ( ( crc16 & 0xff ) << 4 ) << 1;
  116. return c;
  117. }
  118. unsigned CRC16Digest::getDigest ( unsigned char *buffer )
  119. {
  120. memcpy ( buffer, &crc16, sizeof(crc16) );
  121. return sizeof(crc16);
  122. }
  123. void CRC16Digest::putDigest ( const unsigned char *buffer, unsigned len )
  124. {
  125. while (len--)
  126. overflow (*buffer++);
  127. }
  128. ostream &CRC16Digest::strDigest ( ostream &os )
  129. {
  130. return os << std::setw(4) << std::setfill('0') << std::hex << (unsigned)crc16 << std::dec;
  131. }
  132. CRC32Digest::CRC32Digest() : Digest()
  133. {
  134. initDigest();
  135. crc32 = 0;
  136. }
  137. CRC32Digest::CRC32Digest(const CRC32Digest &crc) : Digest()
  138. {
  139. crc32 = crc.crc32;
  140. crc_reg = crc.crc_reg;
  141. register int32 i;
  142. for (i = 0; i < 256; i++) {
  143. crc_table[i] = crc.crc_table[i];
  144. }
  145. }
  146. void CRC32Digest::initDigest(void)
  147. {
  148. // the generator polynomial used here is the same as Ethernet
  149. // 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
  150. const uint32 POLYNOMIAL = 0x04C11DB7;
  151. // Initialize the accumulator to all ones
  152. crc_reg = 0xFFFFFFFF;
  153. // Initialize the lookup table
  154. register int32 i,j;
  155. register uint32 crc;
  156. for (i = 0; i < 256; i++) {
  157. crc = ( (uint32) i << 24 );
  158. for (j = 0; j < 8; j++) {
  159. if (crc & 0x80000000)
  160. crc = (crc << 1) ^ POLYNOMIAL;
  161. else
  162. crc <<= 1;
  163. }
  164. crc_table[i] = crc;
  165. }
  166. }
  167. unsigned char CRC32Digest::overflow(unsigned char octet)
  168. {
  169. crc_reg = crc_table[((crc_reg >> 24) ^ octet) & 0xFF] ^ (crc_reg << 8);
  170. crc32 = ~crc_reg;
  171. return octet;
  172. }
  173. unsigned CRC32Digest::getDigest(unsigned char *buffer)
  174. {
  175. memcpy(buffer, &crc32, sizeof(crc32));
  176. return sizeof(crc32);
  177. }
  178. void CRC32Digest::putDigest(const unsigned char *buffer, unsigned len)
  179. {
  180. while(len--)
  181. overflow(*buffer++);
  182. }
  183. ostream& CRC32Digest::strDigest(ostream &os)
  184. {
  185. return os << std::setw(8) << std::setfill('0') << std::hex << (unsigned)crc32 << std::dec;
  186. }
  187. CRC32Digest& CRC32Digest::operator= (const CRC32Digest &right)
  188. {
  189. if ( this == &right ) return *this;
  190. crc32 = right.crc32;
  191. crc_reg = right.crc_reg;
  192. register int32 i;
  193. for (i = 0; i < 256; i++) {
  194. crc_table[i] = right.crc_table[i];
  195. }
  196. return *this;
  197. }
  198. #ifdef CCXX_NAMESPACES
  199. }
  200. #endif