Related recommendations:

  • Android custom View | distortion effect
  • Android custom View | sign out effect
  • The Android source code to read | Handler

0. Thanks

  • Base64 algorithm coding process and principle
  • Base64 encoding and decoding principle in detail

1. An overview of the

  • In the mail age, there are some invisible characters in the mail, such as newline characters, tabs and so on. During the mail transmission, some

The router or some DNS will take care of the invisible characters, and it will be a mess to reach the recipient. So people thought, why don’t we just map these invisible and unprintable characters to visible characters?

  • So there’s this Base64 algorithm. Base64 is not strictly an encryption algorithm. It simply maps binary data into 64 printable characters. Although it is not clear text, it can be restored according to the encoding method, so it is only an encoding method.

2. The coding

  • 64 printable characters, upper case A-Z, lower case A-z, numbers 0-9, total 26+26+10=62, plus+/Let’s make it 64.
Serial number character Serial number character Serial number character Serial number character
00 A 16 Q 32 g 48 w
01 B 17 R 33 h 49 x
02 C 18 S 34 i 50 y
03 D 19 T 35 j 51 z
04 E 20 U 36 k 52 0
05 F 21 V 37 l 53 1
06 G 22 W 38 m 54 2
07 H 23 X 39 n 55 3
08 I 24 Y 40 o 56 4
09 J 25 Z 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 /
  • We know that all the data in the network is transmitted in binary, so given a piece of data, we need to convert it into one of the above 64,

Since 2^6=64, we took every six bits of the binary data, mapped it to the table above, and so on and so forth, we got our Base64 encoding.

  • On the other hand, in computers, every eight bits is a Byte, so 24 bits in three bytes map exactly four

Base64 encoding. Well, if I use base64 encoding to encode a file that was originally three bytes, then it becomes four characters, eight bits per character, or 32 bits, instead of 24 bits ->32 bits, the amount of data has increased! Yeah, it’s a third bigger. So, with Base64, it’s four thirds the size.

  • In actual encoding, the number of characters in our text is not necessarily 8, and the total number of bits is not necessarily a multiple of 6. so

There are the following agreements:

  • At the end of the text, the remaining two characters are: 2*8=16bit, 16%6=4, the remaining four bits are filled with a =
  • At the end of the text, the remaining 1 character: 1*8=8bit, 8%6=2, the remaining 2 bits complement 2 =

Example:

  • Base64 encodes strings that are multiples of 3 (N*8%, 6=0)
P h p01110000   01101000  011100006A segmentation:011100  000110  100001 110000The corresponding10Hexadecimal values:28      6       33     48The corresponding characters of Base64 are C G H WCopy the code
  • The base64 encoding is performed on the character string with N*8%, 6=2, that is, the remaining two characters
R a n L01110010 01100001 01101110 011011006A segmentation:011100  100110 000101 101110  011011  000000XXXXXX XXXXXX corresponding10Hexadecimal values:28      38    5       46    27      0= = The corresponding base64 characters are c M F U B A = =Copy the code
  • The base64 encoding is performed for the character string with N*8%, 6=4, that is, the remaining 1 character
H a C k e01101000  01100001  01100011  01101011   011001016A segmentation:011010  000110  000101  100011  011010  110110  0101 00XXXXXX corresponding10Hexadecimal values:26       6      5       35      26      54       20= Corresponding to base64 characters: A G F J A2        U         =
Copy the code

3. The decoding

Knowing the principle of coding, decoding is easy. It’s the reverse. Probably is:

  • According to the code table, find the corresponding decimal number,
  • And then we base the number,
  • Concatenate all the binary numbers in eight bits to get the ASCII value.

4. Talk is cheap show me the code!

  • Coding, know the principle, coding is easy to implement, as follows (Java version) :
private static final char[] baseChars = {
        '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'.'+'.'/'};/** * Base64 encoding *@paramS string *@returnResults the * /
    public static String enCode64(String s) {
        int index = 0;
        StringBuilder strBuff = new StringBuilder();
        StringBuilder resultBuff = new StringBuilder();
        while (true) {
            // Whether to end
            if (index == -1) {
                switch (s.length()*8%6) {
                    case 2:
                        resultBuff.append('=').append('=');
                        break;
                    case 4:
                        resultBuff.append('=');
                        break;
                }
                break;
            }
            // Determine whether zeros need to be added
            if (index>=s.length()) {
                int zeroCount = 6 - strBuff.length();
                for (int i = 0; i < zeroCount; i++) {
                    strBuff.append('0');
                }
                index = -1;
            }
            // Update the binary buffer
            if (strBuff.length()<6) {
                strBuff.append(getBitStr(s.charAt(index++)));
            }
            // Take 6 characters from the buffer
            String temp2 = strBuff.substring(0.6);
            int temp10 = Integer.parseInt(temp2, 2);
            resultBuff.append(baseChars[temp10]);
            strBuff.delete(0.6);
        }
        return resultBuff.toString();
    }

    /** * get the corresponding character of the ASCII binary sequence * 8 bits, before the complement zero *@paramI character *@returnBinary sequence */
    public static String getBitStr(char i) {
        int ascii = (int) i;
        // Where 0 means to fill in zeros instead of Spaces, and 8 means to fill in at least 8 bits
        StringBuilder s = new StringBuilder(Integer.toBinaryString(ascii));
        if (s.length()<8) {
            int zeroCount = 8 - s.length();
            for (int j = 0; j < zeroCount; j++) {
                s.insert(0.'0'); }}return s.toString();
    }
Copy the code

You can just use it. I’ve tested it all. On the Java platform, sun’s package is generally used to do base64 codec, as follows:

    public static String encode(byte[] data){
        return new sun.misc.BASE64Encoder().encode(data);
    }
Copy the code
  • Decoding. Decoding is the reverse process
    /** * Base64 decodes *@paramS encoded base64 *@returnResults the * /
    public static String decode(String s) {
        int index = 0;
        StringBuilder strBuff = new StringBuilder();
        StringBuilder resultBuff = new StringBuilder();
        while (true) {
            / / zero padding
            if (index==s.length() || s.charAt(index)=='=') {
                int zeroCount = 8 - strBuff.length();
                for (int i = 0; i < zeroCount; i++) {
                    strBuff.append('0');
                }
                index = -1;
            }
            // Update the buffer character
            while(index! = -1 && strBuff.length()<8 && index<s.length()) {
                int chatIndex = getCharIndexInBaseChars(s.charAt(index++));
                strBuff.append(get6BitStr(chatIndex));
            }
            // Take 8 characters from the buffer
            String temp2 = strBuff.substring(0.8);
            int temp10 = Integer.valueOf(temp2,2);
            resultBuff.append((char)temp10);
            strBuff.delete(0.8);
            // Determine whether to end
            if (index==-1)
                break;
        }
        return resultBuff.toString().trim();
    }
    /** * gets a character at position * in the encoding table@paramI character *@returnNo. * /
    private static int getCharIndexInBaseChars(char i) {
        int ascii = (int) i;
        if (ascii == 43) / / '+'
            return 62;
        else if (ascii == 47) / / '/'
            return 63;
        else if (ascii>=48 && ascii<=57) / / 0-9
            return ascii+4;
        else if (ascii>=65 && ascii<=90) // A-Z
            return ascii-65;
        else if (ascii>=97 && ascii<=122) // a-z
            return ascii-71;
        else
            return -1;
    }
    private static String get6BitStr(int ascii) {
        StringBuilder s = new StringBuilder(Integer.toBinaryString(ascii));
        if (s.length()<6) {
            int zeroCount = 6 - s.length();
            for (int j = 0; j < zeroCount; j++) {
                s.insert(0.'0'); }}return s.toString();
    }
Copy the code
  • In general Java decoding is also through the Sun package:
public static byte[] decode(String str) {
        byte[] bt = null;
        try {
            sun.misc.BASE64Decoder decoder = new sun.misc.BASE64Decoder();
            bt = decoder.decodeBuffer(str);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return bt;
    }
Copy the code

The full code is here


Code word is not easy, convenient if the quality of three even, or pay attention to my public number technology sauce, focus on Android technology, not regularly push fresh articles, if you have a good article to share with you, welcome to pay attention to contribute!