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