[uchome]一个相当好用的 字符串 加密 与 解密 函数

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

 

ExpandedBlockStart.gif 代码
/* *
 * 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”,注意,“+”被 空字符 自动代替了,

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

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

 

 

ExpandedBlockStart.gif 代码
/* *
 * 字符串(自定义)加密、解密
 * @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 中哪些字符不需再编码传输。我用到了其中的“*”。

 

 

ExpandedBlockStart.gif 代码
/*  
    这个事我实现的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
    } 
}

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值