您的位置:首页 > 其它

BASE64 编码原理

2014-11-13 19:01 155 查看
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.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: