package com.example.vastlib.utils

import kotlin.math.pow

class Encryptor(
    val key: String
) {
    sealed class Encryptable(val type: Int) {
        object Encrypt : Encryptable(1)
        object Decrypt : Encryptable(-1)
    }
}

fun Byte.encryption(key: Byte, method: Encryptor.Encryptable): Byte {
    // key的预处理，处理结果0<=key&&key<8
    val msg = this
    var key = key
    key = (method.type * (key % 8)).toByte()
    key = (if (key >= 0) key else key + 8).toByte()

    // msg的预处理，避免msg首位为1
    var nMsg = msg.toInt() and 255
    // 移位掩码，tmp保存低位溢出信息
    val mask = 2.0.pow(key.toDouble()).toInt() - 1
    var tmp = nMsg and mask

    // 循环移位
    nMsg = nMsg shr key.toInt()
    tmp = tmp shl 8 - key // 低位溢出信息移至高位
    nMsg = nMsg or tmp
    return (255 and nMsg).toByte() // 取出低8位
}

private fun ByteArray.encryption(key: ByteArray, method: Encryptor.Encryptable): ByteArray {
    val result = ByteArray(this.size)
    this.forEachIndexed { index, byte ->
        result[index] = byte.encryption(key[index % key.size], method)
    }
    return result
}

fun ByteArray.encrypt(key: String): ByteArray =
    this.encryption(key.toByteArray(), Encryptor.Encryptable.Encrypt)

fun ByteArray.decrypt(key: String): ByteArray =
    this.encryption(key.toByteArray(), Encryptor.Encryptable.Decrypt)


fun String.encryptToByteArray(key: String): ByteArray =
    this.toByteArray().encrypt(key)


fun ByteArray.decryptToString(key: String): String =
    String(this.decrypt(key))