在 JavaScript 中复制 C# CRC32 生成器

问题描述 投票:0回答:1

我正在尝试将 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 输出之间的差异可能是由于这两种语言处理按位运算、字节顺序以及可能的字符编码方式的差异所致。

我希望对这些事情有更多了解的人可以为我指明正确的方向,因为不可否认,这超出了我的理解范围。

javascript c# crc32
1个回答
0
投票

C# 代码在字符串的小端 UTF-16 表示形式上计算 CRC-32,字符串是字符串中的 ASCII 字节,每个字节后跟一个零字节,总共 44 个字节。该 CRC 是

0x80f9cd67
。 C# 代码反转这些字节以显示结果
0x67CDF980

JavaScript 代码直接在 22 个 ASCII 字节上计算 CRC-32,结果为

0xcf2f4221
(不是字节反转)。

© www.soinside.com 2019 - 2024. All rights reserved.