版权归作者所有,如有转发,请注明文章出处:cyrus-studio.github.io/blog/
Java 实现标准 Base64 编码和解码
Base64 编码:
vbscript
val encoded = Base64.encodeToString(str.toByteArray(), Base64.DEFAULT)
Base64 解码:
ini
val decoded = Base64.decode(str, Base64.DEFAULT)
val decodedString = String(decoded)
C++ 实现标准 Base64 编d码和解码
创建 base64.cpp 实现 Base64 编码和解码
scss
#include <jni.h>
#include <string>
#include <android/log.h>
static const std::string base64_chars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
// 检查字符是否是 Base64 字符
static inline bool is_base64(unsigned char c) {
return (isalnum(c) || (c == '+') || (c == '/'));
}
// Base64 编码函数
std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) {
std::string ret;
int i = 0;
int j = 0;
unsigned char char_array_3[3];
unsigned char char_array_4[4];
while (in_len--) {
char_array_3[i++] = *(bytes_to_encode++);
if (i == 3) {
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for (i = 0; i < 4; i++) {
ret += base64_chars[char_array_4[i]];
}
i = 0;
}
}
if (i) {
for (int j = i; j < 3; j++) {
char_array_3[j] = '\0';
}
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for (int j = 0; j < i + 1; j++) {
ret += base64_chars[char_array_4[j]];
}
while ((i++ < 3)) {
ret += '=';
}
}
return ret;
}
// Base64 解码函数
std::string base64_decode(std::string const& encoded_string) {
int in_len = encoded_string.size();
int i = 0;
int j = 0;
int in_ = 0;
unsigned char char_array_4[4], char_array_3[3];
std::string ret;
while (in_len-- && (encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
char_array_4[i++] = encoded_string[in_];
in_++;
if (i == 4) {
for (i = 0; i < 4; i++) {
char_array_4[i] = base64_chars.find(char_array_4[i]);
}
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
for (i = 0; i < 3; i++) {
ret += char_array_3[i];
}
i = 0;
}
}
if (i) {
for (int j = i; j < 4; j++) {
char_array_4[j] = 0;
}
for (int j = 0; j < 4; j++) {
char_array_4[j] = base64_chars.find(char_array_4[j]);
}
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
for (int j = 0; j < i - 1; j++) {
ret += char_array_3[j];
}
}
return ret;
}
参考:Base64 decode snippet in C++
Kotlin 层中声明 native 编码和解码函数
kotlin
// 标准 Base64(C++)
external fun nativeBase64Encode(data: ByteArray): String
external fun nativeBase64Decode(input: String): ByteArray
实现 native 函数并调用 C++ 中 Base64 编码和解码函数
scss
extern "C" JNIEXPORT jstring JNICALL
Java_com_cyrus_example_base64_Base64Activity_nativeBase64Encode(JNIEnv* env, jobject, jbyteArray input) {
jsize input_len = env->GetArrayLength(input);
unsigned char* bytes_to_encode = reinterpret_cast<unsigned char*>(env->GetByteArrayElements(input, nullptr));
std::string encoded = base64_encode(bytes_to_encode, input_len);
env->ReleaseByteArrayElements(input, reinterpret_cast<jbyte*>(bytes_to_encode), 0);
return env->NewStringUTF(encoded.c_str());
}
extern "C" JNIEXPORT jbyteArray JNICALL
Java_com_cyrus_example_base64_Base64Activity_nativeBase64Decode(JNIEnv* env, jobject, jstring input) {
const char* encoded_chars = env->GetStringUTFChars(input, nullptr);
std::string encoded_string(encoded_chars);
std::string decoded_string = base64_decode(encoded_string);
env->ReleaseStringUTFChars(input, encoded_chars);
jbyteArray decoded_byte_array = env->NewByteArray(decoded_string.size());
env->SetByteArrayRegion(decoded_byte_array, 0, decoded_string.size(), reinterpret_cast<const jbyte*>(decoded_string.c_str()));
return decoded_byte_array;
}
Kotlin 中调用编码函数
ini
val encoded = nativeBase64Encode(selected.toByteArray())
Kotlin 中调用解码函数
ini
val decodedString = String(nativeBase64Decode(selected))
自定义码表
Base64 的标准编码表是:
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
自定义 Base64 码表就是 替换这个字符映射,比如:
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_
这里我把大小写字母顺序调转,还有用 -_ 代替了 +/。
Kotlin 端用 external 关键字声明对应的 native 方法。
kotlin
// 自定义 Base64 编码和解码
external fun customBase64Encode(data: ByteArray): String
external fun customBase64Decode(encoded: String): ByteArray
C++ 实现 customBase64Encode 和 customBase64Decode(使用自定义 Base64 码表)。
c
#include <jni.h>
#include <string>
#include <vector>
#include <android/log.h>
#define LOG_TAG "Base64Custom"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
// 自定义 Base64 码表
static const std::string CUSTOM_BASE64_ALPHABET = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_";
// **自定义 Base64 编码**
extern "C"
JNIEXPORT jstring JNICALL
Java_com_cyrus_example_base64_Base64Activity_customBase64Encode(JNIEnv *env, jobject thiz, jbyteArray data) {
jsize len = env->GetArrayLength(data);
std::vector<unsigned char> input(len);
env->GetByteArrayRegion(data, 0, len, reinterpret_cast<jbyte *>(input.data()));
std::string encoded;
int val = 0, valb = -6;
for (unsigned char c : input) {
val = (val << 8) + c;
valb += 8;
while (valb >= 0) {
encoded.push_back(CUSTOM_BASE64_ALPHABET[(val >> valb) & 0x3F]);
valb -= 6;
}
}
if (valb > -6) {
encoded.push_back(CUSTOM_BASE64_ALPHABET[((val << 8) >> (valb + 8)) & 0x3F]);
}
return env->NewStringUTF(encoded.c_str());
}
// **自定义 Base64 解码**
extern "C"
JNIEXPORT jbyteArray JNICALL
Java_com_cyrus_example_base64_Base64Activity_customBase64Decode(JNIEnv *env, jobject thiz, jstring encodedStr) {
const char *encoded = env->GetStringUTFChars(encodedStr, nullptr);
if (encoded == nullptr) return nullptr; // 内存分配失败
std::string input(encoded);
env->ReleaseStringUTFChars(encodedStr, encoded);
std::vector<unsigned char> output;
std::vector<int> T(256, -1);
for (int i = 0; i < CUSTOM_BASE64_ALPHABET.size(); i++) {
T[CUSTOM_BASE64_ALPHABET[i]] = i;
}
int val = 0, valb = -8;
for (unsigned char c : input) {
if (T[c] == -1) break;
val = (val << 6) + T[c];
valb += 6;
if (valb >= 0) {
output.push_back((val >> valb) & 0xFF);
valb -= 8;
}
}
jbyteArray result = env->NewByteArray(output.size());
env->SetByteArrayRegion(result, 0, output.size(), reinterpret_cast<jbyte *>(output.data()));
return result;
}
Kotlin 中调用编码函数
ini
val encoded = customBase64Encode(selected.toByteArray())
Kotlin 中调用解码函数
ini
val decodedString = String(customBase64Decode(selected))
动态码表
基于输入字符串长度的动态 Base64 码表,让 Base64 码表动态变化,方法是:
-
根据输入字符串的长度计算一个 XOR(异或)值。
-
使用 XOR 值对标准 Base64 码表进行偏移,生成新的 Base64 码表。
-
在编码和解码时使用这个动态码表。
计算 xor_key = length % 64,用于 异或 码表索引
-
xor_key 控制字符映射偏移。
-
i ^ xor_key 让字符位置变化。
c
#include <jni.h>
#include <string>
#include <vector>
#include <android/log.h>
#define TAG "DynamicBase64"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__)
// 标准 Base64 码表
static const std::string BASE64_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
// 根据字符串长度生成 Base64 动态码表
std::string generateDynamicBase64Alphabet(size_t length) {
std::string dynamicBase64(64, ' ');
int xor_key = length % 64;
for (int i = 0; i < 64; i++) {
int new_index = i ^ xor_key; // 计算新的索引
dynamicBase64[new_index] = BASE64_ALPHABET[i]; // 重新排列字符
}
return dynamicBase64;
}
动态 Base64 编码
-
码表基于 输入长度变化,用 异或(XOR)运算 生成新字符映射。
-
使 Base64 在不同长度下编码不同的字符串。
ini
// 动态 Base64 编码
std::string dynamicBase64Encode(const uint8_t* data, size_t length) {
std::string base64Alphabet = generateDynamicBase64Alphabet(length);
std::string encoded;
int val = 0, valb = -6;
for (size_t i = 0; i < length; i++) {
val = (val << 8) + data[i];
valb += 8;
while (valb >= 0) {
encoded.push_back(base64Alphabet[(val >> valb) & 0x3F]);
valb -= 6;
}
}
if (valb > -6) {
encoded.push_back(base64Alphabet[((val << 8) >> (valb + 8)) & 0x3F]);
}
return encoded;
}
动态 Base64 解码
-
用 相同的 XOR 码表恢复原数据。
-
需 传入原始字符串长度 以正确解码。
c
// 动态 Base64 解码
std::vector<uint8_t> dynamicBase64Decode(const std::string& input, size_t originalLength) {
std::string base64Alphabet = generateDynamicBase64Alphabet(originalLength);
std::vector<int> T(256, -1);
for (int i = 0; i < 64; i++) {
T[base64Alphabet[i]] = i; // 生成解码表
}
std::vector<uint8_t> decoded;
int val = 0, valb = -8;
for (unsigned char c : input) {
if (T[c] == -1) break;
val = (val << 6) + T[c];
valb += 6;
if (valb >= 0) {
decoded.push_back((val >> valb) & 0xFF);
valb -= 8;
}
}
return decoded;
}
声明 native 编码和解码函数
kotlin
// 动态 Base64 编码和解码
external fun dynamicBase64Encode(input: ByteArray): String
external fun dynamicBase64Decode(input: String, originalLength: Int): ByteArray
C++ 中实现 native 编码和解码函数
scss
// JNI 动态 Base64 编码
extern "C" JNIEXPORT jstring JNICALL
Java_com_cyrus_example_base64_Base64Activity_dynamicBase64Encode(JNIEnv* env, jobject, jbyteArray input) {
jsize length = env->GetArrayLength(input);
jbyte* data = env->GetByteArrayElements(input, nullptr);
std::string encoded = dynamicBase64Encode(reinterpret_cast<uint8_t*>(data), length);
env->ReleaseByteArrayElements(input, data, JNI_ABORT);
return env->NewStringUTF(encoded.c_str());
}
// JNI 动态 Base64 解码
extern "C" JNIEXPORT jbyteArray JNICALL
Java_com_cyrus_example_base64_Base64Activity_dynamicBase64Decode(JNIEnv* env, jobject, jstring input, jint originalLength) {
const char* encodedStr = env->GetStringUTFChars(input, nullptr);
std::vector<uint8_t> decoded = dynamicBase64Decode(std::string(encodedStr), originalLength);
env->ReleaseStringUTFChars(input, encodedStr);
jbyteArray output = env->NewByteArray(decoded.size());
env->SetByteArrayRegion(output, 0, decoded.size(), reinterpret_cast<jbyte*>(decoded.data()));
return output;
}
Kotlin 中调用 native 方法编码
ini
val data = str.toByteArray()
stringLength = data.size
val encoded = dynamicBase64Encode(data)
Kotlin 中调用 native 方法解码
ini
val decodedBytes = dynamicBase64Decode(selected, stringLength)
val decodedString = String(decodedBytes)
完整源码
完整源码地址:github.com/CYRUS-STUDI...