您的位置:首页 > 移动开发 > IOS开发

Base64数据加密与解密

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

APP的数据安全已经牵动着我们开发者的心,简单的MD5/Base64等已经难以满足当下的数据安全标准,本文简单的介绍下AES与Base64的混合加密与解密"
AES:高级加密标准(英语:Advanced EncryptionStandard,缩写:AES),在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。经过五年的甄选流程,高级加密标准由美国国家标准与技术研究院(NIST)于2001年11月26日发布于FIPS PUB197,并在2002年5月26日成为有效的标准。2006年,高级加密标准已然成为对称密钥加密中最流行的算法之一。

标准的Base64并不适合直接放在URL里传输,因为URL编码器会把标准Base64中的“/”和“+”字符变为形如“%XX”的形式,而这些“%”号在存入数据库时还需要再进行转换,因为ANSISQL中已将“%”号用作通配符
为解决此问题,可采用一种用于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编码),这个表是这样的:(摘自RFC2045)
转换列表:

索引
对应字符
索引
对应字符
索引
对应字符
索引
对应字符
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
15
P
32
g
49
x
16
Q
33
h
50
y
原理
转码过程例子:
3*8=4*6
内存1个字符占8位
转前: s 1 3
先转成ascii:对应115 49 51
2进制:01110011 00110001 00110011
6个一组(4组)
011100110011000100110011
然后才有后面的011100 110011 000100 110011
然后计算机是8位8位的存数6不够,自动就补两个高位0了
所有有了 高位补0
科学计算器输入
00011100 0011001100000100
00110011
得到 28 51 451
查对下照表 c zE z
先以“迅雷下载”为例:很多下载类网站都提供“迅雷下载”的链接,其地址通常是加密的迅雷专用下载地址。
其实迅雷的“专用地址”也是用Base64"加密"的,其过程如下:
一、在地址的前后分别添加AA和ZZ
二、对新的字符串进行Base64编码
另:Flashget的与迅雷类似,只不过在第一步时加的“料”不同罢了,Flashget在地址前后加的“料”是[FLASHGET]
而QQ旋风的干脆不加料,直接就对地址进行Base64编码了

***************************************************************************************************

******************************************************************************************************************************************************************************************************

下面我将用代码来阐述其使用方法。首先我们创建一个NSData的类扩展,命名为AES,创建完如果对的话应该是这样的NSData+AES然后导入如下头文件
#import
《CommonCrypto/CommonDigest.h》
#import
《CommonCrypto/CommonCryptor.h》

再增加加解密的方法,方便外部文件的调用,写完.h文件如下

#import
《Foundation/Foundation.h》
#import
《CommonCrypto/CommonDigest.h》
#import
《CommonCrypto/CommonCryptor.h》
@interface NSData (AES)

加密
- (NSData *)AES256_Encrypt:(NSString *)key;

解密
- (NSData *)AES256_Decrypt:(NSString *)key;
追加64编码
- (NSString*)newStringInBase64FromData;
同上64编码
+(NSString*)base64encode:(NSString*)str;
@end

.m文件中依次实现这几个方法,具体如下
#import
"NSData+AES.h"static char base64[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

@implementation NSData(AES)

加密
- (NSData *)AES256_Encrypt:(NSString *)key{

char keyPtr[kCCKeySizeAES256+1];
bzero(keyPtr,
sizeof(keyPtr));
[keygetCString:keyPtr maxLength:sizeof(keyPtr)encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [self length];
size_tbufferSize = dataLength + kCCBlockSizeAES128;

void *buffer = malloc(bufferSize);
size_tnumBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128,
kCCOptionPKCS7Padding |kCCOptionECBMode,
keyPtr, kCCBlockSizeAES128,

NULL,
[selfbytes], dataLength,
buffer, bufferSize,
&numBytesEncrypted);

if (cryptStatus == kCCSuccess) {

return [NSDatadataWithBytesNoCopy:buffer length:numBytesEncrypted];
}
free(buffer);

return nil;}

解密- (NSData *)AES256_Decrypt:(NSString *)key{
char keyPtr[kCCKeySizeAES256+1];
bzero(keyPtr,
sizeof(keyPtr));
[keygetCString:keyPtr maxLength:sizeof(keyPtr)encoding:NSUTF8StringEncoding];
NSUInteger dataLength= [self length];
size_t bufferSize =dataLength + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
size_tnumBytesDecrypted = 0;
CCCryptorStatuscryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128,
kCCOptionPKCS7Padding | kCCOptionECBMode,
keyPtr, kCCBlockSizeAES128,

NULL,
[selfbytes], dataLength,
buffer, bufferSize,
&numBytesDecrypted);
if (cryptStatus == kCCSuccess) {

return [NSData dataWithBytesNoCopy:bufferlength:numBytesDecrypted];

}
free(buffer);
return nil;}

追加64编码-(NSString *)newStringInBase64FromData
{
NSMutableString *dest= [[NSMutableString alloc] initWithString:@""];

unsigned char * working = (unsigned char *)[selfbytes];

int srcLen = (int)[self length];

for (int i=0;i<srclen; i += 3) {
for(int nib="0;nib= srcLen) break;"
unsigned char curr ="((working[i+byt] << (8-ix)) & 0x3F);"
if (i+nib <srclen) curr |=" ((working[i+nib] ">>ix) & 0x3F);

[destappendFormat:@"%c", base64[curr]];

}

}

return dest;}

+(NSString*)base64encode:(NSString*)str{

if ([str length] == 0)

return @"";

const char *source = [str UTF8String];

int strlength = (int)strlen(source);

char *characters = malloc(((strlength + 2) / 3) *4);

if (characters == NULL)

return nil;

NSUInteger length = 0;

NSUInteger i = 0;

while (i < strlength) {

char buffer[3] = {0,0,0};

short bufferLength = 0;

while (bufferLength < 3 &&i < strlength)

buffer[bufferLength++] = source[i++];

characters[length++] = base64[(buffer[0] & 0xFC) >> 2];

characters[length++] = base64[((buffer[0] & 0x03) << 4) |((buffer[1] & 0xF0) >> 4)];

if (bufferLength > 1)

characters[length++] = base64[((buffer[1] & 0x0F)<< 2) | ((buffer[2] & 0xC0) >> 6)];

else characters[length++] = '=';

if (bufferLength > 2)

characters[length++] = base64[buffer[2] & 0x3F];

else characters[length++] = '=';

}

NSString *g = [[NSString alloc] initWithBytesNoCopy:characters length:lengthencoding:NSASCIIStringEncoding freeWhenDone:YES];

return g;}

@end</srclen; i += 3) {>

AES+Base64的加密方式到此已经结束了,下面讲一下单纯的AES字符串加密的。

和上面的基本上差不多,写一个NSString的类扩展,命名为AES,创建完如果对的话应该是这样的NSString+AES导入如下头文件
1

#import
"NSData+AES.h"

同样的把加解密的方法写在.h文件中,写完如下

#import
《Foundation/Foundation.h》
#import
"NSData+AES.h"

@interface NSString (AES)

加密
-(NSString *) AES256_Encrypt:(NSString *)key;

解密
-(NSString *) AES256_Decrypt:(NSString *)key;

@end

.m实现方法

加密
-(NSString *) AES256_Encrypt:(NSString *)key{

const char *cstr = [self cStringUsingEncoding:NSUTF8StringEncoding];
NSData *data = [NSData dataWithBytes:cstr length:self.length];

对数据进行加密
NSData *result = [data AES256_Encrypt:key];

转换为2进制字符串

if (result && result.length> 0) {

Byte *datas = (Byte*)[result bytes];
NSMutableString *output = [NSMutableStringstringWithCapacity:result.length * 2];

for(int i = 0; i < result.length; i++){
[output appendFormat:@"x", datas[i]];
}

return output;
}

return nil;
}

解密
-(NSString *) AES256_Decrypt:(NSString *)key{

转换为2进制Data
NSMutableData *data = [NSMutableData dataWithCapacity:self.length / 2];

unsigned char whole_byte;

char byte_chars[3] ={'\0','\0','\0'};

int i;

for (i=0; i < [self length] / 2; i++) {
byte_chars[0] = [selfcharacterAtIndex:i*2];
byte_chars[1] = [selfcharacterAtIndex:i*2+1];
whole_byte = strtol(byte_chars,
NULL,16);
[data appendBytes:&whole_byte length:1];
}

对数据进行解密
NSData* result = [data AES256_Decrypt:key];

if (result && result.length> 0) {

return [[NSStringalloc] initWithData:result encoding:NSUTF8StringEncoding];
}

return nil;
}

到此我们加密的文件基本上都已经OK了,下面我们来简单的的使用一下,具体如下:
#import
"ViewController.h"
#import
"NSString+AES.h"@interface ViewController ()@end@implementationViewController- (void)viewDidLoad {
[super viewDidLoad];

Do anyadditional setup after loading the view, typically from a nib.

字符串加密 NSString *key = @"12345678";//Key是和后台约定的key哦,不然无法解密....
NSString *secret =
@"aes Bison base64";

NSLog(@"字符串加密---%@",[secret
AES256_Encrypt:key]);

字符串解密 NSLog(@"字符串解密---%@",[[secretAES256_Encrypt:key]
AES256_Decrypt:key]);

NSData加密+base64
NSData*plain = [secret dataUsingEncoding:NSUTF8StringEncoding];
NSData*cipher = [plain AES256_Encrypt:key];
NSLog(@"NSData加密+base64++++%@",[cipher
newStringInBase64FromData]);

解密
plain =[cipher AES256_Decrypt:key];
NSLog(@"NSData解密+base64++++%@",
[[NSString alloc] initWithData:plain encod

***************************************************************************************************

***************************************************************************************************

***************************************************************************************************

Base版:

base64Table=(A B C DE 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 rs 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;
letbin[$idx]=$dividend%2;
dividend=$dividend/2;
done;
done;
letidx=${#str}*8;

for((i=0; i<appendEqualCnt*2; i++)); do
let bin[$idx]=0;
letidx++;
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;
letn=6-1-j;
letsum=sum+${bin[$idx]}*2**n;
done;
echo -n${base64Table[$sum]};
done
}

declare -a bin
functionbase64Encode() {
read -p
"pleaseenter ASCII string:" str;
letappendZero=${#str}*8%6;
letbits=${#str}*8;
appendEqualCnt=0;

if [[ $appendZero -ne 0 ]]; then
letappendEqualCnt=(6-$appendZero)/2;
fi
str2binary;
calcBase64;

if [[ $appendEqualCnt -eq 2 ]]; then
echo -n"==";
elif [[$appendEqualCnt -eq 1 ]]; then
echo -n"=";
fi
echo;

}

***************************************************************************************************

******************************************************************************************************************************************************************************************************
Java版

模板类模板类写好了再按思路写个实现就可以了
publicinterfaceBase64{

/**
*根据传进来的字符的字节码,查询base64码表的索引,并返回所查到的索引
*
*@paramb一个编码后的字节码
*@return返回base64码表的索引
*/
publicabstractbytebaseIndex(byteb);

/**
*解码的方法
*传进来的是编码后的base64字符的字节码
*解析时是4个一组进行解析
*@paramb编码后的字符的字节码数组
*@return返回原来的字符串
*/
publicabstractStringbackEncode(byte[]b);

/**
*解码
*将4个字节码中的第1个的后6位(00xxxxxx)和第2个
*字节的前4位的后2位(00yy0000)
*还原为原来的字节码(xxxxxxyy)
*
*@paramfirst4个字节码中的第1个
*@paramsecond4个字节码中的第2个
*@return原来的字符的字节码
*/publicabstractbytebackFirst(bytefirst,bytesecond);

/**
*解码
*将4个字节码中的第2个的后4位(0000xxxx)和第3个
*字节的前6位的后4位(00yyyy00)
*还原为原来的字节码(xxxxyyyy)
*@paramsecond4个字节码中的第2个
*@paramthird4个字节码中的第3个
*@return原来的字符的字节码
*/
publicabstractbytebackSecond(bytesecond,bytethird);

/**
*解码
*将4个字节码中的第3个的后2位(000000xx)和第4个
*字节的后6位(00yyyyyy)
*还原为原来的字节码(xxyyyyyy)
*@paramthird传进来的第3个字符
*@paramfourth传进来的第4个字符
*@return原来的字符的字节码
*/publicabstractbytebackThird(bytethird,bytefourth);

/**
*解码
*将编码后的字符串数组的最后2个字节码还原为原来的字节码
*假如数组末尾剩下2个字节:
*将倒数第2个字节的前后6位(00xxxxxx)
*和倒数第一个字节的后2位(000000yy)
*还原为原来的编码(xxxxxxyy)
*假如数组末尾剩下3个字节:
*将倒数第2个字节的前后4位(0000xxxx)
*和倒数第一个字节的后4位(0000yyyy)
*还原为原来的编码(xxxxyyyy)
*@paramlast_b倒数第2个字节
*@paramnext_b倒数第1个字节
*@parammove_l倒数第2个字节移动位数的参数
*@parammove_b倒数第1个字节移动位数的参数
*@return原来的字符的字节码
*/
publicbytebackLastOne(bytelast_b,bytenext_b,intmove_l,intmove_b);

/**
*编码
*将传进来的字符编码为base64,返回一个base64的字符串
*编码时3个字节一组进行编码,传进来的是要进行编码的字符串数组
*@paramb要进行编码的字符串数组
*@return编码后的字符串
*/
publicabstractStringencode(byte[]b);

/**
*假如字符长度%3!=0,使用此方法编码末尾字符
*假如b=xxxxyyyy
*假如末尾字节个数等于1:
*将这个字节的前6位作为一个字节(00xxxxyy)
*将这个字节的后6位作为一个字节(00xxyyyy)
*假如末尾字节个数等于2:
*将这个字节的后6位作为一个字节(00xxyyyy)
*@paramb末尾的字符的字节码
*@parammove末尾的字符的字节码要移动的位数的参数
*@return编码后的字节码
*/
publicabstractbytelastOneByte(byteb,intmove);

/**
*编码
*假如b=xxxxyyyy
*将第1个字节的前6位编码为base64
*将3个字节中的第1个子节码转为(00xxxxyy)
*@paramb3个字节中的第1个字节
*@return编码后的字节码
*/
publicabstractbytefirstByte(byteb);

/**
*编码
*假如last_b=xxxxyyyynext_b=kkkkffff
*将3个字节中的第1个字节的最后2位(000000yy)
*和第2个字节的前4位(kkkk0000)编码为(00yykkkk)
*
*@paramlast_b3个字节中的第1个字节
*@paramnext_b3个字节中的第2个字节
*@return编码后的字节码
*/
publicabstractbytesecondByte(bytelast_b,bytenext_b);

/**
*编码
*假如last_b=xxxxyyyynext_b=kkkkffff
*将3个字节中的第2个字节的最后4位(0000yyyy)
*和第4个字节的前2位(kk000000)编码为(00yyyykk)
*
*
*@paramlast_b3个字节中的第2个字节
*@paramnext_b3个字节中的第3个字节
*@return编码后的字节码
*/
publicabstractbytethirdByte(bytelast_b,bytenext_b);

/**
*编码
*假如b=xxxxyyyy
*将3个字节中的第3个字节的最后6位(00xxyyyy)
*转码为(00xxyyyy)
*@paramb3个字节中的第3个字节
*@return编码后的字节码
*/
publicabstractbytefourthByte(byteb);
}
===================================以下是实现类代码=======================================
importjava.util.Enumeration;
importjava.util.Vector;
publicclassMyBase64EncoderimplementsBase64{

/**
*base64码表
*/
privatestaticfinalbytebase[]={0x41,0x42,0x43,0x44,0x45,0x46,
0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,0x50,0x51,
0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x61,0x62,
0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,
0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,
0x79,0x7a,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,
0x39,0x2b,0x2f};

@Override
publicbytebaseIndex(byteb){

for(inti=0;i<base.length;i++){

if(base[i]==b){

return(byte)i;
}
}

return-1;
}

@Override
publicStringbackEncode(byte[]b){
StringBuffersb=newStringBuffer();
Vector<Byte>list=newVector<Byte>();
intreal_len=b.length;
intlen=real_len-2;
intmore_len=len&3;
intuse_len=len-more_len;

for(inti=0;i<use_len;i+=4){
list.add(backFirst(baseIndex(b[i]),baseIndex(b[i+1])));
list.add(backSecond(baseIndex(b[i+1]),baseIndex(b[i+2])));
list.add(backThird(baseIndex(b[i+2]),baseIndex(b[i+3])));
}
Enumeratione=list.elements();
bytebytes[]=newbyte[list.size()];
intk=-1;

while(e.hasMoreElements()){
bytes[++k]=(Byte)e.nextElement();
}
sb.append(newString(bytes));

if(more_len==2){
byteb_1[]=newbyte[1];
b_1[0]=backLastOne(baseIndex(b[len-2]),baseIndex(b[len-1]),2,6);
sb.append(newString(b_1));
}

if(more_len==3){
byteb_2[]=newbyte[2];
b_2[0]=backFirst(baseIndex(b[len-3]),baseIndex(b[len-2]));
b_2[1]=backLastOne(baseIndex(b[len-2]),baseIndex(b[len-1]),4,4);
sb.append(newString(b_2));
}
returnsb.toString();
}
@Override
publicbytelastOneByte(byteb,intmove){
intr_b=b&0xff;
r_b=r_b<<move;
r_b=r_b>>>2;

return(byte)(r_b&0x3f);
}
@Override
publicbytebackLastOne(bytelast_b,bytenext_b,intmove_l,intmove_b){
intr_l=last_b&0xff;
intr_n=next_b&0xff;
r_l=r_l<<move_l;
r_n=r_n<<move_b;
r_n=r_n>>>move_b;

return(byte)((r_l|r_n)&0xff);
}
@Override
publicbytebackFirst(bytefirst,bytesecond){
intr_f=first&0xff;
intr_s=second&0xff;
r_f=r_f<<2;
r_s=r_s>>>4;

return(byte)((r_f|r_s)&0xff);
}

@Override
publicbytebackSecond(bytesecond,bytethird){
intr_s=second&0xff;
intr_t=third&0xff;
r_s=r_s<<4;
r_t=r_t>>>2;

return(byte)((r_s|r_t)&0xff);
}

@Override
publicbytebackThird(bytethird,bytefourth){
intr_t=third&0xff;
intr_f=fourth&0xff;
r_t=r_t<<6;

return(byte)((r_t|r_f)&0xff);
}

@Override
publicStringencode(byte[]b){
StringBuffersb=newStringBuffer();
intlen=b.length;
intmore_len=len%3;
intuse_len=len-more_len;
byte[]bytes=newbyte[4];

for(inti=0;i<use_len;i+=3){
bytes[0]=base[firstByte(b[i])];
bytes[1]=base[secondByte(b[i],b[i+1])];
bytes[2]=base[thirdByte(b[i+1],b[i+2])];
bytes[3]=base[fourthByte(b[i+2])];
sb.append(newString(bytes));
}

if(more_len==1){
byteb_2[]=newbyte[2];
b_2[0]=base[firstByte(b[len-1])];
b_2[1]=base[lastOneByte(b[len-1],6)];
sb.append(newString(b_2));
returnsb.append("==").toString();
}elseif(more_len==2){
byteb_3[]=newbyte[3];
b_3[0]=base[firstByte(b[len-2])];
b_3[1]=base[secondByte(b[len-2],b[len-1])];
b_3[2]=base[lastOneByte(b[len-1],4)];
sb.append(newString(b_3));
returnsb.append("=").toString();
}
returnsb.toString();
}

@Override
publicbytefirstByte(byteb){

00000000000000000000000001010011

01010011
intr_f=b&0xff;
r_f=r_f>>>2;

return(byte)(r_f&0x3f);
}

@Override
publicbytesecondByte(bytelast_b,bytenext_b){
intr_l=last_b&0xff;
intr_n=next_b&0xff;
r_l=r_l<<6;
r_l=r_l>>>2;
r_n=r_n>>>4;

return(byte)((r_l|r_n)&0x3f);
}

@Override
publicbytethirdByte(bytelast_b,bytenext_b){
intr_l=last_b&0xff;
intr_n=next_b&0xff;
r_l=r_l<<4;
r_l=r_l>>>2;
r_n=r_n>>>6;

return(byte)((r_l|r_n)&0x3f);
}

@Override
publicbytefourthByte(byteb){
intr_b=b&0xff;
r_b=r_b<<2;
r_b=r_b>>>2;

return(byte)(r_b&0x3f);
}
}

***************************************************************************************************

***************************************************************************************************

***************************************************************************************************
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>

***************************************************************************************************

***************************************************************************************************

***************************************************************************************************

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

OptionExplicit
'Base64Encoding/DecodingAlgorithm
'By:DavidMidkiff(mznull@earthlink.net)
'
'ThisalgorithmsencodesanddecodesdataintoBase64
'format.Thisformatisextremelymoreefficientthan
'Hexadecimalencoding.
Privatem_bytIndex(0To63)AsByte
Privatem_bytReverseIndex(0To255)AsByte
PrivateConstk_bytEqualSignAsByte=61
PrivateConstk_bytMask1AsByte=3
PrivateConstk_bytMask2AsByte=15
PrivateConstk_bytMask3AsByte=63
PrivateConstk_bytMask4AsByte=192
PrivateConstk_bytMask5AsByte=240
PrivateConstk_bytMask6AsByte=252
PrivateConstk_bytShift2AsByte=4
PrivateConstk_bytShift4AsByte=16
PrivateConstk_bytShift6AsByte=64
PrivateConstk_lMaxBytesPerLineAsLong=152
PrivateDeclareSubCopyMemoryLib"kernel32"Alias"RtlMoveMemory"(ByValDestinationAsLong,ByValSourceAsLong,ByValLengthAsLong)
PublicFunctionDecode64(sInputAsString)AsString
IfsInput=""ThenExitFunction
Decode64=StrConv(DecodeArray64(sInput),vbUnicode)
EndFunction
PrivateFunctionDecodeArray64(sInputAsString)AsByte()
DimbytInput()AsByte
DimbytWorkspace()AsByte
DimbytResult()AsByte
DimlInputCounterAsLong
DimlWorkspaceCounterAsLong
bytInput=Replace(Replace(sInput,vbCrLf,""),"=","")
ReDimbytWorkspace(LBound(bytInput)To(UBound(bytInput)*2))AsByte
lWorkspaceCounter=LBound(bytWorkspace)
ForlInputCounter=LBound(bytInput)ToUBound(bytInput)
bytInput(lInputCounter)=m_bytReverseIndex(bytInput(lInputCounter))
NextlInputCounter
ForlInputCounter=LBound(bytInput)To(UBound(bytInput)-((UBound(bytInput)Mod8)+8))Step8
bytWorkspace(lWorkspaceCounter)=(bytInput(lInputCounter)*k_bytShift2)+(bytInput(lInputCounter+2)\k_bytShift4)
bytWorkspace(lWorkspaceCounter+1)=((bytInput(lInputCounter+2)Andk_bytMask2)*k_bytShift4)+(bytInput(lInputCounter+4)\k_bytShift2)
bytWorkspace(lWorkspaceCounter+2)=((bytInput(lInputCounter+4)Andk_bytMask1)*k_bytShift6)+bytInput(lInputCounter+6)
lWorkspaceCounter=lWorkspaceCounter+3
NextlInputCounter
SelectCase(UBound(bytInput)Mod8):
Case3:
bytWorkspace(lWorkspaceCounter)=(bytInput(lInputCounter)*k_bytShift2)+(bytInput(lInputCounter+2)\k_bytShift4)
Case5:
bytWorkspace(lWorkspaceCounter)=(bytInput(lInputCounter)*k_bytShift2)+(bytInput(lInputCounter+2)\k_bytShift4)
bytWorkspace(lWorkspaceCounter+1)=((bytInput(lInputCounter+2)Andk_bytMask2)*k_bytShift4)+(bytInput(lInputCounter+4)\k_bytShift2)
lWorkspaceCounter=lWorkspaceCounter+1
Case7:
bytWorkspace(lWorkspaceCounter)=(bytInput(lInputCounter)*k_bytShift2)+(bytInput(lInputCounter+2)\k_bytShift4)
bytWorkspace(lWorkspaceCounter+1)=((bytInput(lInputCounter+2)Andk_bytMask2)*k_bytShift4)+(bytInput(lInputCounter+4)\k_bytShift2)
bytWorkspace(lWorkspaceCounter+2)=((bytInput(lInputCounter+4)Andk_bytMask1)*k_bytShift6)+bytInput(lInputCounter+6)
lWorkspaceCounter=lWorkspaceCounter+2
EndSelect
ReDimbytResult(LBound(bytWorkspace)TolWorkspaceCounter)AsByte
IfLBound(bytWorkspace)=0ThenlWorkspaceCounter=lWorkspaceCounter+1
CopyMemoryVarPtr(bytResult(LBound(bytResult))),VarPtr(bytWorkspace(LBound(bytWorkspace))),lWorkspaceCounter
DecodeArray64=bytResult
EndFunction
PublicFunctionEncode64(ByRefsInputAsString)AsString
IfsInput=""ThenExitFunction
DimbytTemp()AsByte
bytTemp=StrConv(sInput,vbFromUnicode)
Encode64=EncodeArray64(bytTemp)
EndFunction
PrivateFunctionEncodeArray64(ByRefbytInput()AsByte)AsString
OnErrorGoToErrorHandler
DimbytWorkspace()AsByte,bytResult()AsByte
DimbytCrLf(0To3)AsByte,lCounterAsLong
DimlWorkspaceCounterAsLong,lLineCounterAsLong
DimlCompleteLinesAsLong,lBytesRemainingAsLong
DimlpWorkSpaceAsLong,lpResultAsLong
DimlpCrLfAsLong
IfUBound(bytInput)<1024Then
ReDimbytWorkspace(LBound(bytInput)To(LBound(bytInput)+4096))AsByte
Else
ReDimbytWorkspace(LBound(bytInput)To(UBound(bytInput)*4))AsByte
EndIf
lWorkspaceCounter=LBound(bytWorkspace)
ForlCounter=LBound(bytInput)To(UBound(bytInput)-((UBound(bytInput)Mod3)+3))Step3
bytWorkspace(lWorkspaceCounter)=m_bytIndex((bytInput(lCounter)\k_bytShift2))
bytWorkspace(lWorkspaceCounter+2)=m_bytIndex(((bytInput(lCounter)Andk_bytMask1)*k_bytShift4)+((bytInput(lCounter+1))\k_bytShift4))
bytWorkspace(lWorkspaceCounter+4)=m_bytIndex(((bytInput(lCounter+1)Andk_bytMask2)*k_bytShift2)+(bytInput(lCounter+2)\k_bytShift6))
bytWorkspace(lWorkspaceCounter+6)=m_bytIndex(bytInput(lCounter+2)Andk_bytMask3)
lWorkspaceCounter=lWorkspaceCounter+8
NextlCounter
SelectCase(UBound(bytInput)Mod3):
Case0:
bytWorkspace(lWorkspaceCounter)=m_bytIndex((bytInput(lCounter)\k_bytShift2))
bytWorkspace(lWorkspaceCounter+2)=m_bytIndex((bytInput(lCounter)Andk_bytMask1)*k_bytShift4)
bytWorkspace(lWorkspaceCounter+4)=k_bytEqualSign
bytWorkspace(lWorkspaceCounter+6)=k_bytEqualSign
Case1:
bytWorkspace(lWorkspaceCounter)=m_bytIndex((bytInput(lCounter)\k_bytShift2))
bytWorkspace(lWorkspaceCounter+2)=m_bytIndex(((bytInput(lCounter)Andk_bytMask1)*k_bytShift4)+((bytInput(lCounter+1))\k_bytShift4))
bytWorkspace(lWorkspaceCounter+4)=m_bytIndex((bytInput(lCounter+1)Andk_bytMask2)*k_bytShift2)
bytWorkspace(lWorkspaceCounter+6)=k_bytEqualSign
Case2:
bytWorkspace(lWorkspaceCounter)=m_bytIndex((bytInput(lCounter)\k_bytShift2))
bytWorkspace(lWorkspaceCounter+2)=m_bytIndex(((bytInput(lCounter)Andk_bytMask1)*k_bytShift4)+((bytInput(lCounter+1))\k_bytShift4))
bytWorkspace(lWorkspaceCounter+4)=m_bytIndex(((bytInput(lCounter+1)Andk_bytMask2)*k_bytShift2)+((bytInput(lCounter+2))\k_bytShift6))
bytWorkspace(lWorkspaceCounter+6)=m_bytIndex(bytInput(lCounter+2)Andk_bytMask3)
EndSelect
lWorkspaceCounter=lWorkspaceCounter+8
IflWorkspaceCounter<=k_lMaxBytesPerLineThen
EncodeArray64=Left$(bytWorkspace,InStr(1,bytWorkspace,Chr$(0))-1)
Else
bytCrLf(0)=13
bytCrLf(1)=0
bytCrLf(2)=10
bytCrLf(3)=0
ReDimbytResult(LBound(bytWorkspace)ToUBound(bytWorkspace))
lpWorkSpace=VarPtr(bytWorkspace(LBound(bytWorkspace)))
lpResult=VarPtr(bytResult(LBound(bytResult)))
lpCrLf=VarPtr(bytCrLf(LBound(bytCrLf)))
lCompleteLines=Fix(lWorkspaceCounter/k_lMaxBytesPerLine)
ForlLineCounter=0TolCompleteLines
CopyMemorylpResult,lpWorkSpace,k_lMaxBytesPerLine
lpWorkSpace=lpWorkSpace+k_lMaxBytesPerLine
lpResult=lpResult+k_lMaxBytesPerLine
CopyMemorylpResult,lpCrLf,4&
lpResult=lpResult+4&
NextlLineCounter
lBytesRemaining=lWorkspaceCounter-(lCompleteLines*k_lMaxBytesPerLine)
IflBytesRemaining>0ThenCopyMemorylpResult,lpWorkSpace,lBytesRemaining
EncodeArray64=Left$(bytResult,InStr(1,bytResult,Chr$(0))-1)
EndIf
ExitFunction
ErrorHandler:
ErasebytResult
EncodeArray64=bytResult
EndFunction
PrivateSubClass_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("/")EndSub

***************************************************************************************************

***************************************************************************************************

***************************************************************************************************

JS版

varbase64EncodeChars="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
varbase64DecodeChars=newArray(
-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);
functionbase64encode(str)
{
varreturnVal,i,len;
varc1,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);
}
returnreturnVal;
}
functionbase64decode(str)
{
varc1,c2,c3,c4;
vari,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)
returnreturnVal;
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)
returnreturnVal;
c4=base64DecodeChars[c4];
}while(i<len&&c4==-1);

if(c4==-1)

break;
returnVal+=String.fromCharCode(((c3&0x03)<<6)|c4);
}
returnreturnVal;
}

AS3版的Base64
packagecrypto{
importflash.utils.ByteArray;
publicclassBase64{
privatestaticconstBASE64_CHARS:String="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
publicstaticfunctionencode(data:String):String{

ConvertstringtoByteArray
varbytes:ByteArray=newByteArray();
bytes.writeUTFBytes(data);

ReturnencodedByteArray
returnencodeByteArray(bytes);
}
publicstaticfunctionencodeByteArray(data:ByteArray):String{

Initialiseoutput
varoutput:String="";

Createdataandoutputbuffers
vardataBuffer:Array;
varoutputBuffer:Array=newArray(4);

RewindByteArray
data.position=0;

whiletherearestillbytestobeprocessed

while(data.bytesAvailable>0){

Createnewdatabufferandpopulatenext3bytesfromdata
dataBuffer=newArray();

for(vari:uint=0;i<3&&data.bytesAvailable>0;i++){
dataBuffer=data.readUnsignedByte();
}

ConverttodatabufferBase64characterpositionsand

storeinoutputbuffer
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;

Ifdatabufferwasshort(i.enot3characters)thenset

endcharacterindexesindatabuffertoindexof'='symbol.

ThisisnecessarybecauseBase64dataisalwaysamultipleof

4bytesandisbasseswith'='symbols.

for(varj:uint=dataBuffer.length;j<3;j++){
outputBuffer[j+1]=64;
}

LoopthroughoutputbufferandaddBase64charactersto

encodeddatastringforeachcharacter.

for(vark:uint=0;k<outputBuffer.length;k++){
output+=BASE64_CHARS.charAt(outputBuffer[k]);
}
}

Returnencodeddata
returnoutput;
}
publicstaticfunctiondecode(data:String):String{

DecodedatatoByteArray
varbytes:ByteArray=decodeToByteArray(data);

Converttostringandreturn
returnbytes.readUTFBytes(bytes.length);
}
publicstaticfunctiondecodeToByteArray(data:String):ByteArray{

InitialiseoutputByteArrayfordecodeddata
varoutput:ByteArray=newByteArray();

Createdataandoutputbuffers
vardataBuffer:Array=newArray(4);
varoutputBuffer:Array=newArray(3);

Whiletherearedatabyteslefttobeprocessed

for(vari:uint=0;i<data.length;i+=4){

PopulatedatabufferwithpositionofBase64charactersfor

next4bytesfromencodeddata

for(varj:uint=0;j<4&&i+j<data.length;j++){
dataBuffer[j]=BASE64_CHARS.indexOf(data.charAt(i+j));
}

Decodedatabufferbackintobytes
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];

Addallnon-paddedbytesinoutputbuffertodecodeddata

for(vark:uint=0;k<outputBuffer.length;k++){

if(dataBuffer[k+1]==64)break;
output.writeByte(outputBuffer[k]);
}
}

RewinddecodeddataByteArray
output.position=0;

Returndecodeddata
returnoutput;
}
publicfunctionBase64(){
thrownewError("Base64classisstaticcontaineronly");
}
}
}

***************************************************************************************************

***************************************************************************************************

***************************************************************************************************

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 functionencodeStr(data:String):String {
var bytes:ByteArray =
newByteArray();
bytes.writeUTFBytes(data);

return encode(bytes);
}

public static functiondecodeStr(data:String):String {
var bytes:ByteArray = decode(data);
bytes.position = 0;

returnbytes.readUTFBytes(bytes.length);
}

public static functionencode(data:ByteArray):String
{
var
out:ByteArray = new ByteArray();

Presettingthe 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.6to 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)
Needone "=" 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 functiondecode(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 =
newByteArray();
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

returnbyteString;
}

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

returnbyteString;
}

c4 = _decodeChars[int(c4)];

if (c4 == -1)

break;

byteString[int(outPos++)]= ((c3 & 0x03) << 6) | c4;
}
byteString.length = outPos

return byteString;
}

public static functionInitEncoreChar():Vector.<int>
{
var encodeChars:Vector.<int> =
new Vector.<int>(64,true);

Wecould push the number directly

butI 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 functionInitDecodeChar():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;
}

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