Kotlin实现TEA算法


Kotlin具有实验性的无符号整数,所以实现TEA算法比较简单,对照C语言版翻译一下即可

typealias u32 = UInt //Java不支持无符号数据类型但Kotlin支持
typealias u64 = ULong

object TEA32 {
    private const val ROUND = 32U
    private const val DELTA = 0x9E3779B9U

    @OptIn(ExperimentalUnsignedTypes::class)
    fun rawEncrypt(msg :UIntArray, key :UByteArray) : UIntArray {
        val (a,b,c,d) = key //获取四个常数

        var (x,y) = msg // 将msg分为两个32位量
        var sum = 0U

        // 迭代x,y
        for (i in ROUND downTo 1U) {
            sum += DELTA
            x += (y shl 4) + a xor y + sum xor (y shr 5) + b
            y += (x shl 4) + c xor x + sum xor (x shr 5) + d
        }

        return uintArrayOf(x,y)
    }

    @OptIn(ExperimentalUnsignedTypes::class)
    fun rawDecrypt(msg :UIntArray, key :UByteArray) : UIntArray {
        val (a,b,c,d) = key

        var (x,y) = msg
        var sum :UInt = DELTA * ROUND

        for (i in ROUND downTo 1U) {
            y -= (x shl 4) + c xor x + sum xor (x shr 5) + d
            x -= (y shl 4) + a xor y + sum xor (y shr 5) + b
            sum -= DELTA
        }

        return uintArrayOf(x,y)
    }

}

//测试
@OptIn(ExperimentalUnsignedTypes::class)
fun main() {
    val msg = uintArrayOf(1708U,8102U)
    val key = ubyteArrayOf(0x33U, 0x45U, 0x77U, 0x20U)

    println("msg = ${msg[0]},${msg[1]}")

    var sec = TEA32.rawEncrypt(msg, key)
    println("sec = ${sec[0]},${sec[1]}")

    var msg1 = TEA32.rawDecrypt(sec, key)
    println("msg1 = ${msg1[0]},${msg1[1]}")
}