base64解码编码详解

编码与解码

54人已加入

描述

  Base64编码是从二进制到字符的过程,可用于在HTTP环境下传递较长的标识信息。例如,在Java Persistence系统Hibernate中,就采用了Base64来将一个较长的唯一标识符(一般为128-bit的UUID)编码为一个字符串,用作HTTP表单和HTTP GET URL中的参数。在其他应用程序中,也常常需要把二进制数据编码为适合放在URL(包括隐藏表单域)中的形式。此时,采用Base64编码具有不可读性,需要解码后才能阅读。

  1、base64编码原理

  标准的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。

  规则

  关于这个编码的规则:

  ①把3个字符变成4个字符。

  ②每76个字符加一个换行符。

  ③最后的结束符也要处理。

  例子(1)

  转换前 11111111, 11111111, 11111111 (二进制)

  转换后 00111111, 00111111, 00111111, 00111111 (二进制)

  上面的三个字节是原文,下面的四个字节是转换后的Base64编码,其前两位均为0。

  转换后,我们用一个码表来得到我们想要的字符串(也就是最终的Base64编码),这个表是这样的:

  111Base64

  例子(2)

  转换前 10101101,10111010,01110110

  转换后 00101011, 00011011 ,00101001 ,00110110

  十进制 43 27 41 54

  对应码表中的值 r b p 2

  所以上面的24位编码,编码后的Base64值为 rbp2

  解码同理,把 rbq2 的二进制位连接上再重组得到三个8位值,得出原码。

  (解码只是编码的逆过程,有关MIME的RFC还有很多,如果需要详细情况请自行查找。)

  第一个字节,根据源字节的第一个字节处理。

  规则:源第一字节右移两位,去掉低2位,高2位补零。

  既:00 + 高6位

  第二个字节,根据源字节的第一个字节和第二个字节联合处理。

  规则如下,第一个字节高6位去掉然后左移四位,第二个字节右移四位

  即:源第一字节低2位 + 源第2字节高4位

  第三个字节,根据源字节的第二个字节和第三个字节联合处理,

  规则第二个字节去掉高4位并左移两位(得高6位),第三个字节右移6位并去掉高6位(得低2位),相加即可

  第四个字节,规则,源第三字节去掉高2位即可

  //用更接近于编程的思维来说,编码的过程是这样的:

  //第一个字符通过右移2位获得第一个目标字符的Base64表位置,根据这个数值取到表上相应的字符,就是第一//个目标字符。

  //然后将第一个字符与0x03(00000011)进行与(&)操作并左移4位,接着第二个字符右移4位与前者相或(|),即获得第二个目标字符。

  //再将第二个字符与0x0f(00001111)进行与(&)操作并左移2位,接着第三个字符右移6位与前者相或(|),获得第三个目标字符。

  //最后将第三个字符与0x3f(00111111)进行与(&)操作即获得第四个目标字符。

  //在以上的每一个步骤之后,再把结果与 0x3F 进行 AND 位操作,就可以得到编码后的字符了。

  可是等等……聪明的你可能会问到,原文的字节数量应该是3的倍数啊,如果这个条件不能满足的话,那该怎么办呢?

  我们的解决办法是这样的:原文剩余的字节根据编码规则继续单独转(1变2,2变3;不够的位数用0补全),再用=号补满4个字节。这就是为什么有些Base64编码会以一个或两个等号结束的原因,但等号最多只有两个。因为:

  一个原字节至少会变成两个目标字节

  所以余数任何情况下都只可能是0,1,2这三个数中的一个。如果余数是0的话,就表示原文字节数正好是3的倍数(最理想的情况)。如果是1的话,转成2个Base64编码字符,为了让Base64编码是4的倍数,就要补2个等号;同理,如果是2的话,就要补1个等号。

  2、编程实现

  (1)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;

  }

  (2)Java版

  import java.util.Base64;

  对于标准的Base64:

  加密为字符串使用Base64.getEncoder().encodeToString();

  加密为字节数组使用Base64.getEncoder().encode();

  解密使用Base64.getDecoder().decode();

  对于URL安全或MIME的Base64,只需将上述getEncoder()getDecoder()更换为getUrlEncoder()getUrlDecoder()

  或getMimeEncoder()和getMimeDecoder()即可。

  (3)PHP版

  [下列代码仅在GBK中实现,UTF8代码请把 if($button==“迅雷地址-》普通地址”) echo substr(base64_decode(str_ireplace(“thunder://”,“”,$txt1)),2,-2); 这句改为if($button==“迅雷地址-》普通地址”) echo substr(mb_convert_encoding(base64_decode(str_ireplace(“thunder://”,“”,$txt1))),2,-2); 并把charset=gb2312改为charset=utf-8]

  《?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》

  (4)VB版

  注:其中DigestStrToHexStr为可在程序外部调用加密函数

  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

  (5)C#版

  自己完成算法实现

  方法一: ///《summary》

  ///Base64加密

  ///《/summary》

  ///《paramname=“Message”》《/param》

  ///《returns》《/returns》

  publicstringBase64Code(stringMessage)

  {

  char[]Base64Code=newchar[]{’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‘,’+‘,’/‘,’=‘};

  byteempty=(byte)0;

  System.Collections.ArrayListbyteMessage=newSystem.Collections.ArrayList(System.Text.Encoding.Default.GetBytes(Message));

  System.Text.StringBuilderoutmessage;

  intmessageLen=byteMessage.Count;

  //将字符分成3个字节一组,如果不足,则以0补齐

  intpage=messageLen/3;

  intuse=0;

  if((use=messageLen%3)》0)

  {

  for(inti=0;i《3-use;i++)

  byteMessage.Add(empty);

  page++;

  }

  //将3个字节的每组字符转换成4个字节一组的。3个一组,一组一组变成4个字节一组

  //方法是:转换成ASCII码,按顺序排列24位数据,再把这24位数据分成4组,即每组6位。再在每组的的最高位前补两个0凑足一个字节。

  outmessage=newSystem.Text.StringBuilder(page*4);

  for(inti=0;i《page;i++)

  {

  //取一组3个字节的组

  byte[]instr=newbyte[3];

  instr[0]=(byte)byteMessage[i*3];

  instr[1]=(byte)byteMessage[i*3+1];

  instr[2]=(byte)byteMessage[i*3+2];

  //六个位为一组,补0变成4个字节

  int[]outstr=newint[4];

  //第一个输出字节:取第一输入字节的前6位,并且在高位补0,使其变成8位(一个字节)

  outstr[0]=instr[0]》》2;

  //第二个输出字节:取第一输入字节的后2位和第二个输入字节的前4位(共6位),并且在高位补0,使其变成8位(一个字节)

  outstr[1]=((instr[0]&0x03)《《4)^(instr[1]》》4);

  //第三个输出字节:取第二输入字节的后4位和第三个输入字节的前2位(共6位),并且在高位补0,使其变成8位(一个字节)

  if(!instr[1].Equals(empty))

  outstr[2]=((instr[1]&0x0f)《《2)^(instr[2]》》6);

  else

  outstr[2]=64;

  //第四个输出字节:取第三输入字节的后6位,并且在高位补0,使其变成8位(一个字节)

  if(!instr[2].Equals(empty))

  outstr[3]=(instr[2]&0x3f);

  else

  outstr[3]=64;

  outmessage.Append(Base64Code[outstr[0]]);

  outmessage.Append(Base64Code[outstr[1]]);

  outmessage.Append(Base64Code[outstr[2]]);

  outmessage.Append(Base64Code[outstr[3]]);

  }

  returnoutmessage.ToString();

  }

  ///《summary》

  ///Base64解密

  ///《/summary》

  ///《paramname=“Message”》《/param》

  ///《returns》《/returns》

  publicstringBase64Decode(stringMessage)

  {

  if((Message.Length%4)!=0)

  {

  thrownewArgumentException(“不是正确的BASE64编码,请检查。”,“Message”);

  }

  if(!System.Text.RegularExpressions.Regex.IsMatch(Message,“^[A-Z0-9/+=]*$”,System.Text.RegularExpressions.RegexOptions.IgnoreCase))

  {

  thrownewArgumentException(“包含不正确的BASE64编码,请检查。”,“Message”);

  }

  stringBase64Code=“ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=”;

  intpage=Message.Length/4;

  System.Collections.ArrayListoutMessage=newSystem.Collections.ArrayList(page*3);

  char[]message=Message.ToCharArray();

  for(inti=0;i《page;i++)

  {

  byte[]instr=newbyte[4];

  instr[0]=(byte)Base64Code.IndexOf(message[i*4]);

  instr[1]=(byte)Base64Code.IndexOf(message[i*4+1]);

  instr[2]=(byte)Base64Code.IndexOf(message[i*4+2]);

  instr[3]=(byte)Base64Code.IndexOf(message[i*4+3]);

  byte[]outstr=newbyte[3];

  outstr[0]=(byte)((instr[0]《《2)^((instr[1]&0x30)》》4));

  if(instr[2]!=64)

  {

  outstr[1]=(byte)((instr[1]《《4)^((instr[2]&0x3c)》》2));

  }

  else

  {

  outstr[2]=0;

  }

  if(instr[3]!=64)

  {

  outstr[2]=(byte)((instr[2]《《6)^instr[3]);

  }

  else

  {

  outstr[2]=0;

  }

  outMessage.Add(outstr[0]);

  if(outstr[1]!=0)

  outMessage.Add(outstr[1]);

  if(outstr[2]!=0)

  outMessage.Add(outstr[2]);

  }

  byte[]outbyte=(byte[])outMessage.ToArray(Type.GetType(“System.Byte”));

  returnSystem.Text.Encoding.Default.GetString(outbyte);

  }

  直接使用.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);

  }

  AS3版本

  public class Base64

  {

  private static const _encodeChars:Vector.《int》 = InitEncoreChar();

  private static const _decodeChars:Vector.《int》 = InitDecodeChar();

  public static function encodeStr(data:String):String {

  var bytes:ByteArray = new ByteArray();

  bytes.writeUTFBytes(data);

  return encode(bytes);

  }

  public static function decodeStr(data:String):String {

  var bytes:ByteArray = decode(data);

  bytes.position = 0;

  return bytes.readUTFBytes(bytes.length);

  }

  public static function encode(data:ByteArray):String

  {

  var out:ByteArray = new ByteArray();

  //Presetting the length keep the memory smaller and optimize speed since there is no “grow” needed

  out.length = (2 + data.length - ((data.length + 2) % 3)) * 4 / 3; //Preset length //1.6 to 1.5 ms

  var i:int = 0;

  var r:int = data.length % 3;

  var len:int = data.length - r;

  var c:uint; //read (3) character AND write (4) characters

  var outPos:int = 0;

  while (i 《 len)

  {

  //Read 3 Characters (8bit * 3 = 24 bits)

  c = data[int(i++)] 《《 16 | data[int(i++)] 《《 8 | data[int(i++)];

  out[int(outPos++)] = _encodeChars[int(c 》》》 18)];

  out[int(outPos++)] = _encodeChars[int(c 》》》 12 & 0x3f)];

  out[int(outPos++)] = _encodeChars[int(c 》》》 6 & 0x3f)];

  out[int(outPos++)] = _encodeChars[int(c & 0x3f)];

  }

  if (r == 1) //Need two “=” padding

  {

  //Read one char, write two chars, write padding

  c = data[int(i)];

  out[int(outPos++)] = _encodeChars[int(c 》》》 2)];

  out[int(outPos++)] = _encodeChars[int((c & 0x03) 《《 4)];

  out[int(outPos++)] = 61;

  out[int(outPos++)] = 61;

  }

  else if (r == 2) //Need one “=” padding

  {

  c = data[int(i++)] 《《 8 | data[int(i)];

  out[int(outPos++)] = _encodeChars[int(c 》》》 10)];

  out[int(outPos++)] = _encodeChars[int(c 》》》 4 & 0x3f)];

  out[int(outPos++)] = _encodeChars[int((c & 0x0f) 《《 2)];

  out[int(outPos++)] = 61;

  }

  return out.readUTFBytes(out.length);

  }

  public static function decode(str:String):ByteArray

  {

  var c1:int;

  var c2:int;

  var c3:int;

  var c4:int;

  var i:int = 0;

  var len:int = str.length;

  var byteString:ByteArray = new ByteArray();

  byteString.writeUTFBytes(str);

  var outPos:int = 0;

  while (i 《 len)

  {

  //c1

  c1 = _decodeChars[int(byteString[i++])];

  if (c1 == -1)

  break;

  //c2

  c2 = _decodeChars[int(byteString[i++])];

  if (c2 == -1)

  break;

  byteString[int(outPos++)] = (c1 《《 2) | ((c2 & 0x30) 》》 4);

  //c3

  c3 = byteString[int(i++)];

  if (c3 == 61)

  {

  byteString.length = outPos

  return byteString;

  }

  c3 = _decodeChars[int(c3)];

  if (c3 == -1)

  break;

  byteString[int(outPos++)] = ((c2 & 0x0f) 《《 4) | ((c3 & 0x3c) 》》 2);

  //c4

  c4 = byteString[int(i++)];

  if (c4 == 61)

  {

  byteString.length = outPos

  return byteString;

  }

  c4 = _decodeChars[int(c4)];

  if (c4 == -1)

  break;

  byteString[int(outPos++)] = ((c3 & 0x03) 《《 6) | c4;

  }

  byteString.length = outPos

  return byteString;

  }

  public static function InitEncoreChar():Vector.《int》

  {

  var encodeChars:Vector.《int》 = new Vector.《int》(64, true);

  // We could push the number directly

  // but I think it’s nice to see the characters (with no overhead on encode/decode)

  var chars:String = “ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/”;

  for (var i:int = 0; i 《 64; i++)

  {

  encodeChars[i] = chars.charCodeAt(i);

  }

  return encodeChars;

  }

  public static function InitDecodeChar():Vector.《int》

  {

  var decodeChars:Vector.《int》 = new 《int》[

  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,

  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,

  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,

  52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,

  -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,

  15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,

  -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,

  41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,

  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,

  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,

  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,

  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,

  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,

  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,

  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,

  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1];

  return decodeChars;

  }

  }

  (6)c/c++版

  /******************************************

  Base64编码解码算法 C语言源代码

  by 虎胆游侠 http://blog.csdn.net/prsniper

  ******************************************/

  #include 《stdio.h》 //注意哦,VC中“”是当前路径,《》是系统路径

  #include 《windows.h》

  const char BASE_CODE[] = “ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/”;

  //编码,参数:要编码的字符串指针,解码后存放的位置(编码字串长度的4/3),要编码的字符串长度 -》返回结果长度

  int fnBase64Encode(char *lpString, char *lpBuffer, int sLen)

  { register int vLen = 0; //寄存器局部变量,提速

  while(sLen 》 0) //处理整个字符串

  { *lpBuffer++ = BASE_CODE[(lpString[0] 》》 2 ) & 0x3F]; //右移两位,与00111111是防止溢出,自加

  if(sLen 》 2) //够3个字符

  { *lpBuffer++ = BASE_CODE[((lpString[0] & 3) 《《 4) | (lpString[1] 》》 4)];

  *lpBuffer++ = BASE_CODE[((lpString[1] & 0xF) 《《 2) | (lpString[2] 》》 6)];

  *lpBuffer++ = BASE_CODE[lpString[2] & 0x3F];

  }else

  { switch(sLen) //追加“=”

  { case 1:

  *lpBuffer ++ = BASE_CODE[(lpString[0] & 3) 《《 4 ];

  *lpBuffer ++ = ‘=’;

  *lpBuffer ++ = ‘=’;

  break;

  case 2:

  *lpBuffer ++ = BASE_CODE[((lpString[0] & 3) 《《 4) | (lpString[1] 》》 4)];

  *lpBuffer ++ = BASE_CODE[((lpString[1] & 0x0F) 《《 2) | (lpString[2] 》》 6)];

  *lpBuffer ++ = ‘=’;

  break;

  }

  }

  lpString += 3;

  sLen -= 3;

  vLen +=4;

  }

  *lpBuffer = 0;

  return vLen;

  }

  //子函数 - 取密文的索引

  inline char GetCharIndex(char c) //内联函数可以省去函数调用过程,提速

  { if((c 》= ‘A’) && (c 《= ‘Z’))

  { return c - ‘A’;

  }else if((c 》= ‘a’) && (c 《= ‘z’))

  { return c - ‘a’ + 26;

  }else if((c 》= ‘0’) && (c 《= ‘9’))

  { return c - ‘0’ + 52;

  }else if(c == ‘+’)

  { return 62;

  }else if(c == ‘/’)

  { return 63;

  }else if(c == ‘=’)

  { return 0;

  }

  return 0;

  }

  //解码,参数:结果,密文,密文长度

  int fnBase64Decode(char *lpString, char *lpSrc, int sLen) //解码函数

  { static char lpCode[4];

  register int vLen = 0;

  if(sLen % 4) //Base64编码长度必定是4的倍数,包括‘=’

  { lpString[0] = ‘\0’;

  return -1;

  }

  while(sLen 》 2) //不足三个字符,忽略

  { lpCode[0] = GetCharIndex(lpSrc[0]);

  lpCode[1] = GetCharIndex(lpSrc[1]);

  lpCode[2] = GetCharIndex(lpSrc[2]);

  lpCode[3] = GetCharIndex(lpSrc[3]);

  *lpString++ = (lpCode[0] 《《 2) | (lpCode[1] 》》 4);

  *lpString++ = (lpCode[1] 《《 4) | (lpCode[2] 》》 2);

  *lpString++ = (lpCode[2] 《《 6) | (lpCode[3]);

  lpSrc += 4;

  sLen -= 4;

  vLen += 3;

  }

  return vLen;

  }

  void main() //主函数,测试函数

  { char s[] = “a”, str[32];

  int l = strlen(s);

  int i = fnBase64Encode(s, str, l);

  printf(“fnBase64Encode(\”%s\“, str, %d) = \”%s\“;\n”, s, l, str);

  l = fnBase64Decode(s, str, i);

  printf(“fnBase64Decode(\”%s\“, s, %d) = \”%s\“;\n”, str, i, s);

  }

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分