CodeEncoder.class.php 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. <?php
  2. /**
  3. * 加密源文件
  4. * User: 时光弧线
  5. * Date: 15/12/24
  6. * Time: 17:13
  7. * Email: zuoxiupeng@live.com
  8. */
  9. class CodeEncoder{
  10. private static $filePath = ''; // 要加密的路径
  11. private static $outFilePath = ''; // 输出路径
  12. private static $counts = 0; // 统计编码的文件数量
  13. public static $level = '0';// 编码级别
  14. public static function encode($fileName, $outFilePath = ''){
  15. self::$filePath = rtrim($fileName, "/\\");
  16. if(!file_exists(self::$filePath)) return '选择的编码目录不存在,请重新选择要编码的php目录';
  17. if($outFilePath){
  18. self::$outFilePath = rtrim($outFilePath, "/\\");
  19. if(!file_exists(self::$outFilePath)) return '输出目录不存在,请先创建';
  20. }else{
  21. self::$outFilePath = self::$filePath . '/tmp_' . md5(time() . rand(1111, 9999));
  22. }
  23. // 递归目录
  24. self::listDir($fileName);
  25. if(self::$counts == 0){
  26. return '没有找到要编码的php文件';
  27. }else{
  28. return '成功编码php文件:' . self::$counts . '个';
  29. }
  30. }
  31. /**
  32. * 获取随机串
  33. * @return string 返回打乱的字符串
  34. */
  35. private static function randAbc() {
  36. $str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
  37. return str_shuffle($str);
  38. }
  39. /**
  40. * 简单编码文件
  41. * @param $fileName 文件路径
  42. * @return string 返回编码的字符串
  43. */
  44. private static function encodeNoKey($fileName){
  45. $contents = file_get_contents($fileName);
  46. $headerPos = strpos($contents, '<?php');
  47. if (!$headerPos){
  48. $headerPos = strpos($contents, '<?') + 2;
  49. }else{
  50. $headerPos += 5;
  51. }
  52. $footerPos = strrpos($contents, '?>');
  53. $footerPos = $footerPos ? $footerPos : strlen($footerPos);
  54. $contents = substr($contents, $headerPos, $footerPos - $headerPos);
  55. $encode = base64_encode(serialize(trim($contents)));
  56. return '<?php'."\neval(unserialize(base64_decode("."'".$encode."'".")));\n?>";
  57. }
  58. /**
  59. * 随机扰乱编码
  60. * @param $fileName 要加密的文件路径
  61. * @return string 返回加密后的字符串
  62. */
  63. public static function encodeKey($fileName){
  64. $key1 = self::randAbc(); // 随机密匙1
  65. $key2 = self::randAbc(); // 随机密匙2
  66. $vstr = file_get_contents($fileName);
  67. $v1 = base64_encode($vstr);
  68. $c = strtr($v1, $key1, $key2); // 根据密匙替换对应字符。
  69. $c = $key1 . $key2 . $c;
  70. $q1 = "O00O0O";
  71. $q2 = "O0O000";
  72. $q3 = "O0OO00";
  73. $q4 = "OO0O00";
  74. $q5 = "OO0000";
  75. $q6 = "O00OO0";
  76. $s = '$'.$q6.'=urldecode("%6E1%7A%62%2F%6D%615%5C%76%740%6928%2D%70%78%75%71%79%2A6%6C%72%6B%64%679%5F%65%68%63%73%77%6F4%2B%6637%6A");$'.$q1.'=$'.$q6.'{3}.$'.$q6.'{6}.$'.$q6.'{33}.$'.$q6.'{30};$'.$q3.'=$'.$q6.'{33}.$'.$q6.'{10}.$'.$q6.'{24}.$'.$q6.'{10}.$'.$q6.'{24};$'.$q4.'=$'.$q3.'{0}.$'.$q6.'{18}.$'.$q6.'{3}.$'.$q3.'{0}.$'.$q3.'{1}.$'.$q6.'{24};$'.$q5.'=$'.$q6.'{7}.$'.$q6.'{13};$'.$q1.'.=$'.$q6.'{22}.$'.$q6.'{36}.$'.$q6.'{29}.$'.$q6.'{26}.$'.$q6.'{30}.$'.$q6.'{32}.$'.$q6.'{35}.$'.$q6.'{26}.$'.$q6.'{30};eval($'.$q1.'("'.base64_encode('$'.$q2.'="'.$c.'";eval(\'?>\'.$'.$q1.'($'.$q3.'($'.$q4.'($'.$q2.',$'.$q5.'*2),$'.$q4.'($'.$q2.',$'.$q5.',$'.$q5.'),$'.$q4.'($'.$q2.',0,$'.$q5.'))));').'"));';
  77. return '<?php'."\n".$s."\n".'?>';
  78. }
  79. /**
  80. * 遍历目录
  81. * @param string $dir 根目录
  82. */
  83. private static function listDir($dir){
  84. if(is_dir($dir)){
  85. if ($handle = opendir($dir)) {
  86. while (false !== ($file = readdir($handle))) {
  87. if($file == '.' || $file == '..'){
  88. continue;
  89. }
  90. $subDir = realpath($dir.'/'.$file); // 子文件或目录地址
  91. if(is_dir($subDir)){
  92. if(stripos($subDir, self::$outFilePath) === 0){
  93. continue;
  94. }
  95. $res = self::mkdir( self::$outFilePath . str_replace(self::$filePath, '', $subDir));
  96. if(checkCli()) echo $res[1], "\n";
  97. self::listDir($subDir);
  98. }else{
  99. self::writeFile($subDir);
  100. }
  101. }
  102. closedir($handle);
  103. }
  104. }else{
  105. self::writeFile($dir);
  106. }
  107. }
  108. /**
  109. * 创建目录
  110. * @param $filePath 创建目录实际地址
  111. * @return array 返回创建是否成功
  112. */
  113. private static function mkdir($filePath){
  114. if(!$filePath){
  115. return array(false, '目录为空:' . $filePath);
  116. }
  117. if(is_dir($filePath)){
  118. return array(false, '目录存在:' . $filePath);
  119. }else{
  120. $res = mkdir($filePath, 0777, true);
  121. return $res ? array(true, '创建目录:' . $filePath) : array(false, '目录创建失败,请检查权限:' . $filePath);
  122. }
  123. }
  124. /**
  125. * 写文件
  126. * @param $fileName 文件路径
  127. * @return bool 返回是否写成功
  128. */
  129. private static function writeFile($fileName){
  130. // 输出目录
  131. $outFileName = str_replace(self::$filePath, self::$outFilePath, $fileName);
  132. if(substr(strrchr($fileName, '.'), 1) == 'php'){
  133. $contents = '';
  134. if(self::$level == '0'){
  135. $contents = self::encodeNoKey($fileName);
  136. }elseif(self::$level == '1'){
  137. $contents = self::encodeKey($fileName);
  138. }
  139. // 写文件
  140. file_put_contents($outFileName, $contents);
  141. self::$counts ++;
  142. }else{
  143. copy($fileName, $outFileName);
  144. }
  145. return true;
  146. }
  147. }