我正在尝试将 C# 中的 CRC32 生成器的特定实现转换为用于静态网站的 JavaScript。
它将两个字符串合并为一个,将其转换为一个,生成一个 CRC 并将其转换为十六进制输出。
问题是,JavaScript 版本 (CF2F4221) 的输出与 C# 版本 (67CDF980) 不匹配。
C#代码:
using System;
using System.Text;
namespace CRC32.Generator
{
internal class CRC
{
public static readonly uint[] Table;
private uint _value = 0xFFFFFFFF;
static CRC()
{
Table = new uint[256];
const uint kPoly = 0xEDB88320;
for (uint i = 0; i < 256; i++)
{
uint r = i;
for (int j = 0; j < 8; j++)
if ((r & 1) != 0)
r = (r >> 1) ^ kPoly;
else
r >>= 1;
Table[i] = r;
}
}
public void Init()
{
_value = 0xFFFFFFFF;
}
public void UpdateByte(byte b)
{
_value = Table[(((byte) (_value)) ^ b)] ^ (_value >> 8);
}
public void Update(byte[] data, uint offset, uint size)
{
for (uint i = 0; i < size; i++)
_value = Table[(((byte) (_value)) ^ data[offset + i])] ^ (_value >> 8);
}
public uint GetDigest()
{
return _value ^ 0xFFFFFFFF;
}
}
class Program
{
static void Main(string[] args)
{
string string1 = "TestString1";
string string2 = "TestString2";
string stringData = string1 + string2;
byte[] data = Encoding.Unicode.GetBytes(stringData);
CRC crc = new CRC();
crc.Update(data, 0, (uint)data.Length);
uint crc32Value = crc.GetDigest();
byte[] bytes = BitConverter.GetBytes(crc32Value);
Array.Reverse(bytes);
uint reversedCrc32Value = BitConverter.ToUInt32(bytes, 0);
Console.WriteLine(reversedCrc32Value.ToString("X"));
}
}
}
JavaScript 代码:
// CRC32 Table
const crc32Table = new Array(256);
for (let i = 0; i < 256; i++) {
let crc = i;
for (let j = 0; j < 8; j++) {
crc = (crc & 1) ? (crc >>> 1) ^ 0xEDB88320 : crc >>> 1;
}
crc32Table[i] = crc;
}
// CRC32 Function
function crc32(data) {
let crc = 0xFFFFFFFF;
for (let i = 0; i < data.length; i++) {
crc = (crc >>> 8) ^ crc32Table[(crc ^ data[i]) & 0xFF];
}
return (crc ^ 0xFFFFFFFF) >>> 0; // Unsigned right shift
}
// Generate CRC
function generateCRC() {
let string1 = document.getElementById('string1').value;
let string2 = document.getElementById('string2').value;
let stringData = string1 + string2;
// Convert the string to a UTF-16LE byte array
let encoder = new TextEncoder('utf-16le');
let data = encoder.encode(stringData);
let crc32Value = crc32(new Uint8Array(data.buffer));
document.getElementById('output').textContent = crc32Value.toString(16).toUpperCase(); // Convert to hexadecimal
}
根据我所做的研究,我了解到 C# 和 JavaScript 输出之间的差异可能是由于这两种语言处理按位运算、字节顺序以及可能的字符编码方式的差异所致。
我希望对这些事情有更多了解的人可以为我指明正确的方向,因为不可否认,这超出了我的理解范围。
C# 代码在字符串的小端 UTF-16 表示形式上计算 CRC-32,字符串是字符串中的 ASCII 字节,每个字节后跟一个零字节,总共 44 个字节。该 CRC 是
0x80f9cd67
。 C# 代码反转这些字节以显示结果 0x67CDF980
。
JavaScript 代码直接在 22 个 ASCII 字节上计算 CRC-32,结果为
0xcf2f4221
(不是字节反转)。