base64

 

 

Base64是网络上最常见的用于传输8Bit字节代码的编码方式之一,大家可以查看RFC2045~RFC2049,上面有MIME的详细规范。Base64编码可用于在HTTP环境下传递较长的标识信息。例如,在Java Persistence系统Hibernate中,就采用了Base64来将一个较长的唯一标识符(一般为128-bit的UUID)编码为一个字符串,用作HTTP表单和HTTP GET URL中的参数。在其他应用程序中,也常常需要把二进制数据编码为适合放在URL(包括隐藏表单域)中的形式。此时,采用Base64编码不仅比较简短,同时也具有不可读性,即所编码的数据不会被人用肉眼所直接看到。

标准的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个字符加一个换行符..
  ③.最后的结束符也要处理..
  这样说会不会太抽象了?不怕,我们来看一个例子:
  转换前 aaaaaabb ccccdddd eeffffff
  转换后 00aaaaaa 00bbcccc 00ddddee 00ffffff
  应该很清楚了吧?上面的三个 字节是原文,下面的四个字节是转换后的Base64编码,其前两位均为0。
  转换后,我们用一个码表来得到我们想要的字符串(也就是最终的Base64编码),这个表是这样的:(摘自RFC2045)

转换表

  Table 1: The Base64 Alphabet
  Value Encoding Value Encoding Value Encoding Value Encoding
  0 A 17 R 34 i 51 z
  1 B 18 S 35 j 52 0
  2 C 19 T 36 k 53 1
  3 D 20 U 37 l 54 2
  4 E 21 V 38 m 55 3
  5 F 22 W 39 n 56 4
  6 G 23 X 40 o 57 5
  7 H 24 Y 41 p 58 6
  8 I 25 Z 42 q 59 7
  9 J 26 a 43 r 60 8
  10 K 27 b 44 s 61 9
  11 L 28 c 45 t 62 +
  12 M 29 d 46 u 63 /
  13 N 30 e 47 v
  14 O 31 f 48 w (pad) =
  15 P 32 g 49 x
  16 Q 33 h 50 y
  
索引对应字符索引对应字符索引对应字符索引对应字符
0A17R34i51z
1B18S35j520
2C19T36k531
3D20U37l542
4E21V38m553
5F22W39n564
6G23X40o575
7H24Y41p586
8I25Z42q597
9J26a43r608
10K27b44s619
11L28c45t62+
12M29d46u63/
13N30e47v  
14O31f48w  
15P32g49x  
16Q33h50y  

举例

  让我们再来看一个实际的例子,加深印象!
  转换前 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位即可
  根据base64的编码规则,每76个字符需要一个换行
  // 用更接近于 编程的思维来说,编码的过程是这样的:
  //第一个 字符通过右移2位获得第一个目标字符的Base64表位置,根据这个数值取到表上相应的字符,就是第一//个目标字符。
  // 然后将第一个字符左移4位加上第二个字符右移4位,即获得第二个目标字符。
  //再将第二个字符左移2位加上第三个字符右移6位,获得第三个目标字符。
  //最后取第三个字符的右6位即获得第四个目标字符。
  //在以上的每一个步骤之后,再把结果与 0x3F 进行 AND 位操作,就可以得到编码后的字符了。
  可是等等……聪明的你可能会问到,原文的 字节数量应该是3的倍数啊,如果这个条件不能满足的话,那该怎么办呢?
  我们的解决办法是这样的:原文的字节不够的地方可以用全0来补足,转换时Base64编码用=号来代替。这就是为什么有些Base64编码会以一个或两个等号结束的原因,但等号最多只有两个。因为:
  余数 = 原文字节数 MOD 3
  所以余数任何情况下都只可能是0,1,2这三个数中的一个。如果余数是0的话,就表示原文字节数正好是3的倍数(最理想的情况啦)。如果是1的话,为了让Base64编码是3的倍数,就要补2个等号;同理,如果是2的话,就要补1个等号。

在URL中的应用

  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用作编码字串。

在下载软件中加密下载地址的原理

  先以“ 迅雷下载”为例: 很多下载类网站都提供“迅雷下载”的链接,其地址通常是加密的迅雷专用下载地址。
  如thunder://QUFodHRwOi8vd3d3LmJhaWR1LmNvbS9pbWcvc3NsbTFfbG9nby5naWZaWg==
  其实迅雷的“专用地址”也是用Base64加密的,其加密过程如下:
  一、在地址的前后分别添加AA和ZZ
  如www.baidu.com/img/sslm1_logo.gif变成
  AAwww.baidu.com/img/sslm1_logo.gifZZ
  二、对新的字符串进行Base64编码
  如AAwww.baidu.com/img/sslm1_logo.gifZZ用Base64编码得到
  QUF3d3cuYmFpZHUuY29tL2ltZy9zc2xtMV9sb2dvLmdpZlpa
  三、在上面得到的字符串前加上“thunder://”就成了
  thunder://QUF3d3cuYmFpZHUuY29tL2ltZy9zc2xtMV9sb2dvLmdpZlpa
  另:
  Flashget的与迅雷类似,只不过在第一步时加的“料”不同罢了,Flashget在地址前后加的“料”是[FLASHGET]
  而QQ旋风的干脆不加料,直接就对地址进行Base64编码了

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'];
  ?>
  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
  <html>
  <head>
  <title>迅雷和FlashGet,QQ旋风地址 地址转换工具</title>
  <meta http-equiv="Content-Type" content="text/html; charset=gb2312">
  <meta content="迅雷,FlashGet,地址转换," name="keywords">
  </head>
  <body>
  <form name="form1" method="post" action="">
  <hr size="1">
  <h3>迅雷转换</h3>
  <P>转换地址:
  <input name="text1" value="<?php echo $txt1;?>" type="text" style="width:516px;" /></P>
  <P>转换后的:
  <input type="text" value="<?php
  if($button=="普通地址->迅雷地址") echo "thunder://".base64_encode("AA".$txt1."ZZ");
  if($button=="迅雷地址->普通地址") echo substr(base64_decode(str_ireplace("thunder://","",$txt1)),2,-2);
  ?>" style="width:516px;" /></P>
  <P>
  <input type="submit" name="button" value="普通地址->迅雷地址" />
  <input type="submit" name="button" value="迅雷地址->普通地址" /></P>
  <h3>FlashGet转换</h3>
  <P>FlashGet地址:
  <input name="text2" value="<?php echo $txt2;?>" type="text" style="width:516px;" /></P>
  <P>转换后 地址:
  <input type="text" value="<?php
  if($button=="普通地址->FlashGet地址") echo "flashget://".base64_encode($txt2);
  if($button=="FlashGet地址->普通地址") echo str_ireplace("[FLASHGET]","",base64_decode(str_ireplace("flashget://","",$txt2)));
  ?>" style="width:516px;" /></P>
  <P>
  <input type="submit" value="普通地址->FlashGet地址" name="button" />
  <input type="submit" value="FlashGet地址->普通地址" name="button" /></P>
  <h3>QQ旋风转换</h3>
  <P>QQ旋风地址:
  <input name="text3" value="<?php echo $txt3;?>" type="text" style="width:516px;" /></P>
  <P>转换后 地址:
  <input type="text" value="<?php
  if($button=="普通地址->QQ旋风") echo "qqdl://".base64_encode($txt3);
  if($button=="QQ旋风->普通地址") echo base64_decode(str_ireplace("qqdl://","",$txt3));
  ?>" style="width:516px;" /></P>
  <P>
  <input type="submit" value="普通地址->QQ旋风" name="button" />
  <input type="submit" value="QQ旋风->普通地址" name="button" /></P>
  </form>
  </body>
  </html>

VB版的Base64编码函数定义

  注:其中DigestStrToHexStr为可在程序外部调用加密函数
  Option Explicit
  ' Base64 Encoding/Decoding Algorithm
  ' By: David Midkiff (mznull@earthlink.net)
  '
  ' This algorithms encodes and decodes data into Base64
  ' format. This format is extremely more efficient than
  ' Hexadecimal encoding.
  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
  CopyMemory VarPtr(bytResult(LBound(bytResult))), VarPtr(bytWorkspace(LBound(bytWorkspace))), lWorkspaceCounter
  DecodeArray64 = bytResult
  End Function
  Public Function Encode64(ByRef sInput 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(ByRef bytInput() 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
  CopyMemory lpResult, lpWorkSpace, k_lMaxBytesPerLine
  lpWorkSpace = lpWorkSpace + k_lMaxBytesPerLine
  lpResult = lpResult + k_lMaxBytesPerLine
  CopyMemory lpResult, lpCrLf, 4&
  lpResult = lpResult + 4&
  Next lLineCounter
  lBytesRemaining = lWorkspaceCounter - (lCompleteLines * k_lMaxBytesPerLine)
  If lBytesRemaining > 0 Then CopyMemory lpResult, lpWorkSpace, lBytesRemaining
  EncodeArray64 = Left$(bytResult, InStr(1, bytResult, Chr$(0)) - 1)
  End If
  Exit Function
  ErrorHandler:
  Erase bytResult
  EncodeArray64 = bytResult
  End Function
  Private Sub Class_Initialize()
  m_bytIndex(0) = 65 'Asc("A")
  m_bytIndex(1) = 66 'Asc("B")
  m_bytIndex(2) = 67 'Asc("C")
  m_bytIndex(3) = 68 'Asc("D")
  m_bytIndex(4) = 69 'Asc("E")
  m_bytIndex(5) = 70 'Asc("F")
  m_bytIndex(6) = 71 'Asc("G")
  m_bytIndex(7) = 72 'Asc("H")
  m_bytIndex(8) = 73 'Asc("I")
  m_bytIndex(9) = 74 'Asc("J")
  m_bytIndex(10) = 75 'Asc("K")
  m_bytIndex(11) = 76 'Asc("L")
  m_bytIndex(12) = 77 'Asc("M")
  m_bytIndex(13) = 78 'Asc("N")
  m_bytIndex(14) = 79 'Asc("O")
  m_bytIndex(15) = 80 'Asc("P")
  m_bytIndex(16) = 81 'Asc("Q")
  m_bytIndex(17) = 82 'Asc("R")
  m_bytIndex(18) = 83 'Asc("S")
  m_bytIndex(19) = 84 'Asc("T")
  m_bytIndex(20) = 85 'Asc("U")
  m_bytIndex(21) = 86 'Asc("V")
  m_bytIndex(22) = 87 'Asc("W")
  m_bytIndex(23) = 88 'Asc("X")
  m_bytIndex(24) = 89 'Asc("Y")
  m_bytIndex(25) = 90 'Asc("Z")
  m_bytIndex(26) = 97 'Asc("a")
  m_bytIndex(27) = 98 'Asc("b")
  m_bytIndex(28) = 99 'Asc("c")
  m_bytIndex(29) = 100 'Asc("d")
  m_bytIndex(30) = 101 'Asc("e")
  m_bytIndex(31) = 102 'Asc("f")
  m_bytIndex(32) = 103 'Asc("g")
  m_bytIndex(33) = 104 'Asc("h")
  m_bytIndex(34) = 105 'Asc("i")
  m_bytIndex(35) = 106 'Asc("j")
  m_bytIndex(36) = 107 'Asc("k")
  m_bytIndex(37) = 108 'Asc("l")
  m_bytIndex(38) = 109 'Asc("m")
  m_bytIndex(39) = 110 'Asc("n")
  m_bytIndex(40) = 111 'Asc("o")
  m_bytIndex(41) = 112 'Asc("p")
  m_bytIndex(42) = 113 'Asc("q")
  m_bytIndex(43) = 114 'Asc("r")
  m_bytIndex(44) = 115 'Asc("s")
  m_bytIndex(45) = 116 'Asc("t")
  m_bytIndex(46) = 117 'Asc("u")
  m_bytIndex(47) = 118 'Asc("v")
  m_bytIndex(48) = 119 'Asc("w")
  m_bytIndex(49) = 120 'Asc("x")
  m_bytIndex(50) = 121 'Asc("y")
  m_bytIndex(51) = 122 'Asc("z")
  m_bytIndex(52) = 48 'Asc("0")
  m_bytIndex(53) = 49 'Asc("1")
  m_bytIndex(54) = 50 'Asc("2")
  m_bytIndex(55) = 51 'Asc("3")
  m_bytIndex(56) = 52 'Asc("4")
  m_bytIndex(57) = 53 'Asc("5")
  m_bytIndex(58) = 54 'Asc("6")
  m_bytIndex(59) = 55 'Asc("7")
  m_bytIndex(60) = 56 'Asc("8")
  m_bytIndex(61) = 57 'Asc("9")
  m_bytIndex(62) = 43 'Asc("+")
  m_bytIndex(63) = 47 'Asc("/")
  m_bytReverseIndex(65) = 0 'Asc("A")
  m_bytReverseIndex(66) = 1 'Asc("B")
  m_bytReverseIndex(67) = 2 'Asc("C")
  m_bytReverseIndex(68) = 3 'Asc("D")
  m_bytReverseIndex(69) = 4 'Asc("E")
  m_bytReverseIndex(70) = 5 'Asc("F")
  m_bytReverseIndex(71) = 6 'Asc("G")
  m_bytReverseIndex(72) = 7 'Asc("H")
  m_bytReverseIndex(73) = 8 'Asc("I")
  m_bytReverseIndex(74) = 9 'Asc("J")
  m_bytReverseIndex(75) = 10 'Asc("K")
  m_bytReverseIndex(76) = 11 'Asc("L")
  m_bytReverseIndex(77) = 12 'Asc("M")
  m_bytReverseIndex(78) = 13 'Asc("N")
  m_bytReverseIndex(79) = 14 'Asc("O")
  m_bytReverseIndex(80) = 15 'Asc("P")
  m_bytReverseIndex(81) = 16 'Asc("Q")
  m_bytReverseIndex(82) = 17 'Asc("R")
  m_bytReverseIndex(83) = 18 'Asc("S")
  m_bytReverseIndex(84) = 19 'Asc("T")
  m_bytReverseIndex(85) = 20 'Asc("U")
  m_bytReverseIndex(86) = 21 'Asc("V")
  m_bytReverseIndex(87) = 22 'Asc("W")
  m_bytReverseIndex(88) = 23 'Asc("X")
  m_bytReverseIndex(89) = 24 'Asc("Y")
  m_bytReverseIndex(90) = 25 'Asc("Z")
  m_bytReverseIndex(97) = 26 'Asc("a")
  m_bytReverseIndex(98) = 27 'Asc("b")
  m_bytReverseIndex(99) = 28 'Asc("c")
  m_bytReverseIndex(100) = 29 'Asc("d")
  m_bytReverseIndex(101) = 30 'Asc("e")
  m_bytReverseIndex(102) = 31 'Asc("f")
  m_bytReverseIndex(103) = 32 'Asc("g")
  m_bytReverseIndex(104) = 33 'Asc("h")
  m_bytReverseIndex(105) = 34 'Asc("i")
  m_bytReverseIndex(106) = 35 'Asc("j")
  m_bytReverseIndex(107) = 36 'Asc("k")
  m_bytReverseIndex(108) = 37 'Asc("l")
  m_bytReverseIndex(109) = 38 'Asc("m")
  m_bytReverseIndex(110) = 39 'Asc("n")
  m_bytReverseIndex(111) = 40 'Asc("o")
  m_bytReverseIndex(112) = 41 'Asc("p")
  m_bytReverseIndex(113) = 42 'Asc("q")
  m_bytReverseIndex(114) = 43 'Asc("r")
  m_bytReverseIndex(115) = 44 'Asc("s")
  m_bytReverseIndex(116) = 45 'Asc("t")
  m_bytReverseIndex(117) = 46 'Asc("u")
  m_bytReverseIndex(118) = 47 'Asc("v")
  m_bytReverseIndex(119) = 48 'Asc("w")
  m_bytReverseIndex(120) = 49 'Asc("x")
  m_bytReverseIndex(121) = 50 'Asc("y")
  m_bytReverseIndex(122) = 51 'Asc("z")
  m_bytReverseIndex(48) = 52 'Asc("0")
  m_bytReverseIndex(49) = 53 'Asc("1")
  m_bytReverseIndex(50) = 54 'Asc("2")
  m_bytReverseIndex(51) = 55 'Asc("3")
  m_bytReverseIndex(52) = 56 'Asc("4")
  m_bytReverseIndex(53) = 57 'Asc("5")
  m_bytReverseIndex(54) = 58 'Asc("6")
  m_bytReverseIndex(55) = 59 'Asc("7")
  m_bytReverseIndex(56) = 60 'Asc("8")
  m_bytReverseIndex(57) = 61 'Asc("9")
  m_bytReverseIndex(43) = 62 'Asc("+")
  m_bytReverseIndex(47) = 63 'Asc("/")
  End Sub

JS版的Base64编码函数定义

  var base64EncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  var base64DecodeChars = new Array(
  -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);
  function base64encode(str)
  {
  var returnVal, i, len;
  var c1, c2, c3;
  len = str.length;
  i = 0;
  returnVal = "";
  while(i < len)
  {
  c1 = str.charCodeAt(i++) & 0xff;
  if(i == len)
  {
  returnVal += base64EncodeChars.charAt(c1 >> 2);
  returnVal += base64EncodeChars.charAt((c1 & 0x3) << 4);
  returnVal += "==";
  break;
  }
  c2 = str.charCodeAt(i++);
  if(i == len)
  {
  returnVal += base64EncodeChars.charAt(c1 >> 2);
  returnVal += base64EncodeChars.charAt(((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4));
  returnVal += base64EncodeChars.charAt((c2 & 0xF) << 2);
  returnVal += "=";
  break;
  }
  c3 = str.charCodeAt(i++);
  returnVal += base64EncodeChars.charAt(c1 >> 2);
  returnVal += base64EncodeChars.charAt(((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4));
  returnVal += base64EncodeChars.charAt(((c2 & 0xF) << 2) | ((c3 & 0xC0) >>6));
  returnVal += base64EncodeChars.charAt(c3 & 0x3F);
  }
  return returnVal;
  }
  function base64decode(str)
  {
  var c1, c2, c3, c4;
  var i, len, returnVal;
  len = str.length;
  i = 0;
  returnVal = "";
  while(i < len)
  {
  /* c1 */
  do
  {
  c1 = base64DecodeChars[str.charCodeAt(i++) & 0xff];
  } while(i < len && c1 == -1);
  if(c1 == -1)
  break;
  /* c2 */
  do
  {
  c2 = base64DecodeChars[str.charCodeAt(i++) & 0xff];
  } while(i < len && c2 == -1);
  if(c2 == -1)
  break;
  returnVal += String.fromCharCode((c1 << 2) | ((c2 & 0x30) >> 4));
  /* c3 */
  do
  {
  c3 = str.charCodeAt(i++) & 0xff;
  if(c3 == 61)
  return returnVal;
  c3 = base64DecodeChars[c3];
  } while(i < len && c3 == -1);
  if(c3 == -1)
  break;
  returnVal += String.fromCharCode(((c2 & 0XF) << 4) | ((c3 & 0x3C) >> 2));
  /* c4 */
  do
  {
  c4 = str.charCodeAt(i++) & 0xff;
  if(c4 == 61)
  return returnVal;
  c4 = base64DecodeChars[c4];
  } while(i < len && c4 == -1);
  if(c4 == -1)
  break;
  returnVal += String.fromCharCode(((c3 & 0x03) << 6) | c4);
  }
  return returnVal;
  }
   AS3版的Base64
  package crypto{
  import flash.utils.ByteArray;
  public class Base64 {
  private static const BASE64_CHARS:String = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
  public static function encode(data:String):String {
  // Convert string to ByteArray
  var bytes:ByteArray = new ByteArray();
  bytes.writeUTFBytes(data);
  // Return encoded ByteArray
  return encodeByteArray(bytes);
  }
  public static function encodeByteArray(data:ByteArray):String {
  // Initialise output
  var output:String = "";
  // Create data and output buffers
  var dataBuffer:Array;
  var outputBuffer:Array = new Array(4);
  // Rewind ByteArray
  data.position = 0;
  // while there are still bytes to be processed
  while (data.bytesAvailable > 0) {
  // Create new data buffer and populate next 3 bytes from data
  dataBuffer = new Array();
  for (var i:uint = 0; i < 3 && data.bytesAvailable > 0; i++) {
  dataBuffer = data.readUnsignedByte();
  }
  // Convert to data buffer Base64 character positions and
  // store in output buffer
  outputBuffer[0] = (dataBuffer[0] & 0xfc) >> 2;
  outputBuffer[1] = ((dataBuffer[0] & 0x03) << 4) | ((dataBuffer[1]) >> 4);
  outputBuffer[2] = ((dataBuffer[1] & 0x0f) << 2) | ((dataBuffer[2]) >> 6);
  outputBuffer[3] = dataBuffer[2] & 0x3f;
  // If data buffer was short (i.e not 3 characters) then set
  // end character indexes in data buffer to index of '=' symbol.
  // This is necessary because Base64 data is always a multiple of
  // 4 bytes and is basses with '=' symbols.
  for (var j:uint = dataBuffer.length; j < 3; j++) {
  outputBuffer[j + 1] = 64;
  }
  // Loop through output buffer and add Base64 characters to
  // encoded data string for each character.
  for (var k:uint = 0; k < outputBuffer.length; k++) {
  output += BASE64_CHARS.charAt(outputBuffer[k]);
  }
  }
  // Return encoded data
  return output;
  }
  public static function decode(data:String):String {
  // Decode data to ByteArray
  var bytes:ByteArray = decodeToByteArray(data);
  // Convert to string and return
  return bytes.readUTFBytes(bytes.length);
  }
  public static function decodeToByteArray(data:String):ByteArray {
  // Initialise output ByteArray for decoded data
  var output:ByteArray = new ByteArray();
  // Create data and output buffers
  var dataBuffer:Array = new Array(4);
  var outputBuffer:Array = new Array(3);
  // While there are data bytes left to be processed
  for (var i:uint = 0; i < data.length; i += 4) {
  // Populate data buffer with position of Base64 characters for
  // next 4 bytes from encoded data
  for (var j:uint = 0; j < 4 && i + j < data.length; j++) {
  dataBuffer[j] = BASE64_CHARS.indexOf(data.charAt(i + j));
  }
  // Decode data buffer back into bytes
  outputBuffer[0] = (dataBuffer[0] << 2) + ((dataBuffer[1] & 0x30) >> 4);
  outputBuffer[1] = ((dataBuffer[1] & 0x0f) << 4) + ((dataBuffer[2] & 0x3c) >> 2);
  outputBuffer[2] = ((dataBuffer[2] & 0x03) << 6) + dataBuffer[3];
  // Add all non-padded bytes in output buffer to decoded data
  for (var k:uint = 0; k < outputBuffer.length; k++) {
  if (dataBuffer[k+1] == 64) break;
  output.writeByte(outputBuffer[k]);
  }
  }
  // Rewind decoded data ByteArray
  output.position = 0;
  // Return decoded data
  return output;
  }
  public function Base64() {
  throw new Error("Base64 class is static container only");
  }
  }
  }

JS实现BASE64加密、解密算法

  此算法只适用于加密ASCII映射表中的 字符组成的字符串,不能处理中文字符串等:
   脚本如下:
  <script language=javascript>
  var base64EncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  var base64DecodeChars = new Array(
  -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);
  function base64encode(str) {
  var out, i, len;
  var c1, c2, c3;
  len = str.length;
  i = 0;
  out = "";
  while(i < len) {
  c1 = str.charCodeAt(i++) & 0xff;
  if(i == len)
  {
  out += base64EncodeChars.charAt(c1 >> 2);
  out += base64EncodeChars.charAt((c1 & 0x3) << 4);
  out += "==";
  break;
  }
  c2 = str.charCodeAt(i++);
  if(i == len)
  {
  out += base64EncodeChars.charAt(c1 >> 2);
  out += base64EncodeChars.charAt(((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4));
  out += base64EncodeChars.charAt((c2 & 0xF) << 2);
  out += "=";
  break;
  }
  c3 = str.charCodeAt(i++);
  out += base64EncodeChars.charAt(c1 >> 2);
  out += base64EncodeChars.charAt(((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4));
  out += base64EncodeChars.charAt(((c2 & 0xF) << 2) | ((c3 & 0xC0) >>6));
  out += base64EncodeChars.charAt(c3 & 0x3F);
  }
  return out;
  }
  function base64decode(str) {
  var c1, c2, c3, c4;
  var i, len, out;
  len = str.length;
  i = 0;
  out = "";
  while(i < len) {
  /* c1 */
  do {
  c1 = base64DecodeChars[str.charCodeAt(i++) & 0xff];
  } while(i < len && c1 == -1);
  if(c1 == -1)
  break;
  /* c2 */
  do {
  c2 = base64DecodeChars[str.charCodeAt(i++) & 0xff];
  } while(i < len && c2 == -1);
  if(c2 == -1)
  break;
  out += String.fromCharCode((c1 << 2) | ((c2 & 0x30) >> 4));
  /* c3 */
  do {
  c3 = str.charCodeAt(i++) & 0xff;
  if(c3 == 61)
  return out;
  c3 = base64DecodeChars[c3];
  } while(i < len && c3 == -1);
  if(c3 == -1)
  break;
  out += String.fromCharCode(((c2 & 0XF) << 4) | ((c3 & 0x3C) >> 2));
  /* c4 */
  do {
  c4 = str.charCodeAt(i++) & 0xff;
  if(c4 == 61)
  return out;
  c4 = base64DecodeChars[c4];
  } while(i < len && c4 == -1);
  if(c4 == -1)
  break;
  out += String.fromCharCode(((c3 & 0x03) << 6) | c4);
  }
  return out;
  }
  </script>
  ================================================================================
  ================================================================================
  ================================================================================
  以下代码可以加密或处理UTF字符串:
  以及实例:
  <table width="773" border="0" align="center" cellpadding="0" cellspacing="0">
  <tr>
  <td>
  <script language=javascript>
  var base64EncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  var base64DecodeChars = new Array(
  -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);
  function base64encode(str) {
  var out, i, len;
  var c1, c2, c3;
  len = str.length;
  i = 0;
  out = "";
  while(i < len) {
  c1 = str.charCodeAt(i++) & 0xff;
  if(i == len)
  {
  out += base64EncodeChars.charAt(c1 >> 2);
  out += base64EncodeChars.charAt((c1 & 0x3) << 4);
  out += "==";
  break;
  }
  c2 = str.charCodeAt(i++);
  if(i == len)
  {
  out += base64EncodeChars.charAt(c1 >> 2);
  out += base64EncodeChars.charAt(((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4));
  out += base64EncodeChars.charAt((c2 & 0xF) << 2);
  out += "=";
  break;
  }
  c3 = str.charCodeAt(i++);
  out += base64EncodeChars.charAt(c1 >> 2);
  out += base64EncodeChars.charAt(((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4));
  out += base64EncodeChars.charAt(((c2 & 0xF) << 2) | ((c3 & 0xC0) >>6));
  out += base64EncodeChars.charAt(c3 & 0x3F);
  }
  return out;
  }
  function base64decode(str) {
  var c1, c2, c3, c4;
  var i, len, out;
  len = str.length;
  i = 0;
  out = "";
  while(i < len) {
  /* c1 */
  do {
  c1 = base64DecodeChars[str.charCodeAt(i++) & 0xff];
  } while(i < len && c1 == -1);
  if(c1 == -1)
  break;
  /* c2 */
  do {
  c2 = base64DecodeChars[str.charCodeAt(i++) & 0xff];
  } while(i < len && c2 == -1);
  if(c2 == -1)
  break;
  out += String.fromCharCode((c1 << 2) | ((c2 & 0x30) >> 4));
  /* c3 */
  do {
  c3 = str.charCodeAt(i++) & 0xff;
  if(c3 == 61)
  return out;
  c3 = base64DecodeChars[c3];
  } while(i < len && c3 == -1);
  if(c3 == -1)
  break;
  out += String.fromCharCode(((c2 & 0XF) << 4) | ((c3 & 0x3C) >> 2));
  /* c4 */
  do {
  c4 = str.charCodeAt(i++) & 0xff;
  if(c4 == 61)
  return out;
  c4 = base64DecodeChars[c4];
  } while(i < len && c4 == -1);
  if(c4 == -1)
  break;
  out += String.fromCharCode(((c3 & 0x03) << 6) | c4);
  }
  return out;
  }
  function utf16to8(str) {
  var out, i, len, c;
  out = "";
  len = str.length;
  for(i = 0; i < len; i++) {
  c = str.charCodeAt(i);
  if ((c >= 0x0001) && (c <= 0x007F)) {
  out += str.charAt(i);
  } else if (c > 0x07FF) {
  out += String.fromCharCode(0xE0 | ((c >> 12) & 0x0F));
  out += String.fromCharCode(0x80 | ((c >> 6) & 0x3F));
  out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));
  } else {
  out += String.fromCharCode(0xC0 | ((c >> 6) & 0x1F));
  out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));
  }
  }
  return out;
  }
  function utf8to16(str) {
  var out, i, len, c;
  var char2, char3;
  out = "";
  len = str.length;
  i = 0;
  while(i < len) {
  c = str.charCodeAt(i++);
  switch(c >> 4)
  {
  case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
  // 0xxxxxxx
  out += str.charAt(i-1);
  break;
  case 12: case 13:
  // 110x xxxx 10xx xxxx
  char2 = str.charCodeAt(i++);
  out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F));
  break;
  case 14:
  // 1110 xxxx 10xx xxxx 10xx xxxx
  char2 = str.charCodeAt(i++);
  char3 = str.charCodeAt(i++);
  out += String.fromCharCode(((c & 0x0F) << 12) |
  ((char2 & 0x3F) << 6) |
  ((char3 & 0x3F) << 0));
  break;
  }
  }
  return out;
  }
  function doit() {
  var f = document.f
  f.output.value = base64encode(f.source.value)
  f.decode.value = base64decode(f.output.value)
  }
  </script>
  <H1 align="center">Base64编码加密
  </H1>
  <FORM NAME="f">
  原码<BR>
  <TEXTAREA NAME="source" ROWS=4 COLS=60 WRAP="soft"></TEXTAREA><BR><BR>
  Base64 encode<BR>
  <TEXTAREA NAME="output" ROWS=4 COLS=60 WRAP="soft"></TEXTAREA><BR><BR>
  Base64 decode<BR>
  <TEXTAREA NAME="decode" ROWS=4 COLS=60 WRAP="soft"></TEXTAREA><BR><BR>
  <INPUT TYPE=BUTTON VALUE="转换" ONCLICK="doit()">
  </FORM>
  </td>
  </tr>
  </table>

C#实现BASE64加密、解密算法

自己完成算法实现

  方法一: /// <summary>
  /// Base64加密
  /// </summary>
  /// <param name="Message"></param>
  /// <returns></returns>
  public string Base64Code(string Message)
  {
  char[] Base64Code = new char[]{'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','+','/','='};
  byte empty = (byte)0;
  System.Collections.ArrayList byteMessage = new System.Collections.ArrayList(System.Text.Encoding.Default.GetBytes(Message));
  System.Text.StringBuilder outmessage;
  int messageLen = byteMessage.Count;
  //将 字符分成3个 字节一组,如果不足,则以0补齐
  int page = messageLen / 3;
  int use = 0;
  if ((use = messageLen % 3) > 0)
  {
  for (int i = 0; i < 3 - use; i++)
  byteMessage.Add(empty);
  page++;
  }
  //将3个字节的每组字符转换成4个字节一组的。3个一组,一组一组变成4个字节一组
  //方法是:转换成ASCII码,按顺序排列24 位数据,再把这24位数据分成4组,即每组6位。再在每组的的最高位前补两个0凑足一个字节。
  outmessage = new System.Text.StringBuilder(page * 4);
  for (int i = 0; i < page; i++)
  {
  //取一组3个字节的组
  byte[] instr = new byte[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 = new int[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]]);
  }
  return outmessage.ToString();
  }
  /// <summary>
  /// Base64解密
  /// </summary>
  /// <param name="Message"></param>
  /// <returns></returns>
  public string Base64Decode(string Message)
  {
  if ((Message.Length % 4) != 0)
  {
  throw new ArgumentException("不是正确的BASE64编码,请检查。", "Message");
  }
  if (!System.Text.RegularExpressions.Regex.IsMatch(Message, "^[A-Z0-9/+=]*$", System.Text.RegularExpressions.RegexOptions.IgnoreCase))
  {
  throw new ArgumentException("包含不正确的BASE64编码,请检查。", "Message");
  }
  string Base64Code = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
  int page = Message.Length / 4;
  System.Collections.ArrayList outMessage = new System.Collections.ArrayList(page * 3);
  char[] message = Message.ToCharArray();
  for (int i = 0; i < page; i++)
  {
  byte[] instr = new byte[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 = new byte[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"));
  return System.Text.Encoding.Default.GetString(outbyte);
  }

直接使用.NET中的的库类函数

  方法二:
  /// <summary>
  /// Base64加密
  /// </summary>
  /// <param name="Message"></param>
  /// <returns></returns>
  public string Base64Code(string Message)
  {
  byte[] bytes = Encoding.Default.GetBytes(Message);
  return Convert.ToBase64String(bytes);
  }
  /// <summary>
  /// Base64解密
  /// </summary>
  /// <param name="Message"></param>
  /// <returns></returns>
  public string Base64Decode(string Message)
  {
  byte[] bytes = Convert.FromBase64String(Message);
  return Encoding.Default.GetString(bytes);
  }

Base64-MIME

  在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个“=”;如果没有剩下任何数据,就什么都不要加,这样才可以保证资料还原的正确性。
  举例来说,一段引用自Thomas Hobbes's Leviathan的文句:
  Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a lust of the mind, that by a perseverance of delight in the continued and indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure.
  经过base64编码之后变成:
  TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz
  IHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2Yg
  dGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGlu
  dWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRo
  ZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值