Files
Test/Library/PackageCache/com.unity.render-pipelines.universal@ffe395a3a1d1/Runtime/2D/URP2D_CRC32.cs
T
2026-11-01 23:39:55 +02:00

87 lines
2.7 KiB
C#

using System;
using System.Text;
using System.Runtime.InteropServices;
namespace UnityEngine.Rendering.Universal
{
internal static class URP2D_Crc32
{
// 8 tables of 256 uints each
private static readonly uint[][] Tables;
static URP2D_Crc32()
{
Tables = new uint[8][];
for (int i = 0; i < 8; i++) Tables[i] = new uint[256];
uint polynomial = 0xEDB88320;
// Fill Table 0
for (uint i = 0; i < 256; i++)
{
uint entry = i;
for (int j = 0; j < 8; j++)
entry = (entry & 1) == 1 ? (entry >> 1) ^ polynomial : (entry >> 1);
Tables[0][i] = entry;
}
// Fill Tables 1 through 7
for (int t = 1; t < 8; t++)
{
for (int i = 0; i < 256; i++)
{
uint prev = Tables[t - 1][i];
Tables[t][i] = (prev >> 8) ^ Tables[0][prev & 0xFF];
}
}
}
public static uint Compute(ReadOnlySpan<byte> data)
{
uint crc = 0xFFFFFFFF;
int i = 0;
int length = data.Length;
// Pull tables into local variables to help the JIT optimize register usage
uint[] t0 = Tables[0];
uint[] t1 = Tables[1];
uint[] t2 = Tables[2];
uint[] t3 = Tables[3];
uint[] t4 = Tables[4];
uint[] t5 = Tables[5];
uint[] t6 = Tables[6];
uint[] t7 = Tables[7];
// Process 8 bytes at a time
while (length - i >= 8)
{
// We use bitwise logic to extract the 4 bytes of the current CRC
// and combine them with the next 4 bytes of data.
uint step1 = data[i] ^ (crc & 0xFF);
uint step2 = data[i + 1] ^ ((crc >> 8) & 0xFF);
uint step3 = data[i + 2] ^ ((crc >> 16) & 0xFF);
uint step4 = data[i + 3] ^ (crc >> 24);
crc = t7[step1] ^ t6[step2] ^ t5[step3] ^ t4[step4] ^
t3[data[i + 4]] ^ t2[data[i + 5]] ^ t1[data[i + 6]] ^ t0[data[i + 7]];
i += 8;
}
// Remaining bytes
while (i < length)
{
crc = (crc >> 8) ^ t0[(crc ^ data[i++]) & 0xFF];
}
return ~crc;
}
public static uint Compute(string input)
{
if (string.IsNullOrEmpty(input)) return 0;
// Use the most efficient way to get bytes without huge allocations
return Compute(Encoding.UTF8.GetBytes(input));
}
}
}