Java 如何在Android上正确使用CRC32
我使用java.util.zip.CRC32来计算CRC32。 我发现了奇怪的特征;我的应用程序与通过字符数组计算CRC32的设备连接,请参阅简单测试:Java 如何在Android上正确使用CRC32,java,android,crc32,Java,Android,Crc32,我使用java.util.zip.CRC32来计算CRC32。 我发现了奇怪的特征;我的应用程序与通过字符数组计算CRC32的设备连接,请参阅简单测试: val i: Int = 123456789 val crc32 = CRC32Any() crc32.reset() crc32.update(i) Timber.i ("CRC32 by int '$i': ${crc32.value}") crc32.reset()
val i: Int = 123456789
val crc32 = CRC32Any()
crc32.reset()
crc32.update(i)
Timber.i ("CRC32 by int '$i': ${crc32.value}")
crc32.reset()
var arr = ByteBuffer.allocate(Int.SIZE_BYTES)
.putInt(i)
.array()
crc32.update(arr)
Timber.i ("CRC32 by array '${arr.toHexString()}': ${crc32.value}")
crc32.reset()
arr.reverse()
crc32.update(arr)
Timber.i ("CRC32 by reverse arr '${arr.toHexString()}': ${crc32.value}")
因此:
CRC32 by int '123456789': 3219065702
CRC32 by array '075BCD15': 3488836380
CRC32 by reverse arr '15CD5B07': 417295518
所有CRC32都不匹配!
如何使用java.util.zip.CRC32计算正确的CRC32以正确使用?解决方案:
@ExperimentalUnsignedTypes
fun toByteArray(any: Any?): ByteArray =
when(any){
is ByteArray -> any
is ByteBuffer -> (any as ByteBuffer).array()
is String -> (any as String).toByteArray()
is Char ->
ByteBuffer.allocate(Char.SIZE_BYTES)
.putChar(any as Char)
.array()
is Byte ->
ByteBuffer.allocate(Byte.SIZE_BYTES)
.put(any)
.array()
is UByte ->
ByteBuffer.allocate(UShort.SIZE_BYTES)
.putShort((any as UByte).toShort())
.array()
.also { it.reverse() }
.copyOfRange(0, UByte.SIZE_BYTES)
is Int ->
ByteBuffer.allocate(Int.SIZE_BYTES)
.putInt(any as Int)
.array()
.also { it.reverse() }
is UInt ->
ByteBuffer.allocate(Long.SIZE_BYTES)
.putLong((any as UInt).toLong())
.array()
.also { it.reverse() }
.copyOfRange(0, UInt.SIZE_BYTES)
is Long ->
ByteBuffer.allocate(Long.SIZE_BYTES)
.putLong(any as Long)
.array()
.also { it.reverse() }
//is ULong -> // not supported now
else ->
ByteArray(0)
}
class CRC32Any: CRC32() {
@Throws(IOException::class)
fun updateAny(any: Any?) {
if (any != null)
when (any) {
is File -> updateFromFile(any)
else -> super.update(toByteArray(any))
}
}
@Throws(IOException::class)
private fun updateFromFile(file: File) {
if (!(file?.exists()))
throw Exception("Source file not found!")
val inFile = FileInputStream(file)
val buf = ByteBuffer.allocate(2048)
var size: Int = 0
while (inFile.channel.read(buf).also { size = it } !== -1) {
buf.flip()
super.update(buf.array(), 0, size)
buf.clear()
}
inFile.close()
}
}