You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:将C# CRC32计算代码转为Kotlin时遇数组越界问题

将C# CRC32计算代码转换为Kotlin的问题

原C#代码如下:

public static UInt32 CalculdateCrc32(byte[] bytes, int length)
{
    UInt32 Checksum = 0xFFFFFFFF;
    for (int i = 0; i < length; i++)
    {
        byte top = (byte)(Checksum >> 24);
        top ^= bytes[i];
        Checksum = (Checksum << 8) ^ crc_table[top];
    }
    return Checksum;
}

这段代码用于计算字节数组bytes前length个字节的CRC32校验值。我尝试了多种处理无符号数据类型的方法,但始终无法得到正确的CRC结果。


最接近正确的尝试

生成CRC表

private val crcTable = (0 until 256).map {
    crc32(it.toUByte(), 0x04C11DB7.toUInt())
}

private fun crc32(input: UByte, polynomial: UInt): UInt {
    val bigEndianInput = input.toBigEndianUInt()

    return (0 until 8).fold(bigEndianInput) { result, _ ->
        val isMostSignificantBitOne = result and 0x80000000.toUInt() != 0.toUInt()
        val shiftedResult = result shl 1

        when (isMostSignificantBitOne) {
            true -> shiftedResult xor polynomial
            false -> shiftedResult
        }
    }
}

private fun UByte.toBigEndianUInt(): UInt = this.toUInt() shl 24

转换后的Kotlin CRC计算方法

private fun calculateCrc32(bytes: ByteArray, length: Int): UInt {
    var checksum : UInt = 0xFFFFFFFFu
    for (i in 0 until length) {
        var top = (checksum shr 24).toByte()
        top = top xor bytes[i]
        checksum = checksum shl 8 xor crcTable[top.toInt()]
    }
    return checksum
}

这段代码会抛出IndexOutOfBoundsException,原因是top最终变为-1。

单元测试

class CrcUtilTest {

    @Test
    fun crc16_correctByteArray_returnsCorrectCrc16() {

        val data = byteArrayOf(
            0xaa.toByte(),
            0xbb.toByte(),
            0xcc.toByte(),
            0xdd.toByte(),

            0xaa.toByte(),
            0xbb.toByte(),
            0xcc.toByte(),
            0xdd.toByte(),

            0xaa.toByte(),
            0xbb.toByte(),
            0xcc.toByte(),
            0xdd.toByte(),

            0xaa.toByte(),

            0xaa.toByte(),
            0xbb.toByte()
        )

        CrcUtil.updateCrc16(data)

        assertThat(data[13]).isEqualTo(0xaa)
        assertThat(data[14]).isEqualTo(0xbb)

    }

}

内容的提问来源于stack exchange,提问作者muetzenflo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 10:20:43