[英]Cannot encode to UTF-8 in JNI
我試圖返回用UTF-8編碼的jstring,但是應用程序崩潰並且JNI寫出錯誤:
JNI DETECTED ERROR IN APPLICATION: input is not valid Modified UTF-8: illegal continuation byte 0x30
我的片段:
jstring Java_tgio_rncryptor_RNCryptorNative_generateKey(JNIEnv *env, jobject instance, const jstring salt_, const jstring password_)
{
const char *salt = env->GetStringUTFChars(salt_, 0);
const char *password = env->GetStringUTFChars(password_, 0);
RNCryptor *cryptor = new RNCryptor();
string value = (char * )cryptor->generateKey(salt, password).data();
delete cryptor;
env->ReleaseStringUTFChars(salt_, salt);
env->ReleaseStringUTFChars(password_, password);
return env->NewStringUTF(value.c_str());
}
還嘗試了:
const char *returning = env->GetStringUTFChars(env->NewStringUTF(value.c_str()), 0);
return env->NewStringUTF(returning);
有什么建議么?
cryptor->generateKey
返回SecByteBlock
,一個字節序列。 當強制轉換為(char *)
並構造std::string
因為它們不僅僅處理文本,所以jstring
保留文本(來自UTF-16編碼的Unicode字符集)。
您的代碼嘗試將非文本字節轉換為Java字符串。 如果確實要這樣做,則必須使用字符集和編碼,其任何值序列0-255均有效。 (CP437就是其中之一。)
但是,相反,您可以將數據保留在更接近數據類型的數據類型中:返回Java byte[]
。 然后在Java端,如果要將密鑰作為字符串傳遞,則可以將字節序列轉換為Base 64 。
通常,密碼算法對字節序列或塊進行操作。 處理文本的只是應用程序或包裝函數。 您將檢查RNCryptor是否為您執行此操作,但是對我而言,它看起來不是那樣。
嘗試將此代碼用於UTF-8
try {
URLEncoder.encode(yourValue, "UTF-8")
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
並非所有字節都是有效的可打印字符,並且大多數不是有效的unicode字符。 當需要將字節數組編碼為字符串時,標准做法是使用Base64或十六進制。
我通過返回jcharArray
而不是jstring
解決了問題:
env->ReleaseStringUTFChars(salt_, salt);
env->ReleaseStringUTFChars(password_, password);
char array[1024];
strcpy(array, value.c_str());
jcharArray charArr = env->NewCharArray(1024);
env->SetCharArrayRegion(charArr, 0, 1024, (jchar *) array);
return charArr;
我只是在Java源代碼中執行了String.valueOf(arr)
並將其打印出來。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.