使用NDK實現的Base64編 解碼

2021-07-24 13:33:48 字數 3634 閱讀 3068

base64的編譯碼原理很簡單,下面是編譯碼的部分核心**:

編碼:

/**

* 編碼

* data : byte陣列

* reallength : 陣列長度

* offset : 偏移量

* length : 從偏移量開始擷取的長度

* flag : 選項

*/encodedata *encode(const char *data, int reallength, int offset, int length, int flag)

}if (flags->iswrap)

free(flags);

encodedata->length = encodelength;

return encodedata;

}

編碼部分用unit test裡簡略的執行時間統計,速度大概比原來android方法20%左右

解碼:

/**

* 另一種方法解碼,不預先計算解碼長度

*/decodedata *decodelikeandroid(const char *data, int reallength, int offset, int length, int flag)

if (index >= len)

break;

}c = table[data[index++]];

switch (state) else if (c != decode_skip)

return geterrordecodedata(decodedata);

break;

case 1:

if (c < decode_equals) else if (c != decode_skip)

return geterrordecodedata(decodedata);

break;

case 2:

if (c < decode_equals) else if (c == decode_equals) else if (c != decode_skip)

return geterrordecodedata(decodedata);

break;

case 3:

if (c < decode_equals) else if (c == decode_equals) else if (c != decode_skip)

return geterrordecodedata(decodedata);

break;

case 4:

if (c == decode_equals) else if (c != decode_skip)

return geterrordecodedata(decodedata);

break;

case 5:

if (c != decode_skip)

return geterrordecodedata(decodedata);

break;}}

//跳出while迴圈後

switch (state)

decodedata->length = decodelength;

return decodedata;

}

注意的是,解碼部分還是用了android原始碼中base64的解碼方法,原因是在解碼中會出現解碼資料被無效字元汙染的情況,暫時沒想到好的思路。

結果倒是很有意思,我在單元測試裡寫了簡單的統計執行時間,結果解碼時間比android提供的base64方法還要慢一些(大資料量、10000次左右的迴圈)。

想到好的思路再修改了

修改瞭解碼拼接字元部分,現在在同一測試中的執行時間基本與android方法持平(最多快1%)

另外,**裡寫了乙個計算解碼後資料長度的方法,適合統計資料來源裡沒有汙染情況下的解碼長度:

/**

* 計算解碼後的資料長度

*/int getdecodelength(const char *data, int reallength, int offset, int length, flags *flags) else if (!flags->ispadding && templength < 2)

//計算資料尾部的換行符佔位數(若存在)

int endspace = 0;

if (length == len_default || (length + offset == reallength)) else if (data[reallength - 1] == '\n')

endspace = 1;

}sprintf(log, "endspace:%d", endspace);

logv(log);

//計算換行符個數

int enters = 0;

if (flags->iswrap)

sprintf(log, "enters:%d", enters);

logv(log);

templength -= endspace;

decodelength = templength;

int t = templength - enters;

templength = t >= 0 ? t : templength;

bool isremainder = false;

int equals = 0;//記錄'='號個數(若存在)

int remainder = 0;//記錄餘數(若存在)

sprintf(log, "templength--:%d", templength);

logv(log);

/** 多判斷一層,存在padding時,解碼資料不足4位且不能被4整除的throw exception,

* 不存在padding時,最少解碼資料是2位,資料不能被4整除時,若餘數為1、2,則資料完整可被解碼

*/if (flags->ispadding)

if (data[decodelength - 2] == '=')

else if (data[decodelength - 1] == '=')

} else else if (d != 0)

}if (isremainder) else

sprintf(log, "decodelength--:%d", decodelength);

logv(log);

return decodelength;

}

獲取編碼後長度的方法也有,思路簡單很多:

/**

* 計算、獲取編碼長度

*/int getencodelength(int reallength, int length, flags *flags)

//沒有padding,不需要在後面補'='

if (!flags->ispadding && remainder > 0)

encodelength -= (3 - remainder);

}return encodelength;

}

具體的**已上傳到github:

BASE64演算法實現

cstring base64encode lpctstr lpszsrc 56 63 unsigned int itest lpctstr pinbuffer lpszsrc int nsize int tcslen lpszsrc char poutbuffer new char nsize 3 ...

base64編碼實現

package com.ls.hfvj 思路 base64只有64個字元,因此只需要6個二進位制位來表示 實現 每3個位元組為一組湊4個base64字元。多餘乙個位元組補4個0bit位 共12位 湊成2個base64字元 多餘兩個位元組補2個bit位 共18位 湊成3個base64字元。為了知道新增...

Base64編碼 Unicode UTF 8編碼

base64編碼 64種可列印字元,表示原二進位制格式中的6bit base64編碼有一張編碼表 解碼的時候也用它 0 63的id對映到可列印字元 6bit 4 8bit 3,所以4個字元一組,表示3個8 bit二進位制子節 原二進位制子節數不為3個倍數時 原位元組缺1個,則編碼為3個字元 第3個字...