vul_checksum.h
Go to the documentation of this file.
1 // This is core/vul/vul_checksum.h
2 #ifndef vul_checksum_h_
3 #define vul_checksum_h_
4 
5 
6 //:
7 // \file
8 // \brief Contains function for calculating checksum
9 // \author Ian Scott, Imorphics.
10 
11 
12 #include <vxl_config.h>
13 
14 
15 
16 
17 
18 //: Caluclate the recommended CRC32C checksum.
19 // As used by iSCSI, Btrfs, ext4.
20 // \param begin,end The sequence of chars to be checksummed.
21 // \note that this checksum is not cryptographically secure - it is easy to find
22 // collisions with the original data.
23 template <class IT> vxl_uint_32 vul_checksum_crc32c(IT begin, IT end);
24 
25 //: Caluclate the popular CRC32 checksum as used by SATA, MPEG-2, PKZIP, Gzip, Bzip2.
26 // \param begin,end The sequence of chars to be checksummed.
27 // \note that this checksum is not cryptographically secure - it is easy to find
28 // collisions with the original data.
29 template <class IT> vxl_uint_32 vul_checksum_crc32(IT begin, IT end);
30 
31 
32 
33 
34 // Copied from "Fast CRC32 in Software" R Black, 1994, http://www.cl.cam.ac.uk/research/srg/bluebook/21/crc/node6.html
35 // Software original is copyright (c) 1993 Richard Black. All rights are reserved. You may use this code only if it includes a statement to that effect.
36 // Heavily modified to handle byte swapping and bit reversing issues, and implement CRC32C
37 
38 namespace
39 {
40  inline vxl_uint_32 byte_swap (vxl_uint_32 val)
41  {
42  val = ((val << 8) & 0xFF00FF00 ) | ((val >> 8) & 0xFF00FF );
43  return (val << 16) | (val >> 16);
44  }
45 
46 
47  #if VXL_LITTLE_ENDIAN
48  //! Byte swap unsigned int
49  inline vxl_uint_32 to_bigendian( vxl_uint_32 val )
50  {
51  return byte_swap (val);
52  }
53 
54  #else
55  inline vxl_uint_32 to_bigendian( vxl_uint_32 val )
56  {
57  return val;
58  }
59 
60  #endif
61 
62  //: reverse this (8-bit) byte
63  // From http://graphics.stanford.edu/~seander/bithacks.html
64  inline char bit_reverse(char b)
65  {
66  return (char)((((unsigned char)(b) * 0x0202020202ULL) & 0x010884422010ULL) % 1023);
67  }
68 
69 
70 
71 // There is a faster implementation in the above reference but I don't have time to fix the endian issues.
72 template <class IT> vxl_uint_32 vul_checksum_crc32x(IT p, IT end, vxl_uint_32 quotient)
73 {
74  vxl_uint_32 result=-1;
75  unsigned char octet;
76 
77 
78  // The running result of the polymnomial long division is result*x^(current_bit_position-32) xor remaining_message
79  while (p!=end)
80  {
81  octet = bit_reverse(*(p++));
82  for (unsigned j=0; j<8; j++)
83  {
84  if ((octet >> 7) ^ (result >> 31)) // xor not power
85  result = (result << 1) ^ quotient;
86  else
87  result = (result << 1);
88  octet <<= 1;
89  }
90  }
91  // After we have finished, result contains the remainer.
92  result = ~result; //The complement of the remainder
93 
94  char* result_carray = reinterpret_cast<char*>(&result);
95  result_carray[0] = bit_reverse(result_carray[0]);
96  result_carray[1] = bit_reverse(result_carray[1]);
97  result_carray[2] = bit_reverse(result_carray[2]);
98  result_carray[3] = bit_reverse(result_carray[3]);
99 
100  return result;
101 }
102 
103 
104 }
105 
106 
107 template <class IT> vxl_uint_32 vul_checksum_crc32c(IT begin, IT end)
108 {
109  return vul_checksum_crc32x(begin, end, 0x1EDC6F41);
110 }
111 
112 
113 template <class IT> vxl_uint_32 vul_checksum_crc32(IT begin, IT end)
114 {
115  return vul_checksum_crc32x(begin, end, 0x04c11db7);
116 }
117 #endif // vul_checksum_h_
vxl_uint_32 vul_checksum_crc32(IT begin, IT end)
Caluclate the popular CRC32 checksum as used by SATA, MPEG-2, PKZIP, Gzip, Bzip2.
Definition: vul_checksum.h:113
vxl_uint_32 vul_checksum_crc32c(IT begin, IT end)
Caluclate the recommended CRC32C checksum.
Definition: vul_checksum.h:107