char[] BaseTable=new char[64]{ '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','+','/'}; 接下来,在加密的时候就是对于需要加密的每个字符,通过一定的算法,转换成上面64字符的一种;而在解密的时候则是把64字符中任意一个字符反算出加密前的字符。对于每个字符的操作有很多方法,这里就不一一介绍了。需要注意的是“=”字符,在Base64加密算法中,是很重要的,它是起到补零作用。 以下是完整代码: //----------------------------- Base64 class -------------------------------------- //--------------------------------------------------------------------------------- //---file:clsBase64 //---Description:The class file to encode string or decode string in base algorith //---Author:Knight //---Date:Oct.8, 2005 //--------------------------------------------------------------------------------- //----------------------------{ Base64 class }------------------------------------- using System; namespace Base64 { /**//// <summary> /// Summary description for clsBase64. /// </summary> public class clsBase64 { private char[] source; private char[] lookupTable; private int length, length2, length3; private int blockCount; private int paddingCount; public clsBase64() { // // TODO: Add constructor logic here // source = null; length = length2 = length3 =0; blockCount = 0; paddingCount = 0; } /**//// <summary> /// Create base64 char array using default base64 char array /// </summary> /// <param name="CreatePara"></param> /// <returns>return the new base64 char array</returns> private char[] CreateBase64Char( ref char[] CreatePara ) { char[] BaseTable=new char[64]{ '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','+','/'}; const int CREATE_TYPE = 8; byte bParavalue = 0; byte bTemp; for( int i = 0; i < CreatePara.Length; i++ ) { bTemp = ( byte )( CreatePara[i] ); switch( bTemp % CREATE_TYPE ) { case 1: // 00000001 bTemp =( byte )( bTemp ^ 0x01 ); break; case 2: // 00000010 bTemp =( byte )( bTemp ^ 0x02 ); break; case 3: // 00000100 bTemp =( byte )( bTemp ^ 0x04 ); break; case 4: // 00001000 bTemp =( byte )( bTemp ^ 0x08 ); break; case 5: // 00010000 bTemp =( byte )( bTemp ^ 0x10 ); break; case 6: // 00100000 bTemp =( byte )( bTemp ^ 0x20 ); break; case 7: // 01000000 bTemp =( byte )( bTemp ^ 0x40 ); break; default: // 10000000 bTemp =( byte )( bTemp ^ 0x80 ); break; } bParavalue =( byte )( bParavalue ^ bTemp ); } char chrTemp; int nIndex; switch( bParavalue % CREATE_TYPE ) { case 1: // Exechange 0 <--> 1, 2 <--> 3, 4 <--> 5, 6 <--> 7 for( int i = 0; i < BaseTable.Length / CREATE_TYPE; i++ ) { nIndex = i * CREATE_TYPE; chrTemp = BaseTable[nIndex]; BaseTable[nIndex] = BaseTable[nIndex + 1]; BaseTable[nIndex + 1] = chrTemp; chrTemp = BaseTable[nIndex + 2]; BaseTable[nIndex + 2] = BaseTable[nIndex + 3]; BaseTable[nIndex + 3] = chrTemp; chrTemp = BaseTable[nIndex + 4]; BaseTable[nIndex + 4] = BaseTable[nIndex + 5]; BaseTable[nIndex + 5] = chrTemp; chrTemp = BaseTable[nIndex + 6]; BaseTable[nIndex + 6] = BaseTable[nIndex + 7]; BaseTable[nIndex + 7] = chrTemp; } break; case 2: // Exechange 0 <--> 2, 1 <--> 3, 4 <--> 6, 5 <--> 7 for( int i = 0; i < BaseTable.Length / CREATE_TYPE; i++ ) { nIndex = i * CREATE_TYPE; chrTemp = BaseTable[nIndex]; BaseTable[nIndex] = BaseTable[nIndex + 2]; BaseTable[nIndex + 2] = chrTemp; chrTemp = BaseTable[nIndex + 1]; BaseTable[nIndex + 1] = BaseTable[nIndex + 3]; BaseTable[nIndex + 3] = chrTemp; chrTemp = BaseTable[nIndex + 4]; BaseTable[nIndex + 4] = BaseTable[nIndex + 6]; BaseTable[nIndex + 6] = chrTemp; chrTemp = BaseTable[nIndex + 5]; BaseTable[nIndex + 5] = BaseTable[nIndex + 7]; BaseTable[nIndex + 7] = chrTemp; } break; case 3: // Exechange 0 <--> 3, 1 <--> 2, 4 <--> 7, 5 <--> 6 for( int i = 0; i < BaseTable.Length / CREATE_TYPE; i++ ) { nIndex = i * CREATE_TYPE; chrTemp = BaseTable[nIndex]; BaseTable[nIndex] = BaseTable[nIndex + 3]; BaseTable[nIndex + 3] = chrTemp; chrTemp = BaseTable[nIndex + 1]; BaseTable[nIndex + 1] = BaseTable[nIndex + 2]; BaseTable[nIndex + 2] = chrTemp; chrTemp = BaseTable[nIndex + 4]; BaseTable[nIndex + 4] = BaseTable[nIndex + 7]; BaseTable[nIndex + 7] = chrTemp; chrTemp = BaseTable[nIndex + 5]; BaseTable[nIndex + 5] = BaseTable[nIndex + 6]; BaseTable[nIndex + 6] = chrTemp; } break; case 4: // Mirror exechange for( int i = 0; i < BaseTable.Length / CREATE_TYPE; i++ ) { nIndex = i * CREATE_TYPE; chrTemp = BaseTable[nIndex]; BaseTable[nIndex] = BaseTable[nIndex + CREATE_TYPE - 1]; BaseTable[nIndex + CREATE_TYPE - 1] = chrTemp; chrTemp = BaseTable[nIndex + 1]; BaseTable[nIndex + 1] = BaseTable[nIndex + CREATE_TYPE - 2]; BaseTable[nIndex + CREATE_TYPE - 2] = chrTemp; chrTemp = BaseTable[nIndex + 2]; BaseTable[nIndex + 2] = BaseTable[nIndex + CREATE_TYPE - 3]; BaseTable[nIndex + CREATE_TYPE - 3] = chrTemp; chrTemp = BaseTable[nIndex + 3]; BaseTable[nIndex + 3] = BaseTable[nIndex + CREATE_TYPE - 4]; BaseTable[nIndex + CREATE_TYPE - 4] = chrTemp; } break; case 5: // Exechange 0 <--> 4, 1 <--> 5, 2 <--> 6, 3 <--> 7 for( int i = 0; i < BaseTable.Length / CREATE_TYPE; i++ ) { nIndex = i * CREATE_TYPE; chrTemp = BaseTable[nIndex]; BaseTable[nIndex] = BaseTable[nIndex + 4]; BaseTable[nIndex + 4] = chrTemp; chrTemp = BaseTable[nIndex + 1]; BaseTable[nIndex + 1] = BaseTable[nIndex + 5]; BaseTable[nIndex + 5] = chrTemp; chrTemp = BaseTable[nIndex + 2]; BaseTable[nIndex + 2] = BaseTable[nIndex + 6]; BaseTable[nIndex + 6] = chrTemp; chrTemp = BaseTable[nIndex + 3]; BaseTable[nIndex + 3] = BaseTable[nIndex + 7]; BaseTable[nIndex + 7] = chrTemp; } break; case 6: // Exechange 0 <--> 5, 1 <--> 6, 2 <--> 7, 3 <--> 4 for( int i = 0; i < BaseTable.Length / CREATE_TYPE; i++ ) { nIndex = i * CREATE_TYPE; chrTemp = BaseTable[nIndex]; BaseTable[nIndex] = BaseTable[nIndex + 5]; BaseTable[nIndex + 5] = chrTemp; chrTemp = BaseTable[nIndex + 1]; BaseTable[nIndex + 1] = BaseTable[nIndex + 6]; BaseTable[nIndex + 6] = chrTemp; chrTemp = BaseTable[nIndex + 2]; BaseTable[nIndex + 2] = BaseTable[nIndex + 7]; BaseTable[nIndex + 7] = chrTemp; chrTemp = BaseTable[nIndex + 3]; BaseTable[nIndex + 3] = BaseTable[nIndex + 4]; BaseTable[nIndex + 4] = chrTemp; } break; case 7: // Exechange 0 <--> 6, 1 <--> 7, 2 <--> 4, 3 <--> 5 for( int i = 0; i < BaseTable.Length / CREATE_TYPE; i++ ) { nIndex = i * CREATE_TYPE; chrTemp = BaseTable[nIndex]; BaseTable[nIndex] = BaseTable[nIndex + 6]; BaseTable[nIndex + 6] = chrTemp; chrTemp = BaseTable[nIndex + 1]; BaseTable[nIndex + 1] = BaseTable[nIndex + 7]; BaseTable[nIndex + 7] = chrTemp; chrTemp = BaseTable[nIndex + 2]; BaseTable[nIndex + 2] = BaseTable[nIndex + 4]; BaseTable[nIndex + 4] = chrTemp; chrTemp = BaseTable[nIndex + 3]; BaseTable[nIndex + 3] = BaseTable[nIndex + 5]; BaseTable[nIndex + 5] = chrTemp; } break; default: break; } return BaseTable; } /**//// <summary> /// Encode string at specific parameter /// </summary> /// <param name="Para"></param> /// <param name="input"></param> /// <returns>return encoded string</returns> public char[] GetEncoded( char[] Para, byte[] input ) { length=input.Length; if((length % 3)==0) { paddingCount=0; blockCount=length/3; } else { paddingCount=3-(length % 3);//need to add padding blockCount=(length+paddingCount) / 3; } length2=length+paddingCount;//or blockCount *3 byte[] source2; source2=new byte[length2]; //copy data over insert padding for (int x=0; x<length2;x++) { if (x<length) { source2[x]=input[x]; } else { source2[x]=0; } } byte b1, b2, b3; byte temp, temp1, temp2, temp3, temp4; byte[] buffer=new byte[blockCount*4]; char[] result=new char[blockCount*4]; for (int x=0;x<blockCount;x++) { b1=source2[x*3]; b2=source2[x*3+1]; b3=source2[x*3+2]; temp1=(byte)((b1 & 252)>>2);//first temp=(byte)((b1 & 3)<<4); temp2=(byte)((b2 & 240)>>4); temp2+=temp; //second temp=(byte)((b2 & 15)<<2); temp3=(byte)((b3 & 192)>>6); temp3+=temp; //third temp4=(byte)(b3 & 63); //fourth buffer[x*4]=temp1; buffer[x*4+1]=temp2; buffer[x*4+2]=temp3; buffer[x*4+3]=temp4; } lookupTable = CreateBase64Char( ref Para ); for (int x=0; x<blockCount*4;x++) { result[x]=sixbit2char(buffer[x]); } //covert last "A"s to "=", based on paddingCount switch (paddingCount) { case 0:break; case 1:result[blockCount*4-1]='=';break; case 2:result[blockCount*4-1]='='; result[blockCount*4-2]='='; break; default:break; } return result; } private char sixbit2char(byte b) { if((b>=0) &&(b<=63)) { return lookupTable[(int)b]; } else { //should not happen; return ' '; } } /**//// <summary> /// Decode string using specific parameter /// </summary> /// <param name="Para"></param> /// <param name="input"></param> /// <returns>If decoded successfully, return the decoded string; else return NULL</returns> public byte[] GetDecoded( char[] Para, char[] input ) { int temp=0; source=input; length=input.Length; if( ( length % 4 ) != 0 ) return null; // The string is not encoded with my base64; //find how many padding there are while( input[length - temp - 1] == '=' && temp < 3 ) { temp++; } if( temp == 3 ) return null; // The string is not encoded with my base64; paddingCount=temp; //calculate the blockCount; //assuming all whitespace and carriage returns/newline were removed. blockCount=length/4; length2=blockCount*3; byte[] buffer=new byte[length];//first conversion result byte[] buffer2=new byte[length2];//decoded array with padding lookupTable = CreateBase64Char( ref Para ); for(int x=0;x<length;x++) { buffer[x]=char2sixbit(source[x]); } byte b, b1,b2,b3; byte temp1, temp2, temp3, temp4; for(int x=0;x<blockCount;x++) { temp1=buffer[x*4]; temp2=buffer[x*4+1]; temp3=buffer[x*4+2]; temp4=buffer[x*4+3]; b=(byte)(temp1<<2); b1=(byte)((temp2 & 48)>>4); b1+=b; b=(byte)((temp2 & 15)<<4); b2=(byte)((temp3 & 60)>>2); b2+=b; b=(byte)((temp3 & 3)<<6); b3=temp4; b3+=b; buffer2[x*3]=b1; buffer2[x*3+1]=b2; buffer2[x*3+2]=b3; } //remove paddings length3=length2-paddingCount; byte[] result=new byte[length3]; for(int x=0;x<length3;x++) { result[x]=buffer2[x]; } return result; } private byte char2sixbit(char c) { if( c=='=' ) return 0; else { for (int x=0;x<64;x++) { if (lookupTable[x]==c) return (byte)x; } //should not reach here return 0; } } } } Trackback: http://tb.blog.youkuaiyun.com/TrackBack.aspx?PostId=627040