一个相当好用的 字符串 加密 与 解密 函数,摘自 uchome系统:

 

代码
/**
 * 04.字符串(自定义)加密、解密
 * @param 1.$String                 加密的对象
 * @param 2.$operation = 'ENCODE'     操作类型,ENCODE:加密,DECODE:解密
 * @param 3.$key = ''                 加密附加密钥值
 * @param 4.$expiry = 0                过期时间,0:不过期            
 * 
*/
function String_authcode($string, $operation = 'ENCODE', $key = '', $expiry = 0) {

    
$ckey_length = 4;    // 随机密钥长度 取值 0-32;
                // 加入随机密钥,可以令密文无任何规律,即便是原文和密钥完全相同,加密结果也会每次不同,增大破解难度。
                // 取值越大,密文变动规律越大,密文变化 = 16 的 $ckey_length 次方
                // 当此值为 0 时,则不产生随机密钥


    
$key = md5($key ? $key : "sggwgleywasgabndwtqplwqwe32l2asglkpbssg235lsfgs5");
    
$keya = md5(substr($key, 0, 16));
    
$keyb = md5(substr($key, 16, 16));
    
$keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';

    
$cryptkey = $keya.md5($keya.$keyc);
    
$key_length = strlen($cryptkey);

    
$string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;
    
$string_length = strlen($string);

    
$result = '';
    
$box = range(0, 255);

    
$rndkey = array();
    
for($i = 0$i <= 255$i++) {
        
$rndkey[$i= ord($cryptkey[$i % $key_length]);
    }

    
for($j = $i = 0$i < 256$i++) {
        
$j = ($j + $box[$i+ $rndkey[$i]) % 256;
        
$tmp = $box[$i];
        
$box[$i= $box[$j];
        
$box[$j= $tmp;
    }

    
for($a = $j = $i = 0$i < $string_length$i++) {
        
$a = ($a + 1% 256;
        
$j = ($j + $box[$a]) % 256;
        
$tmp = $box[$a];
        
$box[$a= $box[$j];
        
$box[$j= $tmp;
        
$result .= chr(ord($string[$i]) ^ ($box[($box[$a+ $box[$j]) % 256]));
    }

    
if($operation == 'DECODE') {
        
if((substr($result, 0, 10== 0 || substr($result, 0, 10- time() > 0&& substr($result, 10, 16== substr(md5(substr($result, 26).$keyb), 0, 16)) {
            
return substr($result, 26);
        } 
else {
            
return '';
        }
    } 
else {
        
return $keyc.str_replace('=', '', base64_encode($result));
    }
}

 

 

 

注意:上面那个机密函数有一个不足之处是:它的输出结果中包含“+”,而“+”在url传参中是当中“空字符”来处理的。

例如:

id的值事先加密过,结果形式如下,

http://www.xxx.com/?p=___example1&id=9ef8eXPl/JuLsZiydwktfJ5453bZ25u+OfS6mAvBf9lVBYU

此时通过 $_GET['id'] ,获取的值却为“9ef8eXPl/JuLsZiydwktfJ5453bZ25u  OfS6mAvBf9lVBYU”,注意,“+”被 空字符 自动代替了,

再对它解密,已不是原先的值了,或者可以说根本解密不出来。

于是,对上面的那个函数再次包装,如下:

 

 

代码
/**
 * 字符串(自定义)加密、解密
 * @param 1.$String                 加密的对象
 * @param 2.$operation = 'ENCODE'         操作类型,ENCODE:加密,DECODE:解密
 * 
*/
 
public static function String_authcode($string, $operation = 'ENCODE'){
    
$result="";
    
//1.加密:
    if($operation == 'ENCODE'){
        
$result=Security_authcode($string,$operation);
        
//用*代替+
        $result=str_replace("+","*",$result);
    }
    
//2.解密:
    else if($operation == 'DECODE'){
        
//用+代替*
        $string=str_replace("*","+",$string);
        
$result=Security_authcode($string,$operation);
        
    }
    
return $result;
 }

 

 

 

这下经过它加密过的字符串可以放心在URL中传递了。。。

 

 

 

 

附:下面是某个人写的关于base64编码的方法:

  从下面至少可看到base64编码后会输出哪些字符。。。从http://www.cnblogs.com/qiantuwuliang/archive/2010/10/31/1865446.html 可以了解到 url 中哪些字符不需再编码传输。我用到了其中的“*”。

 

 

代码
/* 
    这个事我实现的Base64编码器,应该有大优化的余地,但是功能没问题, 
    在各大邮件服务器测试过 

    支持中英文的Base64编码解码器 

    开发者:王飞平 
    jtchina@sohu.com 

    Base64   字符表 
    码值   字符             码值   字符             码值   字符             码值   字符 
          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           (pad)         = 
        15         P                 32         g                 49         x 
        16         Q                 33         h                 50         y 
*/ 
import   java.io.*

public   class   Base64{ 
    
public   static   char   BASETABLE[]=''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''}; 

    
public   static   String   encode(String   text){ 
        
/*编码算法 
            1.将数据按3个字节一组分成数块; 
            2.每块将3个8位的数据转换成4个6位数据段; 
                11111111   00000000   11111111     ----     111111   110000   000011   111111 
            3.根据Base64字符表得到4个6位数据段对应的字符; 
            4.如果最后一块只有两个字节,则添加两个0位,转换成对应Base64字符表的三个字符,并在结尾添一个 '= '字符; 
                如果最后一块只有一个字节,则添加四个0位,转换成对应Base64字符表的两个字符,并在结尾添两个 '= '字符。 
        
*/ 
        StringBuffer   code
=new   StringBuffer(); 
        
byte[]   textBytes=text.getBytes(); 
        
int   textLength=textBytes.length; 
        
int   blockCount=(int)textLength/3
        
//char[]   textChars=new   char[textLength]; 
        int   ch,   bits,   textChars[]=new   int[textLength]; 
        
//text.getChars(0,   textLength,   textChars,   0); 

        
for(int   i=0;i <textLength;i++
            textChars[i]
=textBytes[i]> =0   ?   textBytes[i]   :   256+(int)textBytes[i]; 

        
for(int   i=0;i <blockCount;i++){ 
            ch
=(int)textChars[0+i*3]; 
            ch
=ch> > > 2
            code.append(BASETABLE[ch]); 
            bits
=(int)textChars[0+i*3]-ch*4
            ch
=(int)textChars[1+i*3]; 
            ch
=ch> > > 4
            code.append(BASETABLE[ch
+bits*16]); 
            bits
=(int)textChars[1+i*3]-ch*16
            ch
=(int)textChars[2+i*3]; 
            ch
=ch> > > 6
            code.append(BASETABLE[ch
+bits*4]); 
            bits
=(int)textChars[2+i*3]-ch*64
            code.append(BASETABLE[bits]); 
        } 
        
if((textLength   %   3)!=0
            {   ch
=(int)textChars[blockCount*3]; 
                ch
=ch> > > 2
                code.append(BASETABLE[ch]); 
                bits
=(int)textChars[blockCount*3]-ch*4
                
switch(textLength   %   3){ 
                    
case   1:   code.append(BASETABLE[bits*16]); 
                                    code.append(BASETABLE[
64]); 
                                    code.append(BASETABLE[
64]); 
                                    
break
                    
case   2:   ch=(int)textChars[1+blockCount*3]; 
                                    ch
=ch> > > 4
                                    code.append(BASETABLE[ch
+bits*16]); 
                                    bits
=(int)textChars[1+blockCount*3]-ch*16
                                    code.append(BASETABLE[bits
*4]); 
                                    code.append(BASETABLE[
64]); 
                                    
break
                } 
            } 

        
return   code.toString(); 
    } 

    
public   static   String   decode(String   code){ 
        
/*解码算法 
            1.将数据按4个字节一组分成数块; 
            2.每块将4个字符去掉最高两位并转换成3个8位的数据段; 
                注意:数据块中的字符取值不是ASCII集的值,而是Base64字符表中相对应的索引值! 
                00   111111       00   110000       00   000011       00   111111   ----   11111111   00000000   11111111 
            3.根据ASCII字符集得到3个8位数据段对应的字符; 
            4.如果最后一块只有两个 '= ',去掉两个 '= ',并去掉最低两位,转换成对应ASSCII字符集的两个字符; 
                如果最后一块只有一个 '= ',去掉 '= ',并去掉最低四位,转换成对应ASSCII字符集的一个字符。 
        
*/ 
        
//StringBuffer   text=new   StringBuffer(); 
        int   codeLength=code.length(); 
        
int   blockCount=(int)codeLength/4
        
char[]   codeChars=new   char[codeLength]; 
        
int   ch,   bits; 
        code.getChars(
0,   codeLength,   codeChars,   0); 

        
byte[]   textBytes; 
        
if(codeChars[codeLength-2]== '')   textBytes=new   byte[codeLength/4*3-2]; 
            
else   if(codeChars[codeLength-1]== '')   textBytes=new   byte[codeLength/4*3-1]; 
                          
else   textBytes=new   byte[codeLength/4*3]; 
        
for(int   i=0;i <blockCount;i++){ 
            bits
=indexOfBase64Table(codeChars[1+i*4])> > > 4
            ch
=indexOfBase64Table(codeChars[0+i*4]); 
            textBytes[
0+i*3]=(byte)(ch> =32   ?   (32-ch)*4-bits   :   ch*4+bits); 
            
if(codeChars[2+i*4]!= ''){ 
                ch
=indexOfBase64Table(codeChars[1+i*4])-bits*16
                bits
=indexOfBase64Table(codeChars[2+i*4])> > > 2
                
if(ch> =8)   ch=(8-ch)*16-bits; 
                    
else   ch=ch*16+bits; 
                textBytes[
1+i*3]=(byte)ch; 
                
//text.append((char)ch); 
                if(codeChars[3+i*4]!= ''){ 
                    
//ch=(indexOfBase64Table(codeChars[2+i*4])-bits*4)*64+indexOfBase64Table(codeChars[3+i*4]); 
                    ch=indexOfBase64Table(codeChars[2+i*4])-bits*4
                    
if(ch> =2)   ch=(2-ch)*64-indexOfBase64Table(codeChars[3+i*4]); 
                        
else   ch=ch*64+indexOfBase64Table(codeChars[3+i*4]); 
                    
//text.append((char)ch); 
                    textBytes[2+i*3]=(byte)ch; 
                } 
            } 
        } 

        
for(int   i=0;i <textBytes.length;i++
            
if(textBytes[i] <0)   textBytes[i]=(byte)(-128-(int)textBytes[i]); 
        
//return   text.toString(); 

        String   text
=null
        
try
            text
=new   String(textBytes, "gb2312 "); 
        }
catch(UnsupportedEncodingException   e){} 

        
return   text; 
    } 

    
private   static   int   indexOfBase64Table(char   ch){ 
        
for(int   i=0;i <64;i++)   if(ch==BASETABLE[i])   return   i; 
        
return   -1
    } 
}

 

 

 

 

 

posted on 2010-10-20 22:51  小炒花生米  阅读(1510)  评论(0编辑  收藏  举报