由于长度限制,上篇《网络信息传输编码解码》只介绍了编码解码的原理,本篇将把c#,vc,vb,delphi,php,python,asm 等语言的程序代码列于此,有些是从网上搜来的,供大家参考:
一。系统自带函数:
1.c#
//base64 编码 解码 系统函数
//编码
byte[] bytes = Encoding.Default.GetBytes("要转换的字符串");//我是中国人ce d2 ca c7 d6 d0 b9 fa c8 cb
string b64 = Convert.ToBase64String(bytes);//"ztLKx9bQufrIyw==" 是 "我是中国人" base64的编码
//解码
byte[] oo = Convert.FromBase64String(b64);//
string vv =Encoding.Default.GetString ( oo); ;
2. PHP 系统有两个函数可以很方便地实现解码:base64_decode()与quoted_printable_decode(),前者可用于base64 编码的解码,后者是用于 QP 编码方法的解码。
3. python 代码 转换到base64 和qp :
someBytes.append('\x01\xFF\x41\x42\x43\xC0\xC1\xC2\x61\x62\x63',11)
print someBytes.getEncoded("base64")
print someBytes.getEncoded("qp")
二。编写函数
1. C# 编码解码 base64
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace base64WindowsApplication17
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
string yy="我是中国人";
string be = Class1.Base64Code(yy);
string de = Class1.Base64Decode(be);
MessageBox.Show(yy+ " " + be+ " "+ de);
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
namespace base64WindowsApplication17
{
class Class1
// public class Base64Protector
{
/// <summary>
/// Base64加密
/// </summary>
/// <param name="Message">需要加密的字符串</param>
/// <returns>加密后的字符串</returns>
static 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;
int page = messageLen / 3;
int use = 0;
if ((use = messageLen % 3) > 0)
{
for (int i = 0; i < 3 - use; i++)
byteMessage.Add(empty);
page++;
}
outmessage = new System.Text.StringBuilder(page * 4);
for (int i = 0; i < page; i++)
{
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];
int[] outstr = new int[4];
outstr[0] = instr[0] >> 2;
outstr[1] = ((instr[0] & 0x03) << 4) ^ (instr[1] >> 4);
if (!instr[1].Equals(empty))
outstr[2] = ((instr[1] & 0x0f) << 2) ^ (instr[2] >> 6);
else
outstr[2] = 64;
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>
static 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[1] = 0;//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);
}
}
}
2. vc 编码解码 base64
void CBase64Dlg::OnButton1()
{
//
"abc" --> "YWJj"
3字节编码,后补0个
//
"ab"-->"YWI="
2字节编码, 后补1个=
//
"a" --> "YQ=="
1字节编码, 后补2个==
char src_str[]="中国人";//1tC5+sjL
int src_len=strlen(src_str);//+1;
int lenEncode=GetEncodeNewLen(src_str);
unsigned char* pEncodeStr= new unsigned char[lenEncode];
memset(pEncodeStr,0,lenEncode);
Base64_Encode((unsigned char *)src_str,(unsigned char *)pEncodeStr,src_len);//原字符长度
int lenDecode=GetDecodeNewLen((const char *)pEncodeStr);//获得编码后字符串的再解码的长度
unsigned char* pDecodeStr = new unsigned char[lenDecode];
memset(pDecodeStr,0,lenDecode);
Base64_Decode((unsigned char *)pEncodeStr,pDecodeStr,lenEncode);//编码后的字符长度
src_len=0;
char ch[100];
sprintf(ch,"%s, %s, %s",src_str,pEncodeStr,pDecodeStr);
AfxMessageBox(ch);
}
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <string>
unsigned char EncodeIndex[] =
{//编码索引表
'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','+','/','='
};
//解码字母在数组中的序号
A]0(0x00)
a]26(0x1A)
0]52(0x34) +]62(0x3E) /]63(0x3F) =]64(0x40)
unsigned char Base64Code[]="ABCDEFGHIJKLMNOPQRSTUVWX
YZabcdefghijklmnopqrstuv
wxyz0123456789+/=";
unsigned char DecodeIndex[] =
{//解码索引表
0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,//0
00-15
0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,//1
16-31
0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x3E,0x40,0x40,0x40,0x3F,//2
32-47
43[+](0x38)
47[/](0x39)
0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x40,0x40,0x40,0x40,0x40,0x40,//3
48-63
48[0](0x34)- 57[9](0x3D)
61[=](0x40)
0x40,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,//4
64-79
65[A](0x00)- 79[O](0x0E)
0x0F,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x40,0x40,0x40,0x40,0x40,//5
80-95
80[P](0x0F)- 90[Z](0x19)
0x40,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,//6
96-111
97[a](0x1A)-111[o](0x28)
0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,0x30,0x31,0x32,0x33,0x40,0x40,0x40,0x40,0x40 //7 112-127
122[p](0x29)-122[z](0x33)
};
//转换前 aaaaaabb ccccdddd eeffffff
//转换后 00aaaaaa 00bbcccc 00ddddee 00ffffff
//方式1,每个字符通过查找太浪费时间
void Base64_Encode(unsigned char* src,unsigned char* dest, int srclen)
{//编码函数
int sign = 0;
for (int i = 0; i!= srclen; i++,src++,dest++)
{
switch(sign)
{
case 0://编码第1字节
*(dest) = EncodeIndex[*src >> 2];
break;
case 1://编码第2字节
*dest = EncodeIndex[((*(src-1)
& 0x03) << 4) | (((*src) & 0xF0) >> 4)];
break;
case 2://编码第3字节
*dest = EncodeIndex[((*(src-1) &0x0F) << 2) | ((*(src) & 0xC0) >> 6)];
*(++dest) = EncodeIndex[(*(src) &0x3F)];//编码第4字节
break;
}
(sign == 2)?(sign = 0):(sign++);
}
switch(sign)
{//3的余数字节,后补=处理
case 0:
break;
case 1:
//
*(dest++) = EncodeIndex[((*(src-1)
& 0x03) << 4) | (((*src) & 0xF0) >> 4)];
*(dest++) = EncodeIndex[((*(src-1)
& 0x03) << 4) ];
*(dest++) = '=';
*(dest++) = '=';
break;
case 2:
//
*(dest++) = EncodeIndex[((*(src-1) &0x0F) << 2) | ((*(src) & 0xC0) >> 6)];
*(dest++) = EncodeIndex[((*(src-1) &0x0F) << 2)];
*(dest++) = '=';
break;
default:
break;
}
}
/
//方式2比较好,通过数组直接得到其值,比较快
void Base64_Decode(unsigned char* src, unsigned char* dest, int srclen)
{//解码处理函数 //len%4 == 0总为true;
for (int i = 0; i != srclen/4; i++)//对于不足4个的不作计算
{//每个字符,通过数组直接得到其值,比较快
*dest = (DecodeIndex[*src] << 2) | ((DecodeIndex[*(src+1)] & 0x30) >> 4);
*(dest+1) = (DecodeIndex[*(src+1)] << 4) | ((DecodeIndex[*(src+2)] &0x3C) >> 2);
*(dest+2) = ((DecodeIndex[*(src+2)] & 0x03) << 6) | (DecodeIndex[*(src+3)] & 0x3F);
src += 4;
dest += 3;
}
}
//*/
int GetEncodeNewLen(const char * src)
{//求编码后的长度
int len = strlen((char*)src);
return (len +(len%3 == 0? 0:(3-len%3)))/3*4 + 1;
}
int GetDecodeNewLen(const char* src)
{//求解码后的长度
int len = strlen(src);
return len/4*3+1;
}
3. vb 编码解码 base64
Private Sub Command1_Click()
Dim InStr1 As String
Dim en_outstr As String
Dim de_outstr As String
InStr1 = "中国人"
en_outstr = Base64Encode(InStr1)
'en_outstr = "1tC5+sjL"
de_outstr = Base64Decode(en_outstr)
MsgBox (InStr1 + " --> " + en_outstr + " --> " + de_outstr)
End Sub
'VB Enc - Base64位加密程序源代码上
'创建一个新类,即可调用该类的加密和解密方法
'Option Explicit
'Base64编码函数:Base64Encode
'Instr1
编码前字符串
'Outstr1
编码后字符串
Public Function Base64Encode(InStr1 As String) As String
Dim mInByte(3) As Byte, mOutByte(4) As Byte
Dim myByte As Byte
Dim i As Integer, LenArray As Integer, j As Integer
Dim myBArray() As Byte
Dim OutStr1 As String
myBArray() = StrConv(InStr1, vbFromUnicode)
LenArray = UBound(myBArray) + 1
For i = 0 To LenArray Step 3
If LenArray - i = 0 Then
Exit For
End If
If LenArray - i = 2 Then
mInByte(0) = myBArray(i)
mInByte(1) = myBArray(i + 1)
Base64EncodeByte mInByte, mOutByte, 2
ElseIf LenArray - i = 1 Then
mInByte(0) = myBArray(i)
Base64EncodeByte mInByte, mOutByte, 1
Else
mInByte(0) = myBArray(i)
mInByte(1) = myBArray(i + 1)
mInByte(2) = myBArray(i + 2)
Base64EncodeByte mInByte, mOutByte, 3
End If
For j = 0 To 3
OutStr1 = OutStr1 & Chr(mOutByte(j))
Next j
Next i
Base64Encode = OutStr1
End Function
Private Sub Base64EncodeByte(mInByte() As Byte, mOutByte() As Byte, Num As Integer)
Dim tByte As Byte
Dim i As Integer
If Num = 1 Then
mInByte(1) = 0
mInByte(2) = 0
ElseIf Num = 2 Then
mInByte(2) = 0
End If
tByte = mInByte(0) And &HFC
mOutByte(0) = tByte / 4
tByte = ((mInByte(0) And &H3) * 16) + (mInByte(1) And &HF0) / 16
mOutByte(1) = tByte
tByte = ((mInByte(1) And &HF) * 4) + ((mInByte(2) And &HC0) / 64)
mOutByte(2) = tByte
tByte = (mInByte(2) And &H3F)
mOutByte(3) = tByte
For i = 0 To 3
If mOutByte(i) >= 0 And mOutByte(i) <= 25 Then
' 00-25 --> A-Z
mOutByte(i) = mOutByte(i) + Asc("A")
ElseIf mOutByte(i) >= 26 And mOutByte(i) <= 51 Then
' 26-51 --> a-z
mOutByte(i) = mOutByte(i) - 26 + Asc("a")
ElseIf mOutByte(i) >= 52 And mOutByte(i) <= 61 Then
' 52-61 --> 0-9
mOutByte(i) = mOutByte(i) - 52 + Asc("0")
ElseIf mOutByte(i) = 62 Then
'
62 --> +
mOutByte(i) = Asc("+")
Else
mOutByte(i) = Asc("/")
'
63 --> /
End If
Next i
If Num = 1 Then
' 其它后补
=
mOutByte(2) = Asc("=")
mOutByte(3) = Asc("=")
ElseIf Num = 2 Then
mOutByte(3) = Asc("=")
End If
End Sub
Public Function Base64Decode(InStr1 As String) As String
Dim mInByte(4) As Byte, mOutByte(3) As Byte
Dim i As Integer, LenArray As Integer, j As Integer
Dim myBArray() As Byte
Dim OutStr1 As String
Dim tmpArray() As Byte
myBArray() = StrConv(InStr1, vbFromUnicode)
LenArray = UBound(myBArray)
ReDim tmpArray(((LenArray + 1) / 4) * 3)
j = 0
For i = 0 To LenArray Step 4
If LenArray - i = 0 Then
Exit For
Else
mInByte(0) = myBArray(i)
mInByte(1) = myBArray(i + 1)
mInByte(2) = myBArray(i + 2)
mInByte(3) = myBArray(i + 3)
Base64DecodeByte mInByte, mOutByte, 4
End If
tmpArray(j * 3) = mOutByte(0)
tmpArray(j * 3 + 1) = mOutByte(1)
tmpArray(j * 3 + 2) = mOutByte(2)
j = j + 1
Next i
Base64Decode = BinaryToString(tmpArray)
End Function
Private Sub Base64DecodeByte(mInByte() As Byte, mOutByte() As Byte, ByteNum As Integer)
Dim tByte As Byte
Dim i As Integer
ByteNum = 0
For i = 0 To 3 '4 byte
If mInByte(i) >= Asc("A") And mInByte(i) <= Asc("Z") Then
mInByte(i) = mInByte(i) - Asc("A")
' A-Z--> 0-25
ElseIf mInByte(i) >= Asc("a") And mInByte(i) <= Asc("z") Then
mInByte(i) = mInByte(i) - Asc("a") + 26
' a-z-->26-51
ElseIf mInByte(i) >= Asc("0") And mInByte(i) <= Asc("9") Then
mInByte(i) = mInByte(i) - Asc("0") + 52
' 0-9-->52-61
ElseIf mInByte(i) = Asc("+") Then
'
+ --> 62
mInByte(i) = 62
ElseIf mInByte(i) = Asc("/") Then
'
/ --> 63
mInByte(i) = 63
Else '"="
'
= --> 0
ByteNum = ByteNum + 1
mInByte(i) = 0
End If
Next i
'取前六位
tByte = (mInByte(0) And &H3F) * 4 + (mInByte(1) And &H30) / 16
'0的六位和1的前两位
mOutByte(0) = tByte
tByte = (mInByte(1) And &HF) * 16 + (mInByte(2) And &H3C) / 4
'1的后四位和2的前四位
mOutByte(1) = tByte
tByte = (mInByte(2) And &H3) * 64 + (mInByte(3) And &H3F)
mOutByte(2) = tByte
'2的后两位和3的六位
End Sub
Private Function BinaryToString(ByVal BinaryStr As Variant) As String '二进制转换为字符串
Dim lnglen As Long
Dim tmpBin As Variant
Dim strC As String
Dim skipflag As Long
Dim i As Long
skipflag = 0
strC = ""
If Not IsNull(BinaryStr) Then
lnglen = LenB(BinaryStr)
For i = 1 To lnglen
If skipflag = 0 Then
tmpBin = MidB(BinaryStr, i, 1)
If AscB(tmpBin) > 127 Then
strC = strC & Chr(AscW(MidB(BinaryStr, i + 1, 1) & tmpBin))
skipflag = 1
Else
strC = strC & Chr(AscB(tmpBin))
End If
Else
skipflag = 0
End If
Next
End If
BinaryToString = strC
End Function
Private Function StringToBinary(ByVal VarString As String) As Variant '字符串转成二进制
Dim strBin As Variant
Dim varchar As Variant
Dim varasc As Long
Dim varlow, varhigh
Dim i As Long
strBin = ""
For i = 1 To Len(VarString)
varchar = Mid(VarString, i, 1)
varasc = Asc(varchar)
If varasc < 0 Then
varasc = varasc + 65535
End If
If varasc > 255 Then
varlow = Left(Hex(Asc(varchar)), 2)
varhigh = Right(Hex(Asc(varchar)), 2)
strBin = strBin & ChrB("&H" & varlow) & ChrB("&H" & varhigh)
Else
strBin = strBin & ChrB(AscB(varchar))
End If
Next
StringToBinary = strBin
End Function
4.delphi 编码解码 base64
delphi版本的Base64解码编码源代码
Unit CnBase64;
Interface
Uses
SysUtils, Windows;
Function Base64Encode(InputData: String; Var OutputData: String): byte;
{* 对数据进行BASE64编码,如编码成功返回Base64_OK
|InputData:string - 要编码的数据
var OutputData: string - 编码后的数据
|
}
Function Base64Decode(InputData: String; Var OutputData: String): byte;
{* 对数据进行BASE64解码,如解码成功返回Base64_OK
|
InputData:string - 要解码的数据
var OutputData: string - 解码后的数据
|
}
Const
BASE64_OK = 0; // 转换成功
BASE64_ERROR = 1;
// 转换错误(未知错误) (e.g. can't encode octet in input stream) -> error in implementation
BASE64_INVALID = 2;
// 输入的字符串中有非法字符 (在 FilterDecodeInput=False 时可能出现)
BASE64_LENGTH = 3; // 数据长度非法
BASE64_DATALEFT = 4;
// too much input data left (receveived 'end of encoded data' but not end of input string)
BASE64_PADDING = 5; // 输入的数据未能以正确的填充字符结束
Implementation
Var
FilterDecodeInput: Boolean = true;
Const
Base64TableLength = 64;
Base64Table : String[Base64TableLength] =
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+*';
Pad = '=';
Function Base64Encode(InputData: String; Var OutputData: String): byte;
Var
i : integer;
CurrentB, PrevB : byte;
c : byte;
s : char;
InputLength : integer;
Function ValueToCharacter(value: byte; Var character: char): Boolean;
//******************************************************************
// 将一个在0..Base64TableLength-1区间内的值,转换为与Base64编码相对应
// 的字符来表示,如果转换成功则返回True
//******************************************************************
Begin
result := true;
If (value > Base64TableLength - 1) Then
result := false
Else
character := Base64Table[value + 1];
End;
Begin
OutputData := '';
InputLength := Length(InputData);
i := 1;
If (InputLength = 0) Then Begin
result := BASE64_OK;
Exit;
End;
Repeat
// 第一次转换
CurrentB := Ord(InputData[i]);
i := i + 1;
InputLength := InputLength - 1;
c := (CurrentB Shr 2);
If Not ValueToCharacter(c, s) Then Begin
result := BASE64_ERROR;
Exit;
End;
OutputData := OutputData + s;
PrevB := CurrentB;
// 第二次转换
If InputLength = 0 Then
CurrentB := 0
Else Begin
CurrentB := Ord(InputData[i]);
i := i + 1;
End;
InputLength := InputLength - 1;
c := (PrevB And $03) Shl 4 + (CurrentB Shr 4);
//取出XX后4位并将其左移4位与XX右移4位合并成六位
If Not ValueToCharacter(c, s) Then
{//检测取得的字符是否在Base64Table内} Begin
result := BASE64_ERROR;
Exit;
End;
OutputData := OutputData + s;
PrevB := CurrentB;
// 第三次转换
If InputLength < 0 Then
s := Pad
Else Begin
If InputLength = 0 Then
CurrentB := 0
Else Begin
CurrentB := Ord(InputData[i]);
i := i + 1;
End;
InputLength := InputLength - 1;
c := (PrevB And $0F) Shl 2 + (CurrentB Shr 6);
//取出XX后4位并将其左移2位与XX右移6位合并成六位
If Not ValueToCharacter(c, s) Then
{//检测取得的字符是否在Base64Table内} Begin
result := BASE64_ERROR;
Exit;
End;
End;
OutputData := OutputData + s;
// 第四次转换
If InputLength < 0 Then
s := Pad
Else Begin
c := (CurrentB And $3F); //取出XX后6位
If Not ValueToCharacter(c, s) Then
{//检测取得的字符是否在Base64Table内} Begin
result := BASE64_ERROR;
Exit;
End;
End;
OutputData := OutputData + s;
Until InputLength <= 0;
result := BASE64_OK;
End;
Function Base64Decode(InputData: String; Var OutputData: String): byte;
Var
i : integer;
InputLength : integer;
CurrentB, PrevB : byte;
c : byte;
s : char;
Function CharacterToValue(character: char; Var value: byte): Boolean;
//******************************************************************
// 转换字符为一在0..Base64TableLength-1区间中的值,如果转换成功则返
// 回True(即字符在Base64Table中)
//******************************************************************
Begin
result := true;
value := Pos(character, Base64Table);
If value = 0 Then
result := false
Else
value := value - 1;
End;
Function FilterLine(InputData: String): String;
//******************************************************************
// 过滤所有不在Base64Table中的字符,返回值为过滤后的字符
//******************************************************************
Var
F : byte;
i : integer;
Begin
result := '';
For i := 1 To Length(InputData) Do
If CharacterToValue(InputData[i], F) Or (InputData[i] = Pad) Then
result := result + InputData[i];
End;
Begin
If (InputData = '') Then Begin
result := BASE64_OK;
Exit;
End;
OutputData := '';
If FilterDecodeInput Then
InputData := FilterLine(InputData);
InputLength := Length(InputData);
If InputLength Mod 4 <> 0 Then Begin
result := BASE64_LENGTH;
Exit;
End;
i := 0;
Repeat
// 第一次转换
i := i + 1;
s := InputData[i];
If Not CharacterToValue(s, CurrentB) Then Begin
result := BASE64_INVALID;
Exit;
End;
i := i + 1;
s := InputData[i];
If Not CharacterToValue(s, PrevB) Then Begin
result := BASE64_INVALID;
Exit;
End;
c := (CurrentB Shl 2) + (PrevB Shr 4);
OutputData := OutputData + Chr(c);
// 第二次转换
i := i + 1;
s := InputData[i];
If s = Pad Then Begin
If (i <> InputLength - 1) Then Begin
result := BASE64_DATALEFT;
Exit;
End
Else
If InputData[i + 1] <> Pad Then Begin
result := BASE64_PADDING;
Exit;
End;
End
Else Begin
If Not CharacterToValue(s, CurrentB) Then Begin
result := BASE64_INVALID;
Exit;
End;
c := (PrevB Shl 4) + (CurrentB Shr 2);
OutputData := OutputData + Chr(c);
End;
// 第三次转换
i := i + 1;
s := InputData[i];
If s = Pad Then Begin
If (i <> InputLength) Then Begin
result := BASE64_DATALEFT;
Exit;
End;
End
Else Begin
If Not CharacterToValue(s, PrevB) Then Begin
result := BASE64_INVALID;
Exit;
End;
c := (CurrentB Shl 6) + (PrevB);
OutputData := OutputData + Chr(c);
End;
Until (i >= InputLength);
result := BASE64_OK;
End;
End.
Function Base64Encode(mSource: String; mAddLine: Boolean = True): String;
Var
I, J: Integer;
S: String;
Begin
Result := '';
J := 0;
For I := 0 To Length(mSource) Div 3 - 1 Do Begin
S := Copy(mSource, I * 3 + 1, 3);
Result := Result + cBase64[Ord(S[1]) Shr 2 + 1];
Result := Result + cBase64[((Ord(S[1]) And $03) Shl 4) + (Ord(S[2]) Shr 4) + 1];
Result := Result + cBase64[((Ord(S[2]) And $0F) Shl 2) + (Ord(S[3]) Shr 6) + 1];
Result := Result + cBase64[Ord(S[3]) And $3F + 1];
If mAddLine Then Begin
Inc(J, 4);
If J >= 76 Then Begin
Result := Result + #13#10;
J := 0;
End;
End;
End;
I := Length(mSource) Div 3;
S := Copy(mSource, I * 3 + 1, 3);
Case Length(S) Of
1: Begin
Result := Result + cBase64[Ord(S[1]) Shr 2 + 1];
Result := Result + cBase64[(Ord(S[1]) And $03) Shl 4 + 1];
Result := Result + cBase64[65];
Result := Result + cBase64[65];
End;
2: Begin
Result := Result + cBase64[Ord(S[1]) Shr 2 + 1];
Result := Result + cBase64[((Ord(S[1]) And $03) Shl 4) + (Ord(S[2]) Shr 4) + 1];
Result := Result + cBase64[(Ord(S[2]) And $0F) Shl 2 + 1];
Result := Result + cBase64[65];
End;
End;
End; { Base64Encode }
Function Base64Decode(mCode: String): String;
Var
I, L: Integer;
S: String;
Begin
Result := '';
L := Length(mCode);
I := 1;
While I <= L Do Begin
If Pos(mCode[I], cBase64) > 0 Then Begin
S := Copy(mCode, I, 4);
If (Length(S) = 4) Then Begin
Result := Result + Chr((Pos(S[1], cBase64) - 1) Shl 2 +
(Pos(S[2], cBase64) - 1) Shr 4);
If S[3] <> cBase64[65] Then Begin
Result := Result + Chr(((Pos(S[2], cBase64) - 1) And $0F) Shl 4 +
(Pos(S[3], cBase64) - 1) Shr 2);
If S[4] <> cBase64[65] Then
Result := Result + Chr(((Pos(S[3], cBase64) - 1) And $03) Shl 6 +
(Pos(S[4], cBase64) - 1));
End;
End;
Inc(I, 4);
End Else Inc(I);
End;
End; { Base64Decode }
5.asm 编码解码 base64
第一个字符通过右移2位获得第一个目标字符的Base64表位置,根据这个数值取到表上相应的字符,就是第一个目标字符。
然后将第一个字符左移4位加上第二个字符右移4位,即获得第二个目标字符。
再将第二个字符左移2位加上第三个字符右移6位,获得第三个目标字符。
最后取第三个字符的右6位即获得第四个目标字符。
在以上的每一个步骤之后,再把结果与 0x3F 进行 AND 位操作,就可以得到编码后的字符了。
DLL的源代码:Base64Dll.asm
;***********************************************
;程序名称:演示Base64编码/解码原理
;作者:罗聪
;日期:2002-9-14
;出处:http://laoluoc.yeah.net(老罗的缤纷天地)
;注意事项:如欲转载,请保持本程序的完整,并注明:
;转载自“老罗的缤纷天地”(http://laoluoc.yeah.net)
;***********************************************
.386
.modelflat,stdcall
optioncasemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
DllEntry proto:HINSTANCE,:DWORD,:DWORD
Base64Encode proto:DWORD,:DWORD
Base64Decode proto:DWORD,:DWORD
.data
;Base64 -> ASCII mapping table
base64_alphabet db "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
;ASCII -> Base64 mapping table
base64table db43dup(255)
db62,255,255,255,63,52,53,54,55,56,57,58,59,60,61,255
db255,255,0,255,255,255,0,1,2,3,4,5,6,7,8,9,10,11,12,13
db14,15,16,17,18,19,20,21,22,23,24,25,255,255,255,255
db255,255,26,27,28,29,30,31,32,33,34,35,36,37,38
db39,40,41,42,43,44,45,46,47,48,49,50,51
db132dup(255)
.code
DllEntry proc hInst: HINSTANCE, reason:DWORD, reserved1:DWORD
moveax, TRUE
ret
DllEntry endp
;**********************************************************
;函数功能:进行Base64编码
;参数:
; source = 传入的字符串
; destination = 返回的编码
;**********************************************************
Base64Encode proc usesebxediesi source:DWORD, destination:DWORD
LOCAL sourcelen:DWORD
invoke lstrlen, source
mov sourcelen,eax
mov esi, source
mov edi, destination
@@base64loop:
xoreax,eax
.if sourcelen ==1
lodsb ;source ptr + 1
movecx,2 ;bytes to output = 2
movedx,03D3Dh ;padding = 2 byte
dec sourcelen ;length - 1
.elseif sourcelen ==2
lodsw ;source ptr + 2
movecx,3 ;bytes to output = 3
movedx,03Dh ;padding = 1 byte
sub sourcelen,2 ;length - 2
.else
lodsd
movecx,4 ;bytes to output = 4
xoredx,edx ;padding = 0 byte
decesi ;source ptr + 3 (+4-1)
sub sourcelen,3 ;length - 3
.endif
xchgal,ah ;flip eax completely
rol eax,16 ;can this be done faster
xchgal,ah
@@:
push eax
and eax,0FC000000h ;get the last 6 high bits
rol eax,6 ;rotate them into al
mov al, byteptr[offset base64_alphabet +eax] ;get encode character
stosb ;write to destination
pop eax
shl eax,6 ;shift left 6 bits
dec ecx
jnz @B ;loop
cmp sourcelen,0
jnz @@base64loop ;main loop
mov eax,edx ;add padding and null terminate
stosd
ret
Base64Encode endp
;**********************************************************
;函数功能:进行Base64解码
;参数:
; source = 传入的编码
; destination = 返回的字符串
;**********************************************************
Base64Decode proc usesebxediesi source:DWORD, destination:DWORD
LOCAL sourcelen:DWORD
invoke lstrlen, source
mov sourcelen,eax
mov esi, source ;esi <- source
mov edi, destination ;edi <- destination
mov ecx, sourcelen
shr ecx,2
cld
;-------------[decoding part]---------------
@@outer_loop:
push ecx
mov ecx,4
xor ebx,ebx
lodsd
@@inner_loop:
push eax
and eax,0ffh
mov al,byteptr[offset base64table +eax]
cmp al,255
je @@invalid_char
shl ebx,6
or bl,al
pop eax
shr eax,8
dec ecx
jnz @@inner_loop
mov eax,ebx
shl eax,8
xchg ah,al
ror eax,16
xchg ah,al
stosd
dec edi
pop ecx
dec ecx
jnz @@outer_loop
xor eax,eax
jmp @@decode_done
;-------------------------------------------
@@invalid_char:
mov eax,-1
@@decode_done:
ret
Base64Decode ENDP
end DllEntry
;******************** over ********************
;by LC
________________________________________
测试程序:base64.asm
;***********************************************
;程序名称:演示Base64编码/解码原理
;作者:罗聪
;日期:2002-9-14
;出处:http://laoluoc.yeah.net(老罗的缤纷天地)
;注意事项:如欲转载,请保持本程序的完整,并注明:
;转载自“老罗的缤纷天地”(http://laoluoc.yeah.net)
;***********************************************
.386
.modelflat,stdcall
optioncasemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
include Base64Dll.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
includelib Base64Dll.lib
WndProc proto:DWORD,:DWORD,:DWORD,:DWORD
.const
IDC_BUTTON_ENCODE equ 3000
IDC_BUTTON_DECODE equ 3001
IDC_EDIT_INPUT equ 3002
MAXSIZE equ 260
.data
szDlgName db "lc_dialog",0
szCaption db "BASE64 demo by LC",0
szBuffer db 255dup(0)
szText db 340dup(0)
szMsg db 450dup(0)
szTemplate_Encode db "字符串 ""%s"" 的Base64编码是:",13,10,13,10,"%s",0
szTemplate_Decode db "编码 ""%s"" 经过Base64还原后的字符串是:",13,10,13,10,"%s",0
.code
main:
invoke GetModuleHandle, NULL
invoke DialogBoxParam,eax,offset szDlgName,0, WndProc,0
invoke ExitProcess,eax
WndProc procusesedi hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
LOCAL hEdit: HWND
.if uMsg == WM_CLOSE
invoke EndDialog, hWnd,0
.elseif uMsg == WM_COMMAND
moveax, wParam
movedx,eax
shredx,16
movzxeax,ax
.ifedx== BN_CLICKED
.ifeax== IDCANCEL
invoke EndDialog, hWnd, NULL
.elseifeax== IDC_BUTTON_ENCODE ||eax== IDOK
;取得用户输入的字符串:
invoke GetDlgItemText, hWnd, IDC_EDIT_INPUT,addr szBuffer,255
;进行 ASCII->Base64 转换:
invoke Base64Encode,addr szBuffer,addr szText
;格式化输出:
invoke wsprintf,addr szMsg,addr szTemplate_Encode,addr szBuffer,addr szText
;显示结果:
invoke MessageBox, hWnd,addr szMsg,addr szCaption, MB_OK
.elseifeax== IDC_BUTTON_DECODE
;取得用户输入的字符串:
invoke GetDlgItemText, hWnd, IDC_EDIT_INPUT,addr szBuffer,255
;进行 Base64->ASCII 转换:
invoke Base64Decode,addr szBuffer,addr szText
;格式化输出:
invoke wsprintf,addr szMsg,addr szTemplate_Decode,addr szBuffer,addr szText
;显示结果:
invoke MessageBox, hWnd,addr szMsg,addr szCaption, MB_OK
.endif
;全选edit里面的内容:
invoke GetDlgItem, hWnd, IDC_EDIT_INPUT
invoke SendMessage,eax, EM_SETSEL,0,-1
.endif
.else
moveax, FALSE
ret
.endif
moveax, TRUE
ret
WndProc endp
end main
;******************** over ********************
;by LC
________________________________________
测试程序的资源文件:base64.rc
#include "resource.h"
#define IDC_BUTTON_ENCODE 3000
#define IDC_BUTTON_DECODE 3001
#define IDC_EDIT_INPUT 3002
#define IDC_STATIC -1
LC_DIALOG DIALOGEX 10, 10, 195, 60
STYLE DS_SETFONT | DS_CENTER | WS_MINIMIZEBOX | WS_VISIBLE | WS_CAPTION |
WS_SYSMENU
CAPTION "Base64 demo by LC"
FONT 9, "宋体", 0, 0, 0x0
BEGIN
LTEXT "请输入字符串:", IDC_STATIC, 11, 7, 130, 10
EDITTEXT IDC_EDIT_INPUT, 11, 20, 173, 12, ES_AUTOHSCROLL
DEFPUSHBUTTON "编码(&E)", IDC_BUTTON_ENCODE, 38, 39, 52, 15
PUSHBUTTON "解码(&D)", IDC_BUTTON_DECODE, 104, 39, 52, 15
END