求助:将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
相关产品推荐
相关产品推荐

