まえがき
標準では用意されていなさそうだったので、Wikipediaに載っているCのソースコードをもとにC#に移植してみた。
※32bitのCRCは1種類ではないので注意。
通常、「CRC-32」とだけ書いた場合は、生成多項式として
$$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$$
を使うものを指すよう。
ソースコード上にでてくる0xEDB88320
は、生成多項式を16進数表記にした0x04C11DB7
のビット順序を反転させたものになっている。
ソースコード
Crc32.cs
using System;
public static class Crc32
{
static uint[] crcTable = MakeCrcTable();
static uint[] MakeCrcTable()
{
uint[] a = new uint[256];
for (uint i = 0; i < a.Length; i++) {
uint c = i;
for (int j = 0; j < 8; j++) {
c = ((c&1)!=0) ? (0xEDB88320 ^ (c >> 1)) : (c >> 1);
}
a[i] = c;
}
return a;
}
public static uint Calculate(byte[] buf)
{
return Calculate(buf, 0, buf.Length);
}
public static uint Calculate(byte[] buf, int start, int len)
{
uint c = 0xFFFFFFFF;
checked{
if (len<0) {
throw new ArgumentException();
}
if (start<0 || start+len>buf.Length){
throw new IndexOutOfRangeException();
}
}
for (int i=0; i<len; i++) {
c = crcTable[(c ^ buf[start+i]) & 0xFF] ^ (c >> 8);
}
return c ^ 0xFFFFFFFF;
}
}
class CrcSample
{
[STAThread]
static void Main(string[] args)
{
byte[] t = new System.Text.ASCIIEncoding().GetBytes("123456789");
uint crcResult = Crc32.Calculate(t);
Console.WriteLine("0x" + crcResult.ToString("X08"));
}
}