Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法。可查看RFC2045~RFC2049,上面有MIME的详细规范。
Base64,就是包括小写字母a-z、大写字母A-Z、数字0-9、符号"+"、"/"一共64个字符的字符集,(任何符号都可以转换成这个字符集中的字符,这个转换过程就叫做base64编码。
Base64编码是从二进制到字符的过程,可用于在HTTP环境下传递较长的标识信息。采用Base64编码具有不可读性,需要解码后才能阅读。
Base64由于以上优点被广泛应用于计算机的各个领域,然而由于输出内容中包括两个以上“符号类”字符(+, /, =),不同的应用场景又分别研制了Base64的各种“变种”。为统一和规范化Base64的输出,Base62x被视为无符号化的改进版本。
简介
标准的Base64并不适合直接放在URL里传输,因为URL编码器会把标准Base64中的“/”和“+”字符变为形如“%XX”的形式,而这些“%”号在存入数据库时还需要再进行转换,因为ANSI SQL中已将“%”号用作通配符。
为解决此问题,可采用一种用于URL的改进Base64编码,它在末尾填充'='号,并将标准Base64中的“+”和“/”分别改成了“-”和“_”,这样就免去了在URL编解码和数据库存储时所要作的转换,避免了编码信息长度在此过程中的增加,并统一了数据库、表单等处对象标识符的格式。
另有一种用于正则表达式的改进Base64变种,它将“+”和“/”改成了“!”和“-”,因为“+”,“*”以及前面在IRCu中用到的“[”和“]”在正则表达式中都可能具有特殊含义。
此外还有一些变种,它们将“+/”改为“_-”或“._”(用作编程语言中的标识符名称)或“.-”(用于XML中的Nmtoken)甚至“_:”(用于XML中的Name)。
Base64要求把每三个8Bit的字节转换为四个6Bit的字节(3*8 = 4*6 = 24),然后把6Bit再添两位高位0,组成四个8Bit的字节,也就是说,转换后的字符串理论上将要比原来的长1/3。
Base64编码的意义是将所有字符的表达集中在一些常见的、可见的字符集上。而Base64编码按照字符集中字符的顺序是否改变可分为:原始Base64编码和私有Base64编码。
原始base64编码是使用原始Base64表的字符顺序的编码, 私有Base64编码是使用了私有Base64表(改变了原始表字符顺序的编码)。原始Base64编码可利用Python的内建模块Base64直接进行base64编解码,而私有Base64编码无法直接使用Python的内建模块。
规则
关于这个编码的规则:
①.把3个字节变成4个字节。
②每76个字符加一个换行符。
③.最后的结束符也要处理。
例子1
转换前 11111111, 11111111, 11111111 (二进制)
转换后 00111111, 00111111, 00111111, 00111111 (二进制)
上面的三个字节是原文,下面的四个字节是转换后的Base64编码,其前两位均为0。
原理
转码过程例子:
3*8=4*6
内存1个字节占8位
转前: s 1 3
先转成ascii:对应 115 49 51
2进制: 01110011 00110001 00110011
6个一组(4组) 011100110011000100110011
然后才有后面的 011100 110011 000100 110011
然后计算机一个字节占8位,不够就自动补两个高位0了
所以有了高位补0
科学计算器输入 00011100 00110011 00000100 00110011
得到 28 51 4 51
查对下照表 c z E z
先以“迅雷下载”为例: 很多下载类网站都提供“迅雷下载”的链接,其地址通常是加密的迅雷专用下载地址。
其实迅雷的“专用地址”也是用Base64"加密"的,其过程如下:
一、在地址的前后分别添加AA和ZZ
二、对新的字符串进行Base64编码
另:Flashget的与迅雷类似,只不过在第一步时加的“料”不同罢了,Flashget在地址前后加的“料”是[FLASHGET]而QQ旋风的干脆不加料,直接就对地址进行Base64编码了
应用
Base64编码可用于在HTTP环境下传递较长的标识信息。例如,在Java Persistence系统Hibernate中,就采用了Base64来将一个较长的一个标识符(一般为128-bit的UUID)编码为一个字符串,用作HTTP表单和HTTP GET URL中的参数。
在其他应用程序中,也常常需要把二进制数据编码为适合放在URL(包括隐藏表单域)中的形式。此时,采用Base64编码不仅比较简短,同时也具有不可读性,即所编码的数据不会被人用肉眼所直接看到。
然而,标准的Base64并不适合直接放在URL里传输,因为URL编码器会把标准Base64中的“/”和“+”字符变为形如“%XX”的形式,而这些“%”号在存入数据库时还需要再进行转换,因为ANSI SQL中已将“%”号用作通配符。
为解决此问题,可采用一种用于URL的改进Base64编码,它不仅在末尾去掉填充的'='号,并将标准Base64中的“+”和“/”分别改成了“-”和“_”,这样就免去了在URL编解码和数据库存储时所要作的转换,避免了编码信息长度在此过程中的增加,并统一了数据库、表单等处对象标识符的格式。
另有一种用于正则表达式的改进Base64变种,它将“+”和“/”改成了“!”和“-”,因为“+”,“/”以及前面在IRCu中用到的“[”和“]”在正则表达式中都可能具有特殊含义。
此外还有一些变种,它们将“+/”改为“_-”或“._”(用作编程语言中的标识符名称)或“.-”(用于XML中的Nmtoken)甚至“_:”(用于XML中的Name)。
其他应用
Mozilla Thunderbird和Evolution用Base64来保密电子邮件密码
Base64 也会经常用作一个简单的“加密”来保护某些数据,而真正的加密通常都比较繁琐。
垃圾讯息传播者用Base64来避过反垃圾邮件工具,因为那些工具通常都不会翻译Base64的讯息。
在LDIF档案,Base64用作编码字串。
JavaScript版实现代码
if (!Shotgun) var Shotgun = {}; if (!Shotgun.Js) Shotgun.Js = {}; Shotgun.Js.Base64 = { _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', '+', '/' ], encode: function (bin) { var codes = []; var un = 0; un = bin.length % 3; if (un == 1) bin.push(0, 0); else if (un == 2) bin.push(0); for (var i = 2; i < bin.length; i += 3) { var c = bin[i - 2] << 16; c |= bin[i - 1] << 8; c |= bin[i]; codes.push(this._table[c >> 18 & 0x3f]); codes.push(this._table[c >> 12 & 0x3f]); codes.push(this._table[c >> 6 & 0x3f]); codes.push(this._table[c & 0x3f]); } if (un >= 1) { codes[codes.length - 1] = "="; bin.pop(); } if (un == 1) { codes[codes.length - 2] = "="; bin.pop(); } return codes.join(""); }, decode: function (base64Str) { var i = 0; var bin = []; var x = 0, code = 0, eq = 0; while (i < base64Str.length) { var c = base64Str.charAt(i++); var idx = this._table.indexOf(c); if (idx == -1) { switch (c) { case '=': idx = 0; eq++; break; case ' ': case '\n': case "\r": case '\t': continue; default: throw { "message": "\u0062\u0061\u0073\u0065\u0036\u0034\u002E\u0074\u0068\u0065\u002D\u0078\u002E\u0063\u006E\u0020\u0045\u0072\u0072\u006F\u0072\u003A\u65E0\u6548\u7F16\u7801\uFF1A" + c }; } } if (eq > 0 && idx != 0) throw { "message": "\u0062\u0061\u0073\u0065\u0036\u0034\u002E\u0074\u0068\u0065\u002D\u0078\u002E\u0063\u006E\u0020\u0045\u0072\u0072\u006F\u0072\u003A\u7F16\u7801\u683C\u5F0F\u9519\u8BEF\uFF01" }; code = code << 6 | idx; if (++x != 4) continue; bin.push(code >> 16); bin.push(code >> 8 & 0xff); bin.push(code & 0xff) code = x = 0; } if (code != 0) throw { "message": "\u0062\u0061\u0073\u0065\u0036\u0034\u002E\u0074\u0068\u0065\u002D\u0078\u002E\u0063\u006E\u0020\u0045\u0072\u0072\u006F\u0072\u003A\u7F16\u7801\u6570\u636E\u957F\u5EA6\u9519\u8BEF" }; if (eq == 1) bin.pop(); else if (eq == 2) { bin.pop(); bin.pop(); } else if (eq > 2) throw { "message": "\u0062\u0061\u0073\u0065\u0036\u0034\u002E\u0074\u0068\u0065\u002D\u0078\u002E\u0063\u006E\u0020\u0045\u0072\u0072\u006F\u0072\u003A\u7F16\u7801\u683C\u5F0F\u9519\u8BEF\uFF01" }; return bin; } };
BASH版实现代码
base64Table=(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 + /); function str2binary() { idx=0; for((i=0; i<${#str}; i++)); do dividend=$(printf "%d" "'${str:i:1}"); for((j=0;j<8;j++)); do let idx=8*i+7-j; let bin[$idx]=$dividend%2; dividend=$dividend/2; done; done; let idx=${#str}*8; for((i=0; i<appendEqualCnt*2; i++)); do let bin[$idx]=0; let idx++; done; } function calcBase64() { for((i=0; i<${#bin[*]}/6; i++)); do sum=0; for((j=0; j<6; j++)); do let idx=i*6+j; let n=6-1-j; let sum=sum+${bin[$idx]}*2**n; done; echo -n ${base64Table[$sum]}; done } declare -a bin function base64Encode() { read -p "please enter ASCII string:" str; let appendZero=${#str}*8%6; let bits=${#str}*8; appendEqualCnt=0; if [[ $appendZero -ne 0 ]]; then let appendEqualCnt=(6-$appendZero)/2; fi str2binary; calcBase64; if [[ $appendEqualCnt -eq 2 ]]; then echo -n "=="; elif [[ $appendEqualCnt -eq 1 ]]; then echo -n "="; fi echo; }
Java版实现代码
import java.util.Base64; 对于标准的Base64: 加密为字符串使用Base64.getEncoder().encodeToString(); 加密为字节数组使用Base64.getEncoder().encode(); 解密使用Base64.getDecoder().decode(); 对于URL安全或MIME的Base64,只需将上述getEncoder()getDecoder()更换为getUrlEncoder()getUrlDecoder() 或getMimeEncoder()和getMimeDecoder()即可。
PHP版实现代码
<?php $txt1=trim($_POST['text1']); $txt2=trim($_POST['text2']); $txt3=trim($_POST['text3']); $button=$_POST['button']; ?> <!DOCTYPEHTMLPUBLIC"-//W3C//DTDHTML4.0Transitional//EN"> <html> <head> <title>迅雷和FlashGet,QQ旋风地址地址转换工具</title> <metahttp-equiv="Content-Type"content="text/html;charset=gb2312"> <metacontent="迅雷,FlashGet,地址转换,"name="keywords"> </head> <body> <formname="form1"method="post"action=""> <hrsize="1"> <h3>迅雷转换</h3> <P>转换地址: <inputname="text1"value="<?phpecho$txt1;?>"type="text"style="width:516px;"/></P> <P>转换后的: <inputtype="text"value="<?php if($button=="普通地址->迅雷地址")echo"thunder://".base64_encode("AA".$txt1."ZZ"); if($button=="迅雷地址->普通地址")echosubstr(base64_decode(str_ireplace("thunder://","",$txt1)),2,-2); ?>"style="width:516px;"/></P> <P> <inputtype="submit"name="button"value="普通地址->迅雷地址"/> <inputtype="submit"name="button"value="迅雷地址->普通地址"/></P> <h3>FlashGet转换</h3> <P>FlashGet地址: <inputname="text2"value="<?phpecho$txt2;?>"type="text"style="width:516px;"/></P> <P>转换后地址: <inputtype="text"value="<?php if($button=="普通地址->FlashGet地址")echo"flashget://".base64_encode($txt2); if($button=="FlashGet地址->普通地址")echostr_ireplace("[FLASHGET]","",base64_decode(str_ireplace("flashget://","",$txt2))); ?>"style="width:516px;"/></P> <P> <inputtype="submit"value="普通地址->FlashGet地址"name="button"/> <inputtype="submit"value="FlashGet地址->普通地址"name="button"/></P> <h3>QQ旋风转换</h3> <P>QQ旋风地址: <inputname="text3"value="<?phpecho$txt3;?>"type="text"style="width:516px;"/></P> <P>转换后地址: <inputtype="text"value="<?php if($button=="普通地址->QQ旋风")echo"qqdl://".base64_encode($txt3); if($button=="QQ旋风->普通地址")echobase64_decode(str_ireplace("qqdl://","",$txt3)); ?>"style="width:516px;"/></P> <P> <inputtype="submit"value="普通地址->QQ旋风"name="button"/> <inputtype="submit"value="QQ旋风->普通地址"name="button"/></P> </form> </body> </html>
VB版实现代码
Option Explicit 'B as e64Encoding/DecodingAlgorithm 'By:DavidMidkif f(mznull@earthlink.net) ' 'Thisalgorithmsencodes and decodesdatain to B as e64 'for mat.Thisfor matisextremelymoreefficientthan 'Hexadecimalencoding. Private m_bytIndex(0 To 63) As Byte Private m_bytReverseIndex(0 To 255) As Byte Private Const k_bytEqualSign As Byte = 61 Private Const k_bytmask1 As Byte = 3 Private Const k_bytmask2 As Byte = 15 Private Const k_bytmask3 As Byte = 63 Private Const k_bytmask4 As Byte = 192 Private Const k_bytmask5 As Byte = 240 Private Const k_bytmask6 As Byte = 252 Private Const k_bytShift2 As Byte = 4 Private Const k_bytShift4 As Byte = 16 Private Const k_bytShift6 As Byte = 64 Private Const k_lMaxBytesPerLine As Long = 152 Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByVal Destination As Long, ByVal Source As Long, ByVal Length As Long) Public Function Decode64(sInput As String) As String If sInput = "" Then Exit Function Decode64 = StrConv(DecodeArray64(sInput), vbUnicode) End Function Private Function DecodeArray64(sInput As String) As Byte() Dim bytInput() As Byte Dim bytWorkspace() As Byte Dim bytResult() As Byte Dim lInputCounter As Long Dim lWorkspaceCounter As Long bytInput = Replace(Replace(sInput, vbCrLf, ""), "=", "") ReDim bytWorkspace(LBound(bytInput) To (UBound(bytInput) * 2)) As Byte lWorkspaceCounter = LBound(bytWorkspace) For lInputCounter = LBound(bytInput) To UBound(bytInput) bytInput(lInputCounter) = m_bytReverseIndex(bytInput(lInputCounter)) Next lInputCounter For lInputCounter = LBound(bytInput) To (UBound(bytInput) - ((UBound(bytInput) Mod 8) + 8)) Step 8 bytWorkspace(lWorkspaceCounter) = (bytInput(lInputCounter) * k_bytShift2) + (bytInput(lInputCounter + 2) \ k_bytShift4) bytWorkspace(lWorkspaceCounter + 1) = ((bytInput(lInputCounter + 2) And k_bytmask2) * k_bytShift4) + (bytInput(lInputCounter + 4) \ k_bytShift2) bytWorkspace(lWorkspaceCounter + 2) = ((bytInput(lInputCounter + 4) And k_bytmask1) * k_bytShift6) + bytInput(lInputCounter + 6) lWorkspaceCounter = lWorkspaceCounter + 3 Next lInputCounter Select Case (UBound(bytInput) Mod 8): Case 3: bytWorkspace(lWorkspaceCounter) = (bytInput(lInputCounter) * k_bytShift2) + (bytInput(lInputCounter + 2) \ k_bytShift4) Case 5: bytWorkspace(lWorkspaceCounter) = (bytInput(lInputCounter) * k_bytShift2) + (bytInput(lInputCounter + 2) \ k_bytShift4) bytWorkspace(lWorkspaceCounter + 1) = ((bytInput(lInputCounter + 2) And k_bytmask2) * k_bytShift4) + (bytInput(lInputCounter + 4) \ k_bytShift2) lWorkspaceCounter = lWorkspaceCounter + 1 Case 7: bytWorkspace(lWorkspaceCounter) = (bytInput(lInputCounter) * k_bytShift2) + (bytInput(lInputCounter + 2) \ k_bytShift4) bytWorkspace(lWorkspaceCounter + 1) = ((bytInput(lInputCounter + 2) And k_bytmask2) * k_bytShift4) + (bytInput(lInputCounter + 4) \ k_bytShift2) bytWorkspace(lWorkspaceCounter + 2) = ((bytInput(lInputCounter + 4) And k_bytmask1) * k_bytShift6) + bytInput(lInputCounter + 6) lWorkspaceCounter = lWorkspaceCounter + 2 End Select ReDim bytResult(LBound(bytWorkspace) To lWorkspaceCounter) As Byte If LBound(bytWorkspace) = 0 Then lWorkspaceCounter = lWorkspaceCounter + 1 CopyMemoryVarPtr (bytResult(LBound(bytResult))), VarPtr(bytWorkspace(LBound(bytWorkspace))), lWorkspaceCounter DecodeArray64 = bytResult End Function Public Function Encode64(ByRefsInput As String) As String If sInput = "" Then Exit Function Dim bytTemp() As Byte bytTemp = StrConv(sInput, vbFromUnicode) Encode64 = EncodeArray64(bytTemp) End Function Private Function EncodeArray64(ByRefbytInput() As Byte) As String On Error GoTo ErrorHandler Dim bytWorkspace() As Byte, bytResult() As Byte Dim bytCrLf(0 To 3) As Byte, lCounter As Long Dim lWorkspaceCounter As Long, lLineCounter As Long Dim lCompleteLines As Long, lBytesRemaining As Long Dim lpWorkSpace As Long, lpResult As Long Dim lpCrLf As Long If UBound(bytInput) < 1024 Then ReDim bytWorkspace(LBound(bytInput) To (LBound(bytInput) + 4096)) As Byte Else ReDim bytWorkspace(LBound(bytInput) To (UBound(bytInput) * 4)) As Byte End If lWorkspaceCounter = LBound(bytWorkspace) For lCounter = LBound(bytInput) To (UBound(bytInput) - ((UBound(bytInput) Mod 3) + 3)) Step 3 bytWorkspace(lWorkspaceCounter) = m_bytIndex((bytInput(lCounter) \ k_bytShift2)) bytWorkspace(lWorkspaceCounter + 2) = m_bytIndex(((bytInput(lCounter) And k_bytmask1) * k_bytShift4) + ((bytInput(lCounter + 1)) \ k_bytShift4)) bytWorkspace(lWorkspaceCounter + 4) = m_bytIndex(((bytInput(lCounter + 1) And k_bytmask2) * k_bytShift2) + (bytInput(lCounter + 2) \ k_bytShift6)) bytWorkspace(lWorkspaceCounter + 6) = m_bytIndex(bytInput(lCounter + 2) And k_bytmask3) lWorkspaceCounter = lWorkspaceCounter + 8 Next lCounter Select Case (UBound(bytInput) Mod 3): Case 0: bytWorkspace(lWorkspaceCounter) = m_bytIndex((bytInput(lCounter) \ k_bytShift2)) bytWorkspace(lWorkspaceCounter + 2) = m_bytIndex((bytInput(lCounter) And k_bytmask1) * k_bytShift4) bytWorkspace(lWorkspaceCounter + 4) = k_bytEqualSign bytWorkspace(lWorkspaceCounter + 6) = k_bytEqualSign Case 1: bytWorkspace(lWorkspaceCounter) = m_bytIndex((bytInput(lCounter) \ k_bytShift2)) bytWorkspace(lWorkspaceCounter + 2) = m_bytIndex(((bytInput(lCounter) And k_bytmask1) * k_bytShift4) + ((bytInput(lCounter + 1)) \ k_bytShift4)) bytWorkspace(lWorkspaceCounter + 4) = m_bytIndex((bytInput(lCounter + 1) And k_bytmask2) * k_bytShift2) bytWorkspace(lWorkspaceCounter + 6) = k_bytEqualSign Case 2: bytWorkspace(lWorkspaceCounter) = m_bytIndex((bytInput(lCounter) \ k_bytShift2)) bytWorkspace(lWorkspaceCounter + 2) = m_bytIndex(((bytInput(lCounter) And k_bytmask1) * k_bytShift4) + ((bytInput(lCounter + 1)) \ k_bytShift4)) bytWorkspace(lWorkspaceCounter + 4) = m_bytIndex(((bytInput(lCounter + 1) And k_bytmask2) * k_bytShift2) + ((bytInput(lCounter + 2)) \ k_bytShift6)) bytWorkspace(lWorkspaceCounter + 6) = m_bytIndex(bytInput(lCounter + 2) And k_bytmask3) End Select lWorkspaceCounter = lWorkspaceCounter + 8 If lWorkspaceCounter <= k_lMaxBytesPerLine Then EncodeArray64 = Left$(bytWorkspace, InStr(1, bytWorkspace, Chr$(0)) - 1) Else bytCrLf(0) = 13 bytCrLf(1) = 0 bytCrLf(2) = 10 bytCrLf(3) = 0 ReDim bytResult(LBound(bytWorkspace) To UBound(bytWorkspace)) lpWorkSpace = VarPtr(bytWorkspace(LBound(bytWorkspace))) lpResult = VarPtr(bytResult(LBound(bytResult))) lpCrLf = VarPtr(bytCrLf(LBound(bytCrLf))) lCompleteLines = Fix(lWorkspaceCounter / k_lMaxBytesPerLine) For lLineCounter = 0 To lCompleteLines CopyMemorylpResult , lpWorkSpace, k_lMaxBytesPerLine lpWorkSpace = lpWorkSpace + k_lMaxBytesPerLine lpResult = lpResult + k_lMaxBytesPerLine CopyMemorylpResult , lpCrLf, 4& lpResult = lpResult + 4& Next lLineCounter lBytesRemaining = lWorkspaceCounter - (lCompleteLines * k_lMaxBytesPerLine) If lBytesRemaining > 0 Then CopyMemorylpResult , lpWorkSpace, lBytesRemaining EncodeArray64 = Left$(bytResult, InStr(1, bytResult, Chr$(0)) - 1) End If Exit Function ErrorHandler: Er As ebytResult EncodeArray64 = bytResult End Function
C#版实现代码
直接使用.NET中的的库类函数 方法: ///<summary> ///Base64加密 ///</summary> ///<paramname="Message"></param> ///<returns></returns> publicstringBase64Code(stringMessage) { byte[]bytes=Encoding.Default.GetBytes(Message); returnConvert.ToBase64String(bytes); } ///<summary> ///Base64解密 ///</summary> ///<paramname="Message"></param> ///<returns></returns> publicstringBase64Decode(stringMessage) { byte[]bytes=Convert.FromBase64String(Message); returnEncoding.Default.GetString(bytes); }
python版实现代码
def base(string:str)->str: oldstr = '' newstr = [] base = '' base64_list = ['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', '+', '/'] #把原始字符串转换为二进制,用bin转换后是0b开头的,所以把b替换了,首位补0补齐8位 for i in string: oldstr += '{:08}'.format(int(str(bin(ord(i))).replace('0b', ''))) #把转换好的二进制按照6位一组分好,最后一组不足6位的后面补0 for j in range(0, len(oldstr), 6): newstr.append('{:<06}'.format(oldstr[j:j + 6])) #在base_list中找到对应的字符,拼接 for l in range(len(newstr)): base += base64_list[int(newstr[l], 2)] #判断base字符结尾补几个‘=’ if len(string) % 3 == 1: base += '==' elif len(string) % 3 == 2: base += '=' return base
在MIME格式的电子邮件中,base64可以用来将binary的字节序列数据编码成ASCII字符序列构成的文本。使用时,在传输编码方式中指定base64。使用的字符包括大小写字母各26个,加上10个数字,和加号“+”,斜杠“/”,一共64个字符,等号“=”用来作为后缀用途。
完整的base64定义可见 RFC1421和 RFC2045。编码后的数据比原始数据略长,为原来的4/3。在电子邮件中,根据RFC822规定,每76个字符,还需要加上一个回车换行。可以估算编码后数据长度大约为原长的135.1%。
转换的时候,将三个byte的数据,先后放入一个24bit的缓冲区中,先来的byte占高位。数据不足3byte的话,于缓冲区中剩下的Bit用0补足。然后,每次取出6个bit,按照其值选择ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/中的字符作为编码后的输出。不断进行,直到全部输入数据转换完成。
如果最后剩下两个输入数据,在编码结果后加1个“=”;如果最后剩下一个输入数据,编码结果后加2个“=”;如果没有剩下任何数据,就什么都不要加,这样才可以保证资料还原的正确性。
完结撒花
全民百科词条内容由用户共同创建和维护,不代表全民百科立场。如果您需要医学、法律、投资理财等专业领域的建议,我们强烈建议您独自对内容的可信性进行评估,并咨询相关专业人士。