将另一个文件的非 class 函数访问到 Kotlin 中的 class 函数
Access non class functions of another file into a class function in Kotlin
我刚刚开始使用 Kotlin,我的代码正在执行正常操作。我需要从另一个文件中定义的 class 调用一个函数,而这个文件没有 class。例如,
File1.kt
从该文件调用主函数并定义一个 class 的对象并在此处访问 class 函数,但此 class 是在 File2.kt
中定义的文件。
fun main(args: Array<String>) {
val secretKey: String = "662ede816988e58fb6d057d9d85605e0"
val initVector = "de816988e58f"
var encryptor: AESEncryptor = AESEncryptor()
val encryptedValue: String? =encryptor.encrypt("This is the first code for encryption in Kotlin.", secretKey, initVector)
println(encryptedValue)
val decryptedValue: String? =encryptor.decryptWithAES(secretKey, encryptedValue, initVector)
println(decryptedValue)
}
File2.kt
此文件中定义了一个 class,此 class 需要访问 File3.kt
文件中定义的函数。
import java.io.UnsupportedEncodingException
import java.security.InvalidKeyException
import java.security.NoSuchAlgorithmException
import javax.crypto.*
import javax.crypto.spec.GCMParameterSpec
import javax.crypto.spec.SecretKeySpec
class AESEncryptor {
fun encrypt(strToEncrypt: String, secret_key: String, iv_key: String): String? {
var keyBytes: ByteArray
var ivKeyBytes: ByteArray
try {
keyBytes = secret_key.toByteArray(charset("UTF8"))
ivKeyBytes = iv_key.toByteArray(charset("UTF8"))
val skey = SecretKeySpec(keyBytes, "AES")
val iv = GCMParameterSpec(128, ivKeyBytes, 0, 12)
val input = strToEncrypt.toByteArray(charset("UTF8"))
synchronized(Cipher::class.java) {
val cipher = Cipher.getInstance("AES/GCM/NoPadding")
cipher.init(Cipher.ENCRYPT_MODE, skey, iv)
val cipherText = ByteArray(cipher.getOutputSize(input.size))
var ctLength = cipher.update(
input, 0, input.size,
cipherText, 0
)
ctLength += cipher.doFinal(cipherText, ctLength)
return cipherText.encodeBase64ToString()
}
} catch (uee: UnsupportedEncodingException) {
uee.printStackTrace()
} catch (ibse: IllegalBlockSizeException) {
ibse.printStackTrace()
} catch (bpe: BadPaddingException) {
bpe.printStackTrace()
} catch (ike: InvalidKeyException) {
ike.printStackTrace()
} catch (nspe: NoSuchPaddingException) {
nspe.printStackTrace()
} catch (nsae: NoSuchAlgorithmException) {
nsae.printStackTrace()
} catch (e: ShortBufferException) {
e.printStackTrace()
}
return null
}
fun decryptWithAES(key: String, strToDecrypt: String?, iv_key: String): String? {
//Security.addProvider(BouncyCastleProvider())
var keyBytes: ByteArray
var ivKeyBytes: ByteArray
var encryptor: AESEncryptor = AESEncryptor()
try {
keyBytes = key.toByteArray(charset("UTF8"))
ivKeyBytes = iv_key.toByteArray(charset("UTF8"))
val skey = SecretKeySpec(keyBytes, "AES")
//val iv = GCMParameterSpec(ivKeyBytes)
val iv = GCMParameterSpec(128, ivKeyBytes, 0, 12)
val input = (strToDecrypt?.trim { it <= ' ' }?.toByteArray(charset("UTF8")))?.decodeBase64()
synchronized(Cipher::class.java) {
val cipher = Cipher.getInstance("AES/GCM/NoPadding")
cipher.init(Cipher.DECRYPT_MODE, skey, iv)
val plainText = ByteArray(cipher.getOutputSize(input?.size!!))
var ptLength = cipher.update(input, 0, input?.size!!, plainText, 0)
ptLength += cipher.doFinal(plainText, ptLength)
val decryptedString = String(plainText)
return decryptedString.trim { it <= ' ' }
}
} catch (uee: UnsupportedEncodingException) {
uee.printStackTrace()
} catch (ibse: IllegalBlockSizeException) {
ibse.printStackTrace()
} catch (bpe: BadPaddingException) {
bpe.printStackTrace()
} catch (ike: InvalidKeyException) {
ike.printStackTrace()
} catch (nspe: NoSuchPaddingException) {
nspe.printStackTrace()
} catch (nsae: NoSuchAlgorithmException) {
nsae.printStackTrace()
} catch (e: ShortBufferException) {
e.printStackTrace()
}
return null
}
}
File3.kt
这种形式只定义了一组函数。
import java.io.ByteArrayOutputStream
public fun String.encodeBase64ToString(): String = String(this.toByteArray().encodeBase64())
fun String.encodeBase64ToByteArray(): ByteArray = this.toByteArray().encodeBase64()
fun ByteArray.encodeBase64ToString(): String = String(this.encodeBase64())
fun String.decodeBase64(): String = String(this.toByteArray().decodeBase64())
fun String.decodeBase64ToByteArray(): ByteArray = this.toByteArray().decodeBase64()
fun ByteArray.decodeBase64ToString(): String = String(this.decodeBase64())
public fun ByteArray.encodeBase64(): ByteArray {
val table = (CharRange('A', 'Z') + CharRange('a', 'z') + CharRange('0', '9') + '+' + '/').toCharArray()
val output = ByteArrayOutputStream()
var padding = 0
var position = 0
while (position < this.size) {
var b = this[position].toInt() and 0xFF shl 16 and 0xFFFFFF
if (position + 1 < this.size) b = b or (this[position + 1].toInt() and 0xFF shl 8) else padding++
if (position + 2 < this.size) b = b or (this[position + 2].toInt() and 0xFF) else padding++
for (i in 0 until 4 - padding) {
val c = b and 0xFC0000 shr 18
output.write(table[c].toInt())
b = b shl 6
}
position += 3
}
for (i in 0 until padding) {
output.write('='.toInt())
}
return output.toByteArray()
}
fun ByteArray.decodeBase64(): ByteArray {
val table = intArrayOf(-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1,
-1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
-1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)
val output = ByteArrayOutputStream()
var position = 0
while (position < this.size) {
var b: Int
if (table[this[position].toInt()] != -1) {
b = table[this[position].toInt()] and 0xFF shl 18
} else {
position++
continue
}
var count = 0
if (position + 1 < this.size && table[this[position + 1].toInt()] != -1) {
b = b or (table[this[position + 1].toInt()] and 0xFF shl 12)
count++
}
if (position + 2 < this.size && table[this[position + 2].toInt()] != -1) {
b = b or (table[this[position + 2].toInt()] and 0xFF shl 6)
count++
}
if (position + 3 < this.size && table[this[position + 3].toInt()] != -1) {
b = b or (table[this[position + 3].toInt()] and 0xFF)
count++
}
while (count > 0) {
val c = b and 0xFF0000 shr 16
output.write(c.toChar().toInt())
b = b shl 8
count--
}
position += 4
}
return output.toByteArray()
}
我需要使用encodeBase64ToString
函数和File2.kt
中的其他函数(AESEncryptor.kt
)。我能不能做这个?
谁能帮我解决这个问题?
由于您将 File3.kt
中的函数声明为 extension functions,因此您应该以正确的语法使用它们。
所以,不是
return encodeBase64ToString(cipherText)
但是
return cipherText.encodeBase64ToString()
我刚刚开始使用 Kotlin,我的代码正在执行正常操作。我需要从另一个文件中定义的 class 调用一个函数,而这个文件没有 class。例如,
File1.kt
从该文件调用主函数并定义一个 class 的对象并在此处访问 class 函数,但此 class 是在 File2.kt
中定义的文件。
fun main(args: Array<String>) {
val secretKey: String = "662ede816988e58fb6d057d9d85605e0"
val initVector = "de816988e58f"
var encryptor: AESEncryptor = AESEncryptor()
val encryptedValue: String? =encryptor.encrypt("This is the first code for encryption in Kotlin.", secretKey, initVector)
println(encryptedValue)
val decryptedValue: String? =encryptor.decryptWithAES(secretKey, encryptedValue, initVector)
println(decryptedValue)
}
File2.kt
此文件中定义了一个 class,此 class 需要访问 File3.kt
文件中定义的函数。
import java.io.UnsupportedEncodingException
import java.security.InvalidKeyException
import java.security.NoSuchAlgorithmException
import javax.crypto.*
import javax.crypto.spec.GCMParameterSpec
import javax.crypto.spec.SecretKeySpec
class AESEncryptor {
fun encrypt(strToEncrypt: String, secret_key: String, iv_key: String): String? {
var keyBytes: ByteArray
var ivKeyBytes: ByteArray
try {
keyBytes = secret_key.toByteArray(charset("UTF8"))
ivKeyBytes = iv_key.toByteArray(charset("UTF8"))
val skey = SecretKeySpec(keyBytes, "AES")
val iv = GCMParameterSpec(128, ivKeyBytes, 0, 12)
val input = strToEncrypt.toByteArray(charset("UTF8"))
synchronized(Cipher::class.java) {
val cipher = Cipher.getInstance("AES/GCM/NoPadding")
cipher.init(Cipher.ENCRYPT_MODE, skey, iv)
val cipherText = ByteArray(cipher.getOutputSize(input.size))
var ctLength = cipher.update(
input, 0, input.size,
cipherText, 0
)
ctLength += cipher.doFinal(cipherText, ctLength)
return cipherText.encodeBase64ToString()
}
} catch (uee: UnsupportedEncodingException) {
uee.printStackTrace()
} catch (ibse: IllegalBlockSizeException) {
ibse.printStackTrace()
} catch (bpe: BadPaddingException) {
bpe.printStackTrace()
} catch (ike: InvalidKeyException) {
ike.printStackTrace()
} catch (nspe: NoSuchPaddingException) {
nspe.printStackTrace()
} catch (nsae: NoSuchAlgorithmException) {
nsae.printStackTrace()
} catch (e: ShortBufferException) {
e.printStackTrace()
}
return null
}
fun decryptWithAES(key: String, strToDecrypt: String?, iv_key: String): String? {
//Security.addProvider(BouncyCastleProvider())
var keyBytes: ByteArray
var ivKeyBytes: ByteArray
var encryptor: AESEncryptor = AESEncryptor()
try {
keyBytes = key.toByteArray(charset("UTF8"))
ivKeyBytes = iv_key.toByteArray(charset("UTF8"))
val skey = SecretKeySpec(keyBytes, "AES")
//val iv = GCMParameterSpec(ivKeyBytes)
val iv = GCMParameterSpec(128, ivKeyBytes, 0, 12)
val input = (strToDecrypt?.trim { it <= ' ' }?.toByteArray(charset("UTF8")))?.decodeBase64()
synchronized(Cipher::class.java) {
val cipher = Cipher.getInstance("AES/GCM/NoPadding")
cipher.init(Cipher.DECRYPT_MODE, skey, iv)
val plainText = ByteArray(cipher.getOutputSize(input?.size!!))
var ptLength = cipher.update(input, 0, input?.size!!, plainText, 0)
ptLength += cipher.doFinal(plainText, ptLength)
val decryptedString = String(plainText)
return decryptedString.trim { it <= ' ' }
}
} catch (uee: UnsupportedEncodingException) {
uee.printStackTrace()
} catch (ibse: IllegalBlockSizeException) {
ibse.printStackTrace()
} catch (bpe: BadPaddingException) {
bpe.printStackTrace()
} catch (ike: InvalidKeyException) {
ike.printStackTrace()
} catch (nspe: NoSuchPaddingException) {
nspe.printStackTrace()
} catch (nsae: NoSuchAlgorithmException) {
nsae.printStackTrace()
} catch (e: ShortBufferException) {
e.printStackTrace()
}
return null
}
}
File3.kt
这种形式只定义了一组函数。
import java.io.ByteArrayOutputStream
public fun String.encodeBase64ToString(): String = String(this.toByteArray().encodeBase64())
fun String.encodeBase64ToByteArray(): ByteArray = this.toByteArray().encodeBase64()
fun ByteArray.encodeBase64ToString(): String = String(this.encodeBase64())
fun String.decodeBase64(): String = String(this.toByteArray().decodeBase64())
fun String.decodeBase64ToByteArray(): ByteArray = this.toByteArray().decodeBase64()
fun ByteArray.decodeBase64ToString(): String = String(this.decodeBase64())
public fun ByteArray.encodeBase64(): ByteArray {
val table = (CharRange('A', 'Z') + CharRange('a', 'z') + CharRange('0', '9') + '+' + '/').toCharArray()
val output = ByteArrayOutputStream()
var padding = 0
var position = 0
while (position < this.size) {
var b = this[position].toInt() and 0xFF shl 16 and 0xFFFFFF
if (position + 1 < this.size) b = b or (this[position + 1].toInt() and 0xFF shl 8) else padding++
if (position + 2 < this.size) b = b or (this[position + 2].toInt() and 0xFF) else padding++
for (i in 0 until 4 - padding) {
val c = b and 0xFC0000 shr 18
output.write(table[c].toInt())
b = b shl 6
}
position += 3
}
for (i in 0 until padding) {
output.write('='.toInt())
}
return output.toByteArray()
}
fun ByteArray.decodeBase64(): ByteArray {
val table = intArrayOf(-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1,
-1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
-1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)
val output = ByteArrayOutputStream()
var position = 0
while (position < this.size) {
var b: Int
if (table[this[position].toInt()] != -1) {
b = table[this[position].toInt()] and 0xFF shl 18
} else {
position++
continue
}
var count = 0
if (position + 1 < this.size && table[this[position + 1].toInt()] != -1) {
b = b or (table[this[position + 1].toInt()] and 0xFF shl 12)
count++
}
if (position + 2 < this.size && table[this[position + 2].toInt()] != -1) {
b = b or (table[this[position + 2].toInt()] and 0xFF shl 6)
count++
}
if (position + 3 < this.size && table[this[position + 3].toInt()] != -1) {
b = b or (table[this[position + 3].toInt()] and 0xFF)
count++
}
while (count > 0) {
val c = b and 0xFF0000 shr 16
output.write(c.toChar().toInt())
b = b shl 8
count--
}
position += 4
}
return output.toByteArray()
}
我需要使用encodeBase64ToString
函数和File2.kt
中的其他函数(AESEncryptor.kt
)。我能不能做这个?
谁能帮我解决这个问题?
由于您将 File3.kt
中的函数声明为 extension functions,因此您应该以正确的语法使用它们。
所以,不是
return encodeBase64ToString(cipherText)
但是
return cipherText.encodeBase64ToString()