diff --git a/utils/src/main/kotlin/cn/tursom/utils/TokenUtil.kt b/utils/src/main/kotlin/cn/tursom/utils/TokenUtil.kt
index 535fa9d..d8200a1 100644
--- a/utils/src/main/kotlin/cn/tursom/utils/TokenUtil.kt
+++ b/utils/src/main/kotlin/cn/tursom/utils/TokenUtil.kt
@@ -12,20 +12,20 @@ open class TokenUtil {
   @Suppress("MemberVisibilityCanBePrivate", "CanBeParameter")
   enum class DigestType(val digest: String) {
     MD5("MD5"), SHA256("SHA-256"), SHA512("SHA-512");
-
+    
     val digestBase64: String = digest.base64()
   }
-
-  fun <T> generate(secretKey: String, data: T, timeout: Long = 30 * 60 * 1000, type: DigestType = DigestType.MD5): String {
+  
+  fun <T : Token> generate(secretKey: String, data: T, type: DigestType = DigestType.MD5): String {
     val head = type.digestBase64
-    val body = toJson(TokenBody(System.currentTimeMillis(), timeout, data)).base64()
+    val body = toJson(data).base64()
     val encryptSource = "$head.$body".toByteArray()
     val encrypt = encrypt(secretKey, encryptSource, type.digest)
     return "$head.$body.$encrypt"
   }
-
+  
   @Throws(TokenException::class)
-  fun <T : Any> decode(secretKey: String, token: String, dataClazz: Class<T>): T {
+  fun <T : Token> decode(secretKey: String, token: String, dataClazz: Class<T>): T {
     val splitToken = token.split(".")
     if (splitToken.size != 3) {
       throw WrongTokenSyntaxException()
@@ -34,14 +34,14 @@ open class TokenUtil {
     if (signature != splitToken[2]) {
       throw WrongSignatureException()
     }
-    val decode = fromJson<TokenBody<T>>(splitToken[1].base64decode())
+    val decode = fromJson(splitToken[1].base64decode(), dataClazz)
     if (decode.tim + decode.exp < System.currentTimeMillis()) {
       throw TokenTimeoutException()
     }
-    return fromJson(toJson(decode.dat), dataClazz)
+    return decode
   }
-
-  open fun encrypt(secretKey: String, encryptSource: ByteArray, type: String): String {
+  
+  protected open fun encrypt(secretKey: String, encryptSource: ByteArray, type: String): String {
     val inner = secretKey.toByteArray().digest(type)!!
     encryptSource.forEachIndexed { index, _ ->
       encryptSource[index] = encryptSource[index] xor inner[index % inner.size]
@@ -52,21 +52,22 @@ open class TokenUtil {
     }
     return digest1.digest(type)!!.toHexString()!!
   }
-
+  
   open fun toJson(bean: Any): String = gson.toJson(bean)
   open fun <T> fromJson(json: String, clazz: Class<T>): T = gson.fromJson(json, clazz)
-
-  private inline fun <reified T : Any> fromJson(json: String): T = fromJson(json, T::class.java)
-
-  data class TokenBody<T>(val tim: Long, val exp: Long, val dat: T)
-
+  
+  interface Token {
+    val tim: Long
+    val exp: Long
+  }
+  
   open class TokenException : Exception()
   class WrongTokenSyntaxException : TokenException()
   class WrongSignatureException : TokenException()
   class TokenTimeoutException : TokenException()
-
+  
   companion object {
     @JvmStatic
-    val instance = TokenUtil()
+    val gsonTokenUtil = TokenUtil()
   }
 }