diff --git a/src/en/animekai/src/eu/kanade/tachiyomi/animeextension/en/animekai/AnimekaiDecoder.kt b/src/en/animekai/src/eu/kanade/tachiyomi/animeextension/en/animekai/AnimekaiDecoder.kt index 2b5f4749..9532a270 100644 --- a/src/en/animekai/src/eu/kanade/tachiyomi/animeextension/en/animekai/AnimekaiDecoder.kt +++ b/src/en/animekai/src/eu/kanade/tachiyomi/animeextension/en/animekai/AnimekaiDecoder.kt @@ -3,44 +3,50 @@ package eu.kanade.tachiyomi.animeextension.en.animekai import android.util.Base64 import java.net.URLEncoder import java.nio.charset.StandardCharsets -import java.security.MessageDigest import javax.crypto.Cipher import javax.crypto.spec.IvParameterSpec import javax.crypto.spec.SecretKeySpec class AnimekaiDecoder { - companion object { - private const val secret = "T3xKHVZBiNwbzVBDLTlaTw==" - private const val iv = "3rR5dURR27mN" - - private fun md5(text: String): ByteArray { - val md = MessageDigest.getInstance("MD5") - return md.digest(text.toByteArray()) - } - - private fun decodeBase64(data: String): ByteArray { - return Base64.decode(data, Base64.NO_WRAP) - } - - private fun encodeBase64(data: ByteArray): String { - return Base64.encodeToString(data, Base64.NO_WRAP) - } - } fun generateToken(id: String): String { - val time = (System.currentTimeMillis() / 1000).toString() - val base = "$id|$time" + val timestamp = (System.currentTimeMillis() / 1000).toString() + val base = "$id|$timestamp" val encrypted = encrypt(base) - return URLEncoder.encode(encrypted, "UTF-8") + return URLEncoder.encode(encrypted, StandardCharsets.UTF_8.toString()) } fun decodeIframeData(data: String): String { return decrypt(data) } + fun decode(base64Data: String, steps: List>): String { + var result = base64Data + for (step in steps) { + when (step[0]) { + "replace" -> { + result = result.replace(step[1], step[2]) + } + "reverse" -> { + result = result.reversed() + } + "base64" -> { + result = decodeBase64(result).toString(StandardCharsets.UTF_8) + } + "xor" -> { + val key = step[1].toByteArray(StandardCharsets.UTF_8) + val bytes = decodeBase64(result) + val xored = bytes.mapIndexed { i, b -> b xor key[i % key.size] }.toByteArray() + result = xored.toString(StandardCharsets.UTF_8) + } + } + } + return result + } + private fun encrypt(text: String): String { - val keyBytes = decodeBase64(secret) - val ivSpec = IvParameterSpec(iv.toByteArray(StandardCharsets.UTF_8)) + val keyBytes = decodeBase64(SECRET) + val ivSpec = IvParameterSpec(IV.toByteArray(StandardCharsets.UTF_8)) val keySpec = SecretKeySpec(keyBytes, "AES") val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding") @@ -51,8 +57,8 @@ class AnimekaiDecoder { } private fun decrypt(base64Data: String): String { - val keyBytes = decodeBase64(secret) - val ivSpec = IvParameterSpec(iv.toByteArray(StandardCharsets.UTF_8)) + val keyBytes = decodeBase64(SECRET) + val ivSpec = IvParameterSpec(IV.toByteArray(StandardCharsets.UTF_8)) val keySpec = SecretKeySpec(keyBytes, "AES") val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding") @@ -61,4 +67,17 @@ class AnimekaiDecoder { val decrypted = cipher.doFinal(decodeBase64(base64Data)) return String(decrypted, StandardCharsets.UTF_8) } -} + + companion object { + private const val SECRET = "T3xKHVZBiNwbzVBDLTlaTw==" + private const val IV = "3rR5dURR27mN" + + private fun decodeBase64(data: String): ByteArray { + return Base64.decode(data, Base64.NO_WRAP) + } + + private fun encodeBase64(data: ByteArray): String { + return Base64.encodeToString(data, Base64.NO_WRAP) + } + } +} \ No newline at end of file