一、什麼是org.apache.commons.codec?
org.apache.commons.codec是一組對數據編碼進行處理的Java包,它提供了多種常見的編碼方法,例如:Base64、URL、Hex、Quoted-printable等等。它不僅僅提供編碼的方法,還提供了一些與編碼有關的工具類和一些擴展的編碼類型,本篇文章將重點關注於Base64編碼的實現細節,以及Hex編碼和URL編碼的區別。並且提供一些代碼示例介紹。
二、Base64編碼實現細節
Base64是一種將任意二進位數據以文本形式進行編碼的方法, Base64對於二進位數據的處理能力非常強大,它可以編碼任何字符集中的任何字元,並且編碼後的結果都可以上傳或者傳輸,但是編碼結果的文本長度會比原始二進位數據長度大。Base64編碼的實現細節通常需要包括以下幾點:
1、編碼表的生成
public static final byte[] ENCODE_TABLE = {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3',
'4', '5', '6', '7', '8', '9', '+', '/'
};
2、剩餘位元組的計算
Base64每次對指定長度的數據編碼時,需要考慮最後剩餘的位元組數,一般會在最後添加1至2個「=」(即Padding),使編碼後的數據長度滿足4的倍數,例如:如果最後剩餘3個位元組,則需要添加1位元組的Padding;如果最後剩餘2個位元組,則需要添加2位元組的Padding。這裡是以byte[]為例進行計算,實際上涉及到其他類型時需要對應調整。
if (remaining == 0) {
encoded[outputIndex++] = ENCODE_TABLE[ buffer[0] >> 2 ];
encoded[outputIndex++] = ENCODE_TABLE[ (buffer[0] & 0x03) <> 2 ];
encoded[outputIndex++] = ENCODE_TABLE[ ( (buffer[0] & 0x03) <> 4 ) ];
encoded[outputIndex++] = ENCODE_TABLE[ (buffer[1] & 0x0f) <> 2 ];
encoded[outputIndex++] = ENCODE_TABLE[ ( (buffer[0] & 0x03) <> 4 ) ];
encoded[outputIndex++] = ENCODE_TABLE[ ( (buffer[1] & 0x0f) <> 6 ) ];
encoded[outputIndex++] = ENCODE_TABLE[ buffer[2] & 0x3f ];
}
3、將「=」 Padding 去除
Base64編碼的結果中可能會包含1至2個「=」字元,這是通過在最後補充數據位元組的方式來實現數據長度補齊的,但也會使得編碼結果的長度增加。因此,對於某些應用場景有去除「=」字元的需求。例如:當使用SMTP發送郵件時,Base64編碼的數據傳輸必須考慮行長度的限制,經由信道進行數據傳輸時還需考慮二進位數據中可能存在像”.”這樣的特殊字元,所以SMTP服務通常會對每行數據進行截斷和連接。去掉Base64編碼結果中的「=」字元可以有效的增加數據字元的密度,減少數據在網路傳輸中帶寬的消耗。
public static byte[] decode(String source, boolean removePadding) {
byte[] data = decode(source);
if (removePadding) {
int paddingCount = 0;
for (int i = data.length - 1; i >= 0; i--) {
if (data[i] == '=') {
paddingCount++;
} else {
break;
}
}
if (paddingCount > 0) {
byte[] temp = new byte[data.length - paddingCount];
System.arraycopy(data, 0, temp, 0, temp.length);
return temp;
}
}
return data;
}
三、Hex編碼和URL編碼的區別
雖然Hex和URL編碼與Base64編碼類似,但是它們的具體實現方式不同,也有不同的應用場景。
1、Hex編碼
Hex編碼是一種將二進位數據轉化為十六進位字元串的方法。Hex編碼常使用在各種數據存儲和傳輸場景,例如將一個電子郵件地址的發件人、收件人、主題和正文數據轉換為十六進位字元串。Hex編碼還可以使得程序更方便的處理、存儲和傳輸二進位數據,因此在某些極端情況下,例如程序進行加密解密時也非常常見。
String result = Hex.encodeHexString( byteArray );
byte[] byteArray = Hex.decodeHex( result.toCharArray() );
2、URL編碼
URL編碼和Base64編碼一樣,是一種將任意二進位數據轉化為字符集合的方法,但和Base64不同的是,URL編碼在編碼過程中要將一些具有特殊含義的字元,例如:「/」,「?」,「=」等字元換成其他字元以實現編碼,這樣可以保證編碼數據和URL之間沒有任何的衝突,也使得URL編碼在數據存儲和傳輸的場景中更適用並且更安全。
String source = "http://www.google.com";
String result = URLEncoder.encode( source, StandardCharsets.UTF_8.toString() );
String result = URLDecoder.decode( result, StandardCharsets.UTF_8.toString() );
原創文章,作者:KXJF,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/138353.html