blob: 1b832e11e433ab9c3ac76753a05cf8a09f2b4550 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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
*
* https://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.
*/
using System;
namespace Avro.File.Snappy
{
/// <summary>
/// Implements a 32-bit CRC hash algorithm.
/// </summary>
internal static class Crc32
{
private const uint DefaultPolynomial = 0xedb88320u;
private const uint DefaultSeed = 0xffffffffu;
private static uint[] defaultTable;
public static uint Compute(byte[] buffer)
{
return Compute(DefaultPolynomial, DefaultSeed, buffer);
}
public static uint Compute(uint polynomial, uint seed, ReadOnlySpan<byte> buffer)
{
return ~CalculateHash(InitializeTable(polynomial), seed, buffer);
}
private static uint[] InitializeTable(uint polynomial)
{
if (polynomial == DefaultPolynomial && defaultTable != null)
return defaultTable;
uint[] createTable = new uint[256];
for (int i = 0; i < 256; i++)
{
uint entry = (uint)i;
for (int j = 0; j < 8; j++)
if ((entry & 1) == 1)
entry = (entry >> 1) ^ polynomial;
else
entry >>= 1;
createTable[i] = entry;
}
if (polynomial == DefaultPolynomial)
defaultTable = createTable;
return createTable;
}
private static uint CalculateHash(uint[] table, uint seed, ReadOnlySpan<byte> buffer)
{
uint hash = seed;
for (int i = 0; i < buffer.Length; i++)
hash = (hash >> 8) ^ table[buffer[i] ^ hash & 0xff];
return hash;
}
}
}