我们知道计算机中的文件可以分为两种,一种是人眼可读的文本文件,一种是肉眼不可读的二进制文件。一般来说,如果用文本编辑器打开二进制文件,会显示乱码,而且二进制文件和文本文件的存储和传输方式不同。那么有什么办法可以将二进制文件转换成文本文件进行传输或存储呢?答案是肯定的。这种编码方式就是我们今天要说的Base64编码。Base64及其编码原理Base64是一种将二进制编码格式转换为文本编码的形式。我们知道二进制编码是0和1的形式,它的单位通常是一个字节,即8bits,每一位代表0或1。文本编码有很多种格式。最早也是最简单的编码格式是ASCII编码。ASCII编码的全称是AmericanStandardCodeforInformationInterchange,即美国信息交换标准码。主要表达一些常用的西欧编码。特点。ASCII的编码范围是0x00-0x7F,用十进制表示是0-127,共128个字符,正好是7bits表示的范围。TheASCIIcodecontains33controlcharactersand95printablecharacters,asfollows:ASCIICodeMeaningASCIICodeMeaningHexadecimalDecimalBinaryHexadecimalDecimalBinary0x0000NULEmpty0x40641000000@0x0111SOH标题开始0x41651000001A0x02210STX文字开始0x42661000010B0x03311ETX文字结束0x43671000011C0x044100EOT传输结束0x44681000100D0x055101ENQ询问字符0x45691000101E0x066110ACK承认0x46701000110F0x077111BEL报警0x47711000111G0x0881000BS退一格0x48721001000H0x0991001HT横向制表0x49731001001I0x0A101010LF换行0x4A741001010J0x0B111011VT垂直制表0x4B751001011K0x0C121100FF走纸控制0x4C761001100L0x0D131101CR回车0x4D771001101M0x0E141110SO移位输出0x4E781001110N0x0F151111SI移位输入0x4F791001111O0x101610000DLE数据链路转义0x50801010000P0x111710001DC1设备控制10x51811010001Q0x121810010DC2设备控制20x52821010010R0x131910011DC3设备控制30x53831010011S0x142010100DC4设备控制40x54841010100T0x152110101NAK否定0x55851010101U0x162210110SYN空转同步0x56861010110V0x172310111ETB信息组传送结束0x57871010111W0x182411000CAN作废0x58881011000X0x192511001EM纸尽0x59891011001Y0x1A2611010SUB换置0x5A901011010Z0x1B2711011ESC换码0x5B911011011[0x1C2811100FS文字分隔符0x5C921011100\0x1D2911101GS组分隔符0x5D931011101]0x1E3011110RS记录分隔符0x5E941011110^0x1F3111111US单元分隔符0x5F951011111_0x2032100000(space)0x60961100000`0x2133100001!0x61971100001a0x2234100010”0x62981100010b0x2335100011#0x63991100011c0x2436100100$0x641001100100d0x2537100101%0x651011100101e0x2638100110&0x661021100110f0x2739100111'0x671031100111g0x2840101000(0x681041101000h0x2941101001)0x691051101001i0x2A42101010*0x6A1061101010j0x2B43101011+0x6B1071101011k0x2C44101100,0x6C1081101100l0x2D45101101-0x6D1091101101m0x2E46101110.0x6E1101101110n0x2F47101111/0x6F1111101111o0x304811000000x701121110000p0x314911000110x711131110001q0x325011001020x721141110010r0x335111001130x731151110011s0x345211010040x741161110100t0x355311010150x751171110101u365411011060x761181110110v0x375511011170x771191110111w0x385611100080x781201111000x0x395711100190x791211111001y0x3A58111010:0x7A1221111010z0x3B59111011;0x7B1231111011{0x3C60111100<0x7C1241111100\0x3D61111101=0x7D1251111101}0x3E62111110>0x7E1261111110~0x3F63111111?0x7F1271111111DEL删除Base64就是从ASCII编码中选出64个字符,映射到二进制中的一个8位的字节,也就是64在Base64中的含义。为什么选择ASCII编码?这是因为ASCII编码是最早的编码形式,几乎所有的计算机应用程序都完全支持它,数据传输时不会有内容转换,非常安全。当然,Base64编码也有多种编码形式。例如,在MIME中,Base64选择A-Z、a-z、0-9共62个字符,加上另外两个可选字符,组成64个编码字符。64个字符的二进制表示为6bits,常用的二进制用一个字节表示,即8bits。那么问题来了,8bits的二进制如何用6bits的Base64字符表示呢?很简单,我们只需要将三个8bits连接到24bits,就可以用四个Base64来表示了。为什么必须进行二进制转换?这是因为互联网中有些传输协议只支持某些特定的字符集,不支持其他的字符集。例如,常用的电子邮件附件。因为SMTP协议最初是为了支持7位ASCII字符而设计的,所以如果我们要传输文件,我们需要在传输文件之前对文件进行编码。另外,Base64的一个用法是在HTML中将图片嵌入到网页中,从而实现图片的显示。Base64虽然很好用,但是由于只能使用6bits的字符映射集,会造成数据映射丢失,导致二进制文件编码后文件体积变大的弊端。Base64的变体Base64简单来说就是位与位之间的映射,所以映射方式肯定不止一种。让我们看看Base64编码的各种变体。一般来说,前62位基本相同。不同之处在于最后两个字符,以及用于填充的字符(在某些协议中可能是强制性的,或在其他协议中被删除)。下表是Base64编码的常见变体:EncodingNameEncodingCharacterEncodingCharacterEncodingCharacter62nd63rdCompletionCharacterRFC1421:Base64forPrivacy-EnhancedMail(deprecated)+/=mandatoryRFC2045:Base64transferencodingforMIME+/=mandatoryRFC2152:Base64forUTF-7+/NoRFC3501:Base64encodingforIMAPmailboxnames+,NoRFC4648:base64(standard)+/=optionalRFC4648:base64url(URL-andfilename-safestandard)-_=optionalRFC4880:Radix-64forOpenPGP+/=mandatoryBase64编码详解上一节我们讲了Base64编码的基本原理和一些常见的变体,那么映射是如何完成的呢?本节我们将以Base64RFC4648的标准形式为例进行详细讲解。RFC4648选择字符+和/作为编码中的位62和63,并选择字符=作为完成字符。首先来观察一下RFC4648的映射表:索引二进制字符索引二进制Char索引二进制Char索引二进制Char0000000A16010000Q32100000g48110000w1000001B17010001R33100001h49110001x2000010C18010010S34100010i50110010y3000011D19010011T35100011j51110011z4000100E20010100U36100100k5211010005000101F21010101V37100101l5311010116000110G22010110W38100110m5411011027000111H23010111X39100111n5511011138001000I24011000Y40101000o5611100049001001J25011001Z41101001p57111001510001010K26011010a42101010q58111010611001011L27011011b43101011r59111011712001100M28011100c44101100s60111100813001101N29011101d45101101t61111101914001110O30011110e46101110u62111110+15001111P31011111f47101111v63111111/补全符=我们来以单词man为例,来观察一下Base64的编码流程。Thewordmanisrepresentedby77,97and110inASCII,andconvertedintobinaryis01001101,01100001and01101110.Combiningtheabovethreebinarynumberstogetherbecomes:010011010110000101101110,atotalof24-bit,selectthecorrespondingcharacterfromtheabovetable,sowecangetmanafterbase64encoding:TWFu.Intheaboveexample,manisexactly3characters,thatis,24bits,whichcanbecompletelyrepresentedbybase64.如果我们只有ma这两个字符,我们应该如何对它们进行编码?如上,ma的二进制值为01001101、01100001,组合为0100110101100001。但是上面的bits只有16bits,因为一个base64是6bits,所以可以用3个base64来表示,因为原来的bits是少两个,所以用0补全:0100110101100001+00=010011010110000100。010011010110000100转成base64就是TWE,因为base64编码需要4个字符,所以最后一个字符用=补全,也就是说me在base64后变成了TWE=。综上所述,以上就是Base64的基本含义和转换规则。事实上,协议非常简单。将需要转换的数据转换成二进制,再根据转换表转换完成。本文已收录于http://www.flydean.com/18-base64-encoding/最流行的解读,最深刻的干货,最简洁的教程,很多你不知道的小技巧等着你去探索!欢迎关注我的公众号:《程序那些事儿》,懂技术,更懂你!
