我试图实现基于 LSB 的反转功能。代码在 C# 中。校验和的反转存在错误。该函数只能在仅使用 8 字节原始数据计算时反转 Crc64 校验和。当我尝试通过 FixChecksum 方法反转校验和时,中间 6 个字节被反转,但第一个和最后一个字节被反转损坏。请告知有什么问题,需要实施或修复什么。我将不胜感激任何解决方案。
[更新]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MYC;
using primaryMethodsCS_2;
using System.Globalization;
using UnitsFramework.Numerics;
using UnitsFramework;
namespace MYC
{
public class Crc64_LSB_Reverse
{
public const UInt64 POLY64REV = 0xD800000000000000; //0xffffffffffffff00;
public static ulong TOPBIT_MASK = 0x8000000000000000;
public static ulong LOWBIT_MASK = 0x0000000000000001;
public const ulong startxor = 0; //0xffffffffffffffff;
public const ulong FinalXor = 0; // 0xffffffffffffffff;
public UInt64[] CRCTable;
public UInt64[] revCRCTable;
public UInt64 crc = 0;
public Crc64_LSB_Reverse(UInt64 POLY = POLY64REV)
{
List<ulong> listforward = new List<ulong>();
List<ulong> listreverse = new List<ulong>();
for (int i = 0; i <= 255; i++)
{
List<ulong> forward = generateCrcTableConstants(new List<ulong>() { (UInt64)i }, POLY);
List<ulong> reverse = generateRevCrcTableConstants(new List<ulong>() { (UInt64)i }, POLY);
listforward.AddRange(forward);
listreverse.AddRange(reverse);
}
this.CRCTable = listforward.ToArray();
this.revCRCTable = listreverse.ToArray();
return;
}
public static List<UInt64> generateCrcTableConstants(List<UInt64> initialValues, UInt64 POLY)
{
List<UInt64> list = new List<ulong>();
for (int thisValue = 0; thisValue < initialValues.Count; thisValue++)
{
UInt64 currentValue = initialValues[thisValue];
UInt64 initialValue = currentValue;
currentValue <<= 56; // is valid for MSB forward table creation
// MSB based forward table implementation.
for (byte bit = 0; bit < 8; bit++)
{
if ((currentValue & TOPBIT_MASK) != 0)
{
//currentValue <<= 1;
//currentValue ^= CrcFramework.Reflect64(POLY);
currentValue = (currentValue << 1) ^ ((0 - (currentValue >> 63)) & POLY); // fwd
}
else
{
currentValue <<= 1;
}
}
list.Add(currentValue);
}
return list;
}
public static List<UInt64> generateRevCrcTableConstants(List<UInt64> initialValues, UInt64 POLY)
{
List<UInt64> list = new List<ulong>();
for (int thisValue = 0; thisValue < initialValues.Count; thisValue++)
{
UInt64 initialValue = initialValues[thisValue];
UInt64 currentValue = initialValues[thisValue];
// LSB based reverse table implementation for MSB based forward table function.
for (byte bit = 0; bit < 8; bit++)
{
if ((currentValue & LOWBIT_MASK) != 0)
{
//currentValue ^= POLY; // CrcFramework.Reflect64(POLY); //POLY;
currentValue = (currentValue >> 1) ^ ((0 - (currentValue & 1)) & POLY); // rvs
//currentValue >>= 1;
//currentValue |= 1; // TOPBIT_MASK;
}
else
{
currentValue >>= 1;
}
}
list.Add(currentValue);
}
return list;
}
public ulong Compute_LSB(byte[] bytes, bool reset = true)
{
if (reset) this.crc = startxor;
foreach (byte b in bytes)
{
byte curByte = b;
/* update the LSB of crc value with next input byte */
crc = (ulong)(crc ^ (ulong)(curByte));
/* this byte value is the index into the lookup table */
byte pos = (byte)(crc & 0xFF); // tushar: original 12-September-2019-1: & 0xFF);
/* shift out this index */
crc = (ulong)(crc >> 8);
/* XOR-in remainder from lookup table using the calculated index */
crc = (ulong)(crc ^ (ulong)CRCTable[pos]);
/* shorter:
byte pos = (byte)((crc ^ curByte) & 0xFF);
crc = (ulong)((crc >> 8) ^ (ulong)(crcTable[pos]));
*/
}
return (ulong)(crc ^ FinalXor);
}
public ulong Compute_MSB(byte[] bytes, bool reset = true)
{
if (reset) this.crc = startxor;
foreach (byte b in bytes)
{
byte curByte = b;
/* update the MSB of crc value with next input byte */
crc = (ulong)(crc ^ (ulong)((ulong)curByte << 56));
/* this MSB byte value is the index into the lookup table */
byte pos = (byte)(crc >> 56);
/* shift out this index */
crc = (ulong)(crc << 8);
/* XOR-in remainder from lookup table using the calculated index */
crc = (ulong)(crc ^ (ulong)CRCTable[pos]);
/* shorter:
byte pos = (byte)((crc ^ (curByte << 56)) >> 56);
crc = (uint)((crc << 8) ^ (ulong)(crcTable[pos]));
*/
}
return (ulong)(crc ^ FinalXor);
}
public UInt64 FixChecksum(byte[] bytes, Int64 length, Int64 fixpos, UInt64 wantcrc)
{
if (fixpos + 8 > length) return 0;
UInt64 crc = startxor;
for (Int64 i = 0; i < fixpos; i++)
{
crc = (crc >> 8) ^ CRCTable[(crc ^ bytes[i]) & 0xff];
}
Array.Copy(BitConverter.GetBytes(crc), 0, bytes, fixpos, 8);
List<UInt64> list = new List<UInt64>();
crc = wantcrc ^ startxor;
for (Int64 i = length - 1; i >= fixpos; i--)
{
UInt64 param0 = (UInt64)(crc >> 56);
list.Add(param0);
crc = (crc << 8) ^ revCRCTable[param0] ^ bytes[i]; //
}
Array.Copy(BitConverter.GetBytes(crc), 0, bytes, fixpos, 8);
return crc;
}
}
}