[Turn] Detailed explanation of Base64 algorithm

Original link: https://blog.csdn.net/robertcpp/article/details/51628647

  The complete BASE64 definition can be found in RFC 1421 and RFC 2045 . The encoded data is slightly longer than the original data, 4/3 of the original. In e-mail, according to RFC 822 , every 76 characters, you need to add a carriage return and line feed. It can be estimated that the length of the encoded data is about 135.1% of the original length.

  When converting, put three bytes of data into a 24-bit buffer one after another, and the first byte occupies the high position. If the data is less than 3 bytes, the remaining bits in the buffer are filled with 0. Then, take out 6 (because 2 6 =64) bits each time, and select ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/the characters in it according to their values ​​as the encoded output. Continue until all input data conversions are complete.

  When the length of the original data is not an integer multiple of 3, if there is one input data left at the end (the original data is in groups of 3, and one is left), add 2 "=" after the encoding result; if there are two inputs left at the end Data (original data in groups of 3, the remaining two), add 1 "=" after the encoding result; if there is no data left, do not add anything, so as to ensure the correctness of data restoration.

example

For example, a quote from Thomas Hobbes ' Leviathan :

Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a lust of the mind, that by a perseverance of delight in the continued and indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure.

After Base64 encoding it becomes:

TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz
IHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2Yg
dGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGlu
dWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRo
ZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=
  • Code "Man"
text M a n
ASCII encoding 77 97 110
binary bit 0 1 0 0 1 1 0 1 0 1 1 0 0 0 0 1 0 1 1 0 1 1 1 0
index 19 22 5 46
Base64 encoding T W F u

In this example, the Base64 algorithm encodes three characters into 4 characters

Base64 index table:

Numerical value character   Numerical value character   Numerical value character   Numerical value character
0 A 16 Q 32 g 48 w
1 B 17 R 33 h 49 x
2 C 18 S 34 i 50 and
3 D 19 T 35 j 51 with
4 E 20 U 36 k 52 0
5 F 21 V 37 l 53 1
6 G 22 W 38 m 54 2
7 H 23 X 39 n 55 3
8 I 24 AND 40 O 56 4
9 J 25 WITH 41 p 57 5
10 K 26 a 42 q 58 6
11 L 27 b 43 r 59 7
12 M 28 c 44 s 60 8
13 N 29 d 45 t 61 9
14 O 30 e 46 u 62 +
15 P 31 f 47 v 63 /

  如果要编码的字节数不能被3整除,最后会多出1个或2个字节,那么可以使用下面的方法进行处理:先使用0字节值在末尾补足,使其能够被3整除,然后再进行Base64的编码。在编码后的Base64文本后加上一个或两个'='号,代表补足的字节数。也就是说,当最后剩余一个八位字节(一个byte)时,最后一个6位的Base64字节块有四位是0值,最后附加上两个等号;如果最后剩余两个八位字节(2个byte)时,最后一个6位的base字节块有两位是0值,最后附加一个等号。 参考下表:

文本(1 Byte) A    
二进制位 0 1 0 0 0 0 0 1                                
二进制位(补0) 0 1 0 0 0 0 0 1 0 0 0 0                        
Base64编码 Q Q    
文本(2 Byte) B C  
二进制位 0 1 0 0 0 0 1 0 0 1 0 0 0 0 1 1     x x x x x x
二进制位(补0) 0 1 0 0 0 0 1 0 0 1 0 0 0 0 1 1 0 0 x x x x x x
Base64编码 Q k M  

public
class Base64 { /** * 将原始数据编码为base64编码 */ static public char[] encode(byte[] data) { char[] out = new char[((data.length + 2) / 3) * 4]; for (int i = 0, index = 0; i < data.length; i += 3, index += 4) { boolean quad = false; boolean trip = false; int val = (0xFF & (int) data[i]); val <<= 8; if ((i + 1) < data.length) { val |= (0xFF & (int) data[i + 1]); trip = true; } val <<= 8; if ((i + 2) < data.length) { val |= (0xFF & (int) data[i + 2]); quad = true; } out[index + 3] = alphabet[(quad ? (val & 0x3F) : 64)]; val >>= 6; out[index + 2] = alphabet[(trip ? (val & 0x3F) : 64)]; val >>= 6; out[index + 1] = alphabet[val & 0x3F]; val >>= 6; out[index + 0] = alphabet[val & 0x3F]; } return out; } /** * 将base64编码的数据解码成原始数据 */ static public byte[] decode(char[] data) { int len = ((data.length + 3) / 4) * 3; if(data.length > 0 && data[data.length - 1] == '=') --len; if(data.length > 1 && data[data.length - 2] == '=') --len; byte[] out = new byte[len]; int shift = 0; int accum = 0; int index = 0; for(int ix = 0; ix < data.length; ix++) { int value = codes[data[ix] & 0xFF]; if(value >= 0) { accum <<= 6; shift += 6; accum |= value; if(shift >= 8) { shift -= 8; out[index++] = (byte)((accum >> shift) & 0xff); } } } if(index != out.length) throw new Error("miscalculated data length!"); return out; } static private char[] alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".toCharArray(); static private byte[] codes = new byte[256]; static { for (int i = 0; i < 256; i++) codes[i] = -1; for (int i = 'A'; i <= 'Z'; i++) codes[i] = (byte) (i - 'A'); for (int i = 'a'; i <= 'z'; i++) codes[i] = (byte) (26 + i - 'a'); for (int i = '0'; i <= '9'; i++) codes[i] = (byte) (52 + i - '0'); codes['+'] = 62; codes['/'] = 63; } public static void main(String[] args) throws Exception { // Encrypt into base64 String strSrc = "Forest" ; String strOut = new String(Base64.encode(strSrc.getBytes())); System.out.println(strOut); String strOut2 = new String(Base64.decode(strOut.toCharArray())); System.out.println(strOut2); } }

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325862204&siteId=291194637