您的位置:首页 > 其它

BASE64 编码原理

2013-03-12 12:19 211 查看
unit uBase64;

{
编码原理:
将3个字节转换成4个字节((3 X 8)=24=(4X6)),先读入3个字节,
每读一个字节,左移8位,再右移四次,每次6位,这样就有4个
字节了。
解码原理:
将4个字节转换成3个字节,先读入4个6位(用或运算),每次左
移6位,再右移3次,每次8位,这样就还原了。

补"="符:
Base64将3个字节转变为4个字节,因此,编码后的代码量(以
字节为单位,下同)约比编码前的代码量多了1/3。如果代码量
正好是3的整数倍,那么恰好多了1/3。但如果不是呢?这个时
候“=”终于派上用场啦,当代码量不是3的整数倍时,代码量/3的
余数自然就是2或者1。转换的时候,结果不够6位的用0来补上
相应的位置,之后再在6位的前面补两个0。转换完空出的结果
就用就用“=”来补位,总之要保证最后编码出来得字节数是4的
倍数。

例子:

1、当字符串字符个数为3的倍数时;比如字符串“ABC”,其在计算机内存中的
十六进制表示为$41、$42、$43,十进制表示为“65”“66”“67”;二进制表示
为01000001  01000010  01000011   将这三个二进制数依次取6bit
,010000/01 0100/0010  01/000011  就转换成了:  010000  
010100  001001  000011  将这四个二进制数转换成十六制数为:
$10,$14,$9,$3,十进制数位为16,20,9,3。对照上面的码表,分别查
找出对应的字符为Q,U,J,D。也是就说字符串“ABC”经过BASE64编码后得
出“QUJD”。  这是最简单的情况,即ASCII码字符数刚好可以被3整除。接
着继续讨论余数为2、为1的情况。  

2、当余数为2时,比如字符串“ce”,其在内存中十六进制表示为$63,$65;十
进制表示表示99,101;二进制表示为  01100011 01100101 依次取6bit
 011000/11 0110/0101  这时,第3个字符不足6位,在后面补零,也就
是0101变成010100。转换结果为  011000 110110 010100  这3个二进
制数转换成十六制数为$18,$36,$14;十进制数位为24,54,20。对照码表
得出结果“Y2U”。编码后的字符个数不足4位,用“=”填充,最后编码得出“Y2U=”。
  
3、当余数为1时,比如字符串“{”,其在内存中的十六进制表示为$7B,十进制为
123,二进制位表示为  01111011 依次取6bit 011110/11   补0后为
 011110/110000  转换结果为011110和110000  这两个二进制数转换成
十六进制数为$1E,$30,十进制数为30,48。对照码表得出结果为“ew”,补上
“=”,最后编码得出“ew= =”。  解码也很简单,是编码的逆过程,即将每
个字符对照码表换算成6bit的二进制数,然后重组起来,按8位进行截取,得出原码。

根据上述原始长度<=3的,转码后长度为4即为 Len/3 向上取整后*4
当长度3<Len<=6

Len*8=iLen*6
iLen mod 4 = 0
iLen = 4/3 * Len = Len+1/3*Len 比原始字符多了1/3

1个汉字=2个字节 一个字节=8位
}

interface

uses
Classes,Sysutils;

function EnCodeBase64(Const srcStr:String;Var Base64DestStr:String):Boolean;
function DeCodeBase64(Const Base64Str:String;var DestStr:String):Boolean;

implementation

const
B64: array[0..63] of byte= (65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,
81,82,83,84,85,86,87,88,89,90,97,98,99,100,101,102,103,104,105,106,107,108,
109,110,111,112,113,114,115,116,117,118,119,120,121,122,48,49,50,51,52,53,
54,55,56,57,43,47);

//CodeIndex : String = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';

function Base64Encode(pInput: pointer; pOutput: pointer; Size: longint): longint;
var
i, iptr, optr: integer;
Input, Output: PByteArray;
begin
Input:= PByteArray(pInput); Output:= PByteArray(pOutput);
iptr:= 0; optr:= 0;
for i:= 1 to (Size div 3) do
begin
Output^[optr+0]:= B64[Input^[iptr] shr 2];
Output^[optr+1]:= B64[((Input^[iptr] and 3) shl 4) + (Input^[iptr+1] shr 4)];
Output^[optr+2]:= B64[((Input^[iptr+1] and 15) shl 2) + (Input^[iptr+2] shr 6)];
Output^[optr+3]:= B64[Input^[iptr+2] and 63];
Inc(optr,4); Inc(iptr,3);
end;
case (Size mod 3) of
1: begin
Output^[optr+0]:= B64[Input^[iptr] shr 2];
Output^[optr+1]:= B64[(Input^[iptr] and 3) shl 4];
Output^[optr+2]:= byte('=');
Output^[optr+3]:= byte('=');
end;
2: begin
Output^[optr+0]:= B64[Input^[iptr] shr 2];
Output^[optr+1]:= B64[((Input^[iptr] and 3) shl 4) + (Input^[iptr+1] shr 4)];
Output^[optr+2]:= B64[(Input^[iptr+1] and 15) shl 2];
Output^[optr+3]:= byte('=');
end;
end;
Result:= ((Size+2) div 3) * 4;
end;

function Base64EncodeStr(const Value: string): string;
begin
SetLength(Result,((Length(Value)+2) div 3) * 4);
Base64Encode(@Value[1],@Result[1],Length(Value));
end;

function Base64Decode(pInput: pointer; pOutput: pointer; Size: longint): longint;
var
i, j, iptr, optr: integer;
Temp: array[0..3] of byte;
Input, Output: PByteArray;
begin
Input:= PByteArray(pInput); Output:= PByteArray(pOutput);
iptr:= 0; optr:= 0;
Result:= 0;
for i:= 1 to (Size div 4) do
begin
for j:= 0 to 3 do
begin
case Input^[iptr] of
65..90 : Temp[j]:= Input^[iptr] - Ord('A');
97..122: Temp[j]:= Input^[iptr] - Ord('a') + 26;
48..57 : Temp[j]:= Input^[iptr] - Ord('0') + 52;
43       : Temp[j]:= 62;
47       : Temp[j]:= 63;
61       : Temp[j]:= $FF;
end;
Inc(iptr);
end;
Output^[optr]:= (Temp[0] shl 2) or (Temp[1] shr 4);
Result:= optr+1;
if (Temp[2]<> $FF) and (Temp[3]= $FF) then
begin
Output^[optr+1]:= (Temp[1] shl 4) or (Temp[2] shr 2);
Result:= optr+2;
Inc(optr)
end
else if (Temp[2]<> $FF) then
begin
Output^[optr+1]:= (Temp[1] shl 4) or (Temp[2] shr 2);
Output^[optr+2]:= (Temp[2] shl 6) or    Temp[3];
Result:= optr+3;
Inc(optr,2);
end;
Inc(optr);
end;
end;

function Base64DecodeStr(const Value: string): string;
begin
SetLength(Result,(Length(Value) div 4) * 3);
SetLength(Result,Base64Decode(@Value[1],@Result[1],Length(Value)));
end;

function EnCodeBase64(Const srcStr:String;Var Base64DestStr:String):Boolean;
begin
Result := True;
try
Base64DestStr := Base64EncodeStr(srcStr);
except
Result := False;
end;
end;

function DeCodeBase64(Const Base64Str:String;var DestStr:String):Boolean;
begin
Result := True;
try
DestStr := Base64DecodeStr(Base64Str);
except
Result := False;
end;
end;

end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: