My favorites | Sign in
Project Home Downloads Issues Source
Repository:
Checkout   Browse   Changes   Clones    
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#region Copyright 2011 by Roger Knapp, Licensed under the Apache License, Version 2.0
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#endregion
using System;

namespace CSharpTest.Net.IO
{
/// <summary> Provides a simple CRC32 checksum for a set of bytes </summary>
[System.Diagnostics.DebuggerDisplay("{Value:X8}")]
public struct Crc32 : IEquatable<Crc32>, IEquatable<int>
{
static readonly int[] Table;
static Crc32()
{
Table = new int[256];
for (uint i = 0; i < 256; i++)
{
uint crc = i;
for (uint j = 0; j < 8; j++)
crc = (crc >> 1) ^ (((crc & 1) == 1) ? 0xEDB88320u : 0);
//Note: table ordinal and value inverted to omit -1 start and end operation
Table[~i & 0x0ff] = ~unchecked((int)crc);
}
}

int _crc32;

/// <summary> Resumes the computation of a CRC32 value </summary>
public Crc32(int crc)
{ _crc32 = crc; }

/// <summary> Initailizes the Crc32 value to the checksum of the string as a series of 16-bit values </summary>
public Crc32(string text)
{ _crc32 = 0; Add(text); }

/// <summary> Initailizes the Crc32 value to the checksum of the bytes provided </summary>
public Crc32(byte[] bytes)
{ _crc32 = 0; Add(bytes, 0, bytes.Length); }

/// <summary> Returns the computed CRC32 value as a Hex string </summary>
public override string ToString() { return String.Format("{0:X8}", Value); }

/// <summary> Returns the computed CRC32 value </summary>
public int Value { get { return _crc32; } }

/// <summary> Adds a byte to the checksum </summary>
public void Add(byte b)
{
_crc32 = (((~_crc32 >> 8) & 0x00FFFFFF) ^ Table[(_crc32 ^ b) & 0x0ff]);
}

/// <summary> Adds a byte to the checksum </summary>
public static Crc32 operator +(Crc32 chksum, byte b)
{
chksum.Add(b);
return chksum;
}

/// <summary> Adds an entire array of bytes to the checksum </summary>
public void Add(byte[] bytes)
{ Add(bytes, 0, Check.NotNull(bytes).Length); }

/// <summary> Adds a range from an array of bytes to the checksum </summary>
public void Add(byte[] bytes, int start, int length)
{
Check.NotNull(bytes);
int end = start + length;

for (int i = start; i < end; i++)
_crc32 = (((~_crc32 >> 8) & 0x00FFFFFF) ^ Table[(_crc32 ^ bytes[i]) & 0x0ff]);

}

/// <summary> Adds an entire array of bytes to the checksum </summary>
public static Crc32 operator +(Crc32 chksum, byte[] bytes)
{
chksum.Add(bytes, 0, bytes.Length);
return chksum;
}

/// <summary> Adds a string to the checksum as a series of 16-bit values (big endian) </summary>
public void Add(string text)
{
foreach (char ch in Check.NotNull(text))
{
_crc32 = (((~_crc32 >> 8) & 0x00FFFFFF) ^ Table[(_crc32 ^ ((byte)ch >> 8)) & 0x0ff]);
_crc32 = (((~_crc32 >> 8) & 0x00FFFFFF) ^ Table[(_crc32 ^ ((byte)ch)) & 0x0ff]);
}
}

/// <summary> Adds a string to the checksum as a series of 16-bit values </summary>
public static Crc32 operator +(Crc32 chksum, string text)
{
chksum.Add(text);
return chksum;
}

/// <summary> Extracts the correct hash code </summary>
public override int GetHashCode() { return Value; }

/// <summary> Returns true if the other object is equal to this one </summary>
public override bool Equals(object obj)
{
return
(obj is Crc32 && _crc32 == ((Crc32)obj)._crc32) ||
(obj is int && Value == ((int)obj));
}

/// <summary> Returns true if the other object is equal to this one </summary>
public bool Equals(Crc32 other) { return _crc32 == other._crc32; }
/// <summary> Returns true if the CRC32 provided is equal to this one </summary>
public bool Equals(int crc32) { return Value == crc32; }

/// <summary> Compares the two objects for equality </summary>
public static bool operator ==(Crc32 x, Crc32 y) { return x._crc32 == y._crc32; }
/// <summary> Compares the two objects for equality </summary>
public static bool operator !=(Crc32 x, Crc32 y) { return x._crc32 != y._crc32; }

/// <summary> Compares the two objects for equality </summary>
public static bool operator ==(Crc32 x, int y) { return x.Value == y; }
/// <summary> Compares the two objects for equality </summary>
public static bool operator !=(Crc32 x, int y) { return x.Value != y; }

}
}

Change log

59104bd26e63 by rogerk on Apr 26, 2011   Diff
Release version 1.11.426.305
Go to: 
Project members, sign in to write a code review

Older revisions

All revisions of this file

File info

Size: 5602 bytes, 136 lines
Powered by Google Project Hosting