com.xml.guard.utils.StringFogUtils.kt Maven / Gradle / Ivy
package com.xml.guard.utils
import com.xml.guard.model.MappingParser
import java.io.File
import java.util.Base64
import kotlin.experimental.xor
// 字符串加密
fun String.stringFogEncrypt(key: ByteArray): String {
val fog = stringFog(this.toByteArray(), key)
val bytes = if (fog.isEmpty()) fog else Base64.getEncoder().encode(fog)
return String(bytes)
}
// 字符串解密
fun String.stringFogDecrypt(key: ByteArray): String {
val fog = this.toByteArray()
val data = if (fog.isEmpty()) fog else Base64.getDecoder().decode(fog)
val bytes = stringFog(data, key)
return String(bytes)
}
// 创建字符串加解密工具类
fun File.createStringFog(
packageName: String,
className: String,
methodName: String,
key: String
) {
fun generateName(): String {
val obfuscateName = getRandomString { text ->
val result = text.lowercase()
MappingParser.verifyObfuscateName(result)
}
return obfuscateName
}
val keyName = generateName().randomizeCase().lowercaseFirstChar()
val dataName = generateName().randomizeCase().lowercaseFirstChar()
val bytesName = generateName().randomizeCase().lowercaseFirstChar()
val convertName = generateName().randomizeCase().lowercaseFirstChar()
val lenName = generateName().randomizeCase().lowercaseFirstChar()
val lenKeyName = generateName().randomizeCase().lowercaseFirstChar()
val iName = generateName()
val jName = generateName()
val text = """
package $packageName;
import androidx.annotation.NonNull;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
public class $className {
@NonNull
public static String $methodName(@NonNull String ${dataName}) {
byte[] $bytesName = ${dataName}.getBytes(StandardCharsets.UTF_8);
if (${bytesName}.length > 0) {
$bytesName = Base64.getDecoder().decode(${bytesName});
}
return new String(${convertName}(${bytesName}));
}
@NonNull
private static byte[] ${convertName}(@NonNull byte[] ${bytesName}) {
byte[] $keyName = "$key".getBytes(StandardCharsets.UTF_8);
int $lenName = ${bytesName}.length;
int $lenKeyName = ${keyName}.length;
int $iName = 0;
int $jName = 0;
while (${iName} < ${lenName}) {
if (${jName} >= ${lenKeyName}) {
$jName = 0;
}
${bytesName}[${iName}] = (byte) (${bytesName}[${iName}] ^ ${keyName}[${jName}]);
${iName}++;
${jName}++;
}
return ${bytesName};
}
}
""".trimIndent()
writeText(text)
}
// 字符串加解密混淆
private fun stringFog(data: ByteArray, key: ByteArray): ByteArray {
val len = data.size
val lenKey = key.size
var i = 0
var j = 0
while (i < len) {
if (j >= lenKey) {
j = 0
}
data[i] = (data[i] xor key[j])
i++
j++
}
return data
}