Base64is a representation of binary data based on 64 printable characters. Since 2 of the 6 is equal to 64, each 6 is a unit, corresponding to a printable character.
Three bites have 24 bits, corresponding to 4 Base64 units, or 3 bytes that need to be represented by 4 printable characters. It can be used as the transmission encoding for e-mail.
The printable characters in Base64 include the letter A-Z, A-Z, the number 0-9, which is 62 characters in total, and two printable symbols that differ from one system to another.
For example, in MIME (Multipurpose Mail Extension), the 64 printable characters used by Base64
A-za-z: 26 Letters of the case
0-9: Add 10 numbers
+: Plus
/: Slash
Total 64 characters, equals "=" used as suffix
The corresponding conversion relationship is
0-63:a-za-z0-9+/
When converting, the data of three bytes is placed in a 24bit buffer successively, and the first byte is the high. If the data is less than 3byte, the remaining bits in the buffer are filled with 0. Then, each time a 6 (because 26=64) bit is removed, the characters in the abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789+/are selected as the encoded output according to their values. Continue until the full input data conversion is complete.
When the original data length is not an integer multiple of 3, if the last input data is left, add 2 "=" after the encoding result, and if there are two input data left, add 1 "=" after the encoding result, and if there is no data left, do not add anything, so as to guarantee the correctness of the data restoration.
Example Analysis:
Code: "Lailaiji"
Find the corresponding relationship by checking the ASCII table
l:0x4c | a:0x61 | i:0x69 | l:0x6c | j:0x6a
So the conversion to binary is: 0100 1100, 0110 0001, 0110 1001, 0110 1100, 0110 0001, 0110 1001, 0110 1010, 0110 1001
The first step: take three bytes of data, namely: 0100 1100, 0110 0001, 0110 1001, and then remove three bits from this 6 byte is 010011, at the highest bit to supplement two bits 00 make it 1 byte, that is 0001 0011, the remaining 18 bits are also so loop, Eventually these three bytes will be expanded to 4 bytes, namely: 0001 0011, 0000 0110, 0000 0101, 0010 1001
The second step, repeat the first step from the remaining byte sequence, and go to less than 3 bytes
In the third step, the remaining bytes are: 0110 1010,0110 1001 less than 3 bytes, need to be replenished from low to 0, that is, 0110 1010,0110 1001,0000 0000 Repeat the first step, get: 0001 1010,0010 0110, 0010 0100, 0000 0000,
After the subsequent operation, we will get a set of bit sequences:
0001 0011, 0000 0110, 0000 0101, 0010 1001
0001 1011,0000 0110, 0000 0101, 0010 1001
0001 1010,0010 0110, 0010 0100, 0000 0000
Convert to decimal: 19,6,5,41,27,6,5,41,26,38,36,0
The corresponding characters are: T,g,f,p,b,g,f,p,a,m,k,a
In particular, the last byte 0000 0000 is 0x00, by looking at table A, because the last 8 bits are supplementary, so it should be converted to = number, not a
Therefore: The end result is: tgfpbgfpamk=
PHP Implementation:
Encode ($input); echo "encode:", $output. php_eol; $output = $obj->decode ($output); echo "Decode:", $output. Php_eol;class mybase64{private $_table = Array ();p rivate $_revtable = Array ();p ublic function __construct () {$this->_ Inittable ();} Public function decode ($string) {$orign _len = strlen ($string); $j = 0; $ret = null;for ($i =0; $i < $orign _len; $i +=4) {$CHR 1 = $this->GETREVCHR ($string [$i]), $CHR 2 = $this->getrevchr ($string [$i +1]), $CHR 3 = $this->GETREVCHR ($string [$ I+2]); $CHR 4 = $this->getrevchr ($string [$i +3]); $_chr1 = $CHR 1<<2 | ($CHR 2&0x3f) >>4;$_chr2 = ($chr 2&0x0f) <<4 | ($CHR 3&0xfc) >>2;$_chr3 = ($chr 3&0x03) <<6 | $CHR 4; $ret. = Chr ($_CHR1); $ret. = Chr ($_CHR2); $ret. = Chr ($_CHR3);} $ret = RTrim ($ret); return $ret;} Private Function GETREVCHR ($CHR) {if (Isset ($this->_revtable[$CHR]) {return $this->_revtable[$CHR];} Else{return 0;}} Public Function _decode ($string) {$orign _len = strlen ($string); $de = null; $kv = Array_flip ($this->_table$b = null;for ($i = 0; $i < $orign _len; $i + +) {$CHR = $string [$i];if ($chr! = ' = ') {$c = $kv [$CHR];} else{$c = chr (0);} printf ("%x", $c); $b [] = Pack (' C ', $c); echo Php_eol;} for ($i = 0; $i < count ($b), $i +=3) {$ch 1 = ($b [$i]<<2) | ($b [$i +1]>>4); $ch 2 = ($b [$i +1]<<4) | ($b [$i +2]>>2); $ch 3 = ($b [$i +2]<<6) | ($b [$i +3]);p rintf ('%08b,%08b,%08b ', $ch 1, $ch 2, $ch 3), Echo php_eol;printf ('%08b,%08b ', ($b [$i]<<2), ($b [$i +1] >>4)); echo Php_eol;}} Public function encode ($string) {$orign _len = strlen ($string), $len = Intval (ceil ($orign _len/3)); $bin = Pack (' A '. $len, $string); $gen = Null;for ($i =0; $i < $len; $i +=3) {$ch 1 = ord ($bin [$i]) >> 2; $ch 2 = (ord ($bin [$i]) &am P 0X03) << 4) | (Ord ($bin [$i +1]) >> 4); $ch 3 = ((Ord ($bin [$i +1]) & 0x0F) << 2) | ((Ord ($bin [$i +2]) & 0xC0) >> 6), $ch 4 = Ord ($bin [$i +2]) & 0x3F; $gen. = $this->_table[$ch 1]; $gen. = $this-& gt;_table[$ch 2]; $gen. = $this->_table[$ch 3]; $gen. = $this_table[$ch 4];} if ($orign _len-$len) {$gen = substr ($gen, 0,-abs ($orign _len-$len)), for ($i =0; $i < $len-$orign _len; $i + +) {$gen. = ' = ';}} return $gen;} Private Function _inittable () {$tbl = array (); for ($i =ord (' A '); $i <=ord (' Z '); $i + +) {$tbl [] = Chr ($i);} For ($i =ord (' a '), $i <=ord (' z '), $i + +) {$tbl [] = Chr ($i);} For ($i =ord (' 0 '); $i <=ord (' 9 '); $i + +) {$tbl [] = Chr ($i);} $tbl [] = ' + '; $tbl [] = '/'; $reverse = Array_flip ($TBL); $this->_table = $tbl; $this->_re vtable = $reverse;}}