读取中...  
读取中...
时 间 记 忆
读取中...
最 新 评 论
读取中...
专 题 分 类
读取中...
最 新 日 志
读取中...
最 新 留 言
读取中...
搜 索
用 户 登 录
读取中...
友 情 连 接
博 客 信 息
读取中...


 
简单加密的程序实现 
[ 2010-5-28 18:19:00 | By: 速度 ]
 


  将进行加密的字母移动任意位,达到加密的目的。

  由于字母表位置循序及移动位数可以自定义,在没有对应的字母表的情况下,即使猜测到加密方法也无法得到准确信息。每刷新一次加密值都会变化。

  可以对中英文、数字进行加密,主要用于、session的信息加密。实际应用中为防止他人拦截、session进行破解,需要更改字母表、数字表的字符顺序及移动位数。

 


简单加密的PHP实现

http://localhost/easyencode.php






代码:
<?php

< http-equiv="Content-Type" content="text\html; charset=utf-8" />
<?php

 header("Content-type: text/html; charset=utf-8");


 // 存储配置信息的数组
 $code_ini = array( 'numeric_list'=>null , 'character_list'=>null , 'type_list'=>null , 'movebit'=> 6 , 'pot'=>',' );

  en5code( $str , $code_ini=null ){  // $movebit = 6 , $numeric_list=null , $character_list=null ,$type=null

  !$code_ini && $code_ini = array(
   'type_list'=> 'abcdefghijklmnopqrstuvwxyz' ,   // 默认标记类型的表。作为类型识别标记,一般可以不修改。
   'numeric_list'=> 'abcdefghijklmnopqrstuvwxyz' , // 数字表,任意不重复字符,数目最少9个。
   'character_list'=> 'abcdefghijklmnopqrstuvwxyz' , // 字串表,可在26个字母基础上添加其它字符。如-+.;:'"?*&^%$等等。
   'movebit'=> 6 ,             // 自定义字串表的移动偏移量。如5,则字母a处理后是f (LOC[a]+5)。
   'pot'=>',' ,               // 小数点或者英文点号的表示方式,默认是逗号。
  );

  !isset( $type ) && $type = $code_ini['type_list'];
  !isset( $numeric_list ) && $numeric_list = $code_ini['numeric_list'];
  !isset( $character_list ) && $character_list = $code_ini['character_list'];
  !isset( $movebit ) && $movebit= $code_ini['movebit'];
  !isset( $pot ) && $pot = $code_ini['pot'];

  $s_len = strlen( $str ); // 输入字串长度
  $t_len = strlen( $type ); // 类型长度
  $n_len = strlen( $numeric_list ); // 数字表长度
  $c_len = strlen( $character_list ); // 字符表长度

  // ------------------------- 处理输入的内容(加密) -------------------------
  $i = 0;
  $out = '';
  
  while( $i < $s_len ){
   
   // 输入的每一个字符作为右边值。(第1位在左边是一个标记码,第2位在右边,2者重新构成一个字符。如aa对应数字0)
   $right = $str[$i];   
   
   // 每次生成类型的随机位置
   $randkey = mt_rand( 0, $t_len -1 );
   $randkey % 2 == 1 &&  $randkey += 1; // 产生偶数位的随机数(从0开始数起,偶数位即是奇数)
   $randkey = $randkey < $n_len ? $randkey : ($n_len -2) ; // 防止超过最大下标的溢出。

   $is_chn = ord( $right );// 以ascii特定值判断中文
   
   // 处理小数点点号。用单字节逗号,表示点号
   if( $right == '.' ){
     // 合成奇数
     $out .= $pot.$type[$randkey];
   }
   // 匹配数字
   elseif( is_numeric( $right ) ){ // 0123456789及小数点.    ($n % 10)
    // 取右边值
    $right = $numeric_list[$right];

    // 左边取奇数值
    
    $left = $type[$randkey];
    
    // 2位组合成一个字符
    $out .= $left.$right;

   }
   // 是否中文
   elseif( $is_chn >= 160 && $is_chn <= 254 ){ // gbk中文的ascii值范围是160~254(160+0~94)
    
    // 向后取3字节组成一个中文字符,再取其ascii码。
    // 普通4位中文区位码。前2数字为区码,后2数字为位码
    $right = $str[$i].$str[$i+1].$str[$i+2];
    $right = iconv( 'UTF-8', 'gbk', $right );
    $right0 = abs( ( ord($right[0]) - 160) );
    if( $right0 < 10 ) $right0 = '0'.$right0; // 给少于2位的补0
    $right1 = abs( ( ord($right[1]) -160 ) );
    if( $right1 < 10 ) $right1 = '0'.$right1;
    // 连接区码和位码
    $right = $right0.$right1;
    
    // 数字转为字母
    $right0 = '';
    for( $j =0; $j<=3;++$j ){
     $right0 .= $character_list[ (int)( $right[$j] + $movebit ) ];
    } //var_dump( $right0 );

    // 使用随机的1-9数字标记中文,对中文加入标记
    $left = mt_rand( 0, 9 );
    $out .= $left.$right0;
    $i = $i+2;
   }
   // 普通字符串。字母、符号等。
   else{

    // 依据位置移动movebit位,取相应的值
    $right = strpos( $character_list , $right )+$movebit;
    $right = ($right < $c_len) ? $right : ($right-$c_len); //  5  26
    $right = $character_list[$right];
    
    // 合成偶数标记码
    $left = ($randkey-1 > 0) ? $randkey-1 : 0 ;
    $left = $type[$left];
    
    // 2位重构成一个字符
    $out .= $left.$right;
   }

   // 指针后移,处理下一个
   ++$i;
  }

  return $out;
 }

 

  de5code( $str , $code_ini=null ){


  !$code_ini && $code_ini = array(
   'type_list'=> 'abcdefghijklmnopqrstuvwxyz' ,   // 默认标记类型的表。作为类型识别标记,一般可以不修改。
   'numeric_list'=> 'abcdefghijklmnopqrstuvwxyz' , // 数字表,任意不重复字符,数目最少9个。
   'character_list'=> 'abcdefghijklmnopqrstuvwxyz' , // 字串表,可在26个字母基础上添加其它字符。如-+.;:'"?*&^%$等等。
   'movebit'=> 6 ,             // 自定义字串表的移动偏移量。如5,则字母a处理后是f (LOC[a]+5)。
   'pot'=>',' ,               // 小数点或者英文点号的表示方式,默认是逗号。
  );

  !isset( $type ) && $type = $code_ini['type_list'];
  !isset( $numeric_list ) && $numeric_list = $code_ini['numeric_list'];
  !isset( $character_list ) && $character_list = $code_ini['character_list'];
  !isset( $movebit ) && $movebit= $code_ini['movebit'];
  !isset( $pot ) && $pot = $code_ini['pot'];

   
   $c_len = strlen( $character_list );// 对于固定的字符表,可以直接赋值长度,如26个字母表。
   $s_len = strlen( $str )-1;

   echo '<br /><strong>输入字串:</strong> '.$str.' <br />长度'.$s_len.'<br />';


   // -------- 说明:  每2个字节组构成一个字符。第1位为类型标记记码,第2位为字符的值 -------------
   
   $i = 0;
   $output = '';
   
   while( $i < $s_len ){
    
    // 确定第1位的类型
    $left = strpos( $type , $str[$i] );
    
    // 取第2位的值
    $right = $str[$i+1];

    
    // 对类型分别处理
    

    // 匹配.号
    if( $str[$i] == $pot ){
     $output .= '.';
    }
     // 匹配中文。中文规则:1个中文字符5位字节,第1位是数字的标记码,2-5位是4个字母(由ascii数字转化成)
    elseif( is_numeric($str[$i]) ){

     $right = $str[$i+1].$str[$i+2].$str[$i+3].$str[$i+4]; // 向后取4位
     
     // 字母转化为区位码
     $right_temp = '';

     for( $j=0; $j<=3; ++$j ){
      $pos = strpos( $character_list , $right[$j] );
      $diff = ( $pos - $movebit );
      if( $pos>=$movebit ) $pos = $diff;
      else $pos = $c_len + $diff;

      $right_temp .= $pos;
     }
     // 区位码转为中文
     $right = chr( (int)($right_temp[0].$right_temp[1]) + 160 ).chr( (int)($right_temp[2].$right_temp[3]) + 160 );
     $right = iconv( 'gbk' , 'UTF-8' , $right );
     // 输出
     $output .= $right;
     // 跳动指针到下一个标记
     $i = $i + 3; // 这里指针+3,后面再+2,一共向后移动5字节。
    }
    elseif( $left !== 0 && $left % 2 == 0 ){ //奇数位字母表示数字

     $right = strpos( $numeric_list , $right ); // 第2位在数字表中的位置
     if( $right === false )  return '解码错误,输入了解码表的数字部分中不存在的字符';

     $output .= $right;
    }
    else{
     
     $right = strpos( $character_list , $right ); // 第2位在字母表中的位置
     $diff = ( $right - $movebit );  // 差值,有正有负

     // 定位未加密前的字符,在字母表中的位置
     $right = ( $right >= $movebit ) ? $diff : ( $c_len + $diff );

     // 解码后得到的位置,对应在字母表中的值
     $output .= $character_list[$right];
    }

    // 将指针后移2个位置
    $i = $i+2;
   }

   return $output;
 }

 

 echo '<hr /><center><font color=red><strong><数字、中英文>简易加密</strong></font></center>';

 $str2 = 'ajjw业务19.88y总金fks额foeo';
 $t1 = microtime( true );
 echo '<br />';
 $s2code = en5code( $str2 );
 echo '<strong>输入字串:</strong>'.$str2.' <br /><br /><br /><strong>加密后:</strong>'.$s2code;
 $t = microtime( true );
 echo '<br /><br />消耗机器时间:',$t-$t1;
 echo '<br /><br /><div style=" width:620px;font-size:13px;border:1px dotted green; padding:5px 10px;"><br /><strong>简介</strong>:<br />算法时间复杂度:加密解密过程都各使用2次循环,其中1次循环用于处理4字节的中文<br />输入输出编码:UTF-8<br />编码转换过程:加密解密过程各使用一次iconv()函数转gbk。(如果知道utf8的中文ascii码,这一过程就可以去掉,待改进)
 <br />  其中处理中文多耗了10倍以上时间<br />主要使用函数:strlen、strpos、mt_rand、ord</div>';

 echo '<hr /><br /><center><font color=red><strong>解密:</strong></font></center>';
 
 $t1 =microtime( true );
 echo '<br /><br /><strong>解码值:</strong>'.de5code( $s2code );//vgjplprc6lgih1kmohabaj,kciyife7llmg6ipoghljqry9iinovljubkdu
 $t =microtime( true );
 echo '<br /><br />消耗机器时间:',$t-$t1;

 

 echo '<hr />';


 $t1 =microtime( true );
 echo '<br /><br /><strong>md5值:</strong>'.md5( $str2 );
 $t =microtime( true );
 echo '<br /><br />消耗机器时间:',$t-$t1;


 echo '<hr />';


 $t1 =microtime( true );
 echo '<br /><br /><strong>1次strlen值:</strong>'.strlen( $str2 );
 $t =microtime( true );
 echo '<br /><br />消耗机器时间:',$t-$t1;

?>

 

END

 
发表评论:
读取中...
Powered by 推理之门.