class.geetestlib.php 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. <?php
  2. /**
  3. * 极验行为式验证安全平台,php 网站主后台包含的库文件
  4. *@author Tanxu
  5. */
  6. require_once dirname(dirname(__FILE__)) . '/plugin/config.php';
  7. class GeetestLib{
  8. const GT_SDK_VERSION = 'php_2.15.7.6.1';
  9. public function __construct() {
  10. $this->challenge = "";
  11. }
  12. /**
  13. *判断极验服务器是否down机
  14. *
  15. * @return
  16. */
  17. public function register() {
  18. $url = "http://api.geetest.com/register.php?gt=" . CAPTCHA_ID;
  19. $this->challenge = $this->send_request($url);
  20. if (strlen($this->challenge) != 32) {
  21. return 0;
  22. }
  23. return 1;
  24. }
  25. public function validate($challenge, $validate, $seccode) {
  26. if ( ! $this->check_validate($challenge, $validate)) {
  27. return FALSE;
  28. }
  29. $data = array(
  30. "seccode"=>$seccode,
  31. "sdk"=>self::GT_SDK_VERSION,
  32. );
  33. $url = "http://api.geetest.com/validate.php";
  34. $codevalidate = $this->post_request($url, $data);
  35. if (strlen($codevalidate) > 0 && $codevalidate == md5($seccode)) {
  36. return TRUE;
  37. } else if ($codevalidate == "false"){
  38. return FALSE;
  39. } else {
  40. return $codevalidate;
  41. }
  42. }
  43. private function check_validate($challenge, $validate) {
  44. if (strlen($validate) != 32) {
  45. return FALSE;
  46. }
  47. if (md5(PRIVATE_KEY.'geetest'.$challenge) != $validate) {
  48. return FALSE;
  49. }
  50. return TRUE;
  51. }
  52. private function send_request($url){
  53. if(function_exists('curl_exec')){
  54. $ch = curl_init();
  55. curl_setopt ($ch, CURLOPT_URL, $url);
  56. curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
  57. $data = curl_exec($ch);
  58. curl_close($ch);
  59. }else{
  60. $opts = array(
  61. 'http'=>array(
  62. 'method'=>"GET",
  63. 'timeout'=>2,
  64. )
  65. );
  66. $context = stream_context_create($opts);
  67. $data = file_get_contents($url, false, $context);
  68. }
  69. return $data;
  70. }
  71. /**
  72. *解码随机参数
  73. *
  74. * @param $challenge
  75. * @param $string
  76. * @return
  77. */
  78. private function decode_response($challenge,$string) {
  79. if (strlen($string) > 100) {
  80. return 0;
  81. }
  82. $key = array();
  83. $chongfu = array();
  84. $shuzi = array("0"=>1,"1"=>2,"2"=>5,"3"=>10,"4"=>50);
  85. $count = 0;
  86. $res = 0;
  87. $array_challenge = str_split($challenge);
  88. $array_value = str_split($string);
  89. for ($i=0; $i < strlen($challenge); $i++) {
  90. $item = $array_challenge[$i];
  91. if (in_array($item, $chongfu)) {
  92. continue;
  93. }else{
  94. $value = $shuzi[$count % 5];
  95. array_push($chongfu, $item);
  96. $count++;
  97. $key[$item] = $value;
  98. }
  99. }
  100. for ($j=0; $j < strlen($string); $j++) {
  101. $res += $key[$array_value[$j]];
  102. }
  103. $res = $res - $this->decodeRandBase($challenge);
  104. return $res;
  105. }
  106. /**
  107. *
  108. * @param $x_str
  109. * @return
  110. */
  111. private function get_x_pos_from_str($x_str) {
  112. if (strlen($x_str) != 5) {
  113. return 0;
  114. }
  115. $sum_val = 0;
  116. $x_pos_sup = 200;
  117. $sum_val = base_convert($x_str,16,10);
  118. $result = $sum_val % $x_pos_sup;
  119. $result = ($result < 40) ? 40 : $result;
  120. return $result;
  121. }
  122. /**
  123. *
  124. * @param full_bg_index
  125. * @param img_grp_index
  126. * @return
  127. */
  128. private function get_failback_pic_ans($full_bg_index,$img_grp_index) {
  129. $full_bg_name = substr(md5($full_bg_index),0,9);
  130. $bg_name = substr(md5($img_grp_index),10,9);
  131. $answer_decode = "";
  132. // 通过两个字符串奇数和偶数位拼接产生答案位
  133. for ($i=0; $i < 9; $i++) {
  134. if ($i % 2 == 0) {
  135. $answer_decode = $answer_decode . $full_bg_name[$i];
  136. }elseif ($i % 2 == 1) {
  137. $answer_decode = $answer_decode . $bg_name[$i];
  138. }
  139. }
  140. $x_decode = substr($answer_decode, 4 , 5);
  141. $x_pos = $this->get_x_pos_from_str($x_decode);
  142. return $x_pos;
  143. }
  144. /**
  145. * 输入的两位的随机数字,解码出偏移量
  146. *
  147. * @param challenge
  148. * @return
  149. */
  150. private function decodeRandBase($challenge) {
  151. $base = substr($challenge, 32, 2);
  152. $tempArray = array();
  153. for ($i=0; $i < strlen($base); $i++) {
  154. $tempAscii = ord($base[$i]);
  155. $result = ($tempAscii > 57) ? ($tempAscii - 87) : ($tempAscii -48);
  156. array_push($tempArray,$result);
  157. }
  158. $decodeRes = $tempArray['0'] * 36 + $tempArray['1'];
  159. return $decodeRes;
  160. }
  161. /**
  162. * 得到答案
  163. *
  164. * @param validate
  165. * @return
  166. */
  167. public function get_answer($validate) {
  168. if ($validate) {
  169. $value = explode("_",$validate);
  170. $challenge = $_SESSION['challenge'];
  171. $ans = $this->decode_response($challenge,$value['0']);
  172. $bg_idx = $this->decode_response($challenge,$value['1']);
  173. $grp_idx = $this->decode_response($challenge,$value['2']);
  174. $x_pos = $this->get_failback_pic_ans($bg_idx ,$grp_idx);
  175. $answer = abs($ans - $x_pos);
  176. if ($answer < 4) {
  177. return 1;
  178. }else{
  179. return 0;
  180. }
  181. }else{
  182. return 0;
  183. }
  184. }
  185. public function post_request($url, $postdata = null){
  186. $data = http_build_query($postdata);
  187. if(function_exists('curl_exec')){
  188. $ch = curl_init();
  189. curl_setopt($ch, CURLOPT_URL, $url);
  190. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  191. if(!$postdata){
  192. curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
  193. curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
  194. }else{
  195. curl_setopt($ch, CURLOPT_POST, 1);
  196. curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
  197. }
  198. $data = curl_exec($ch);
  199. curl_close($ch);
  200. }else{
  201. if($postdata){
  202. $url = $url.'?'.$data;
  203. $opts = array(
  204. 'http' => array(
  205. 'method' => 'POST',
  206. 'header'=> "Content-type: application/x-www-form-urlencoded\r\n" . "Content-Length: " . strlen($data) . "\r\n",
  207. 'content' => $data
  208. )
  209. );
  210. $context = stream_context_create($opts);
  211. $data = file_get_contents($url, false, $context);
  212. }
  213. }
  214. return $data;
  215. }
  216. }
  217. ?>