<?php
/**
 * Copyright (C) OElove All rights reserved.
 * <E-Mail：service@phpcoo.com>
 * Url http://www.phpcoo.com
 *     http://www.oephp.com
 *     http://www.oelove.com
 * Update 2020.06.12
 */
@session_start();
$type = $_GET['type']; //类型
$num = intval($_GET['num']); //长度
if ($num < 1) {
    $num = 4;
}
$width = intval($_GET['width']); //图片宽 0.06.12
if ($width < 1 || $width > 200) {
    $width = 60;
}
$height = intval($_GET['height']); //图片高 0.06.12
if ($height < 1 || $height > 200) {
    $height = 30;
}

if ($type == "char") {
    _oephp_validcode_char($num, $width, $height);
}
elseif ($type == "math") {
    _oephp_validcode_math($width, $height);
}
elseif ($type == "gg") {
    _oephp_validcode_gg($num, $width, $height);
}
else {
    _oephp_validcode_number($num, $width, $height);
}

/**
 * 数字加字符验证码
 * @param:: int $num 长度
 * @param:: int $w 图片宽
 * @param:: int $h 图片高
 * @return:: image
*/
function _oephp_validcode_char($num, $w, $h) {
    // 去掉了 0 1 O l 等
    $str = "23456789abcdefghijkmnpqrstuvwxyz";
    $code = '';
    for ($i = 0; $i < $num; $i++) {
        $code .= $str[mt_rand(0, strlen($str)-1)];
    }
    //将生成的验证码写入session，备验证页面使用
    $_SESSION["verifycode"] = $code;
    //创建图片，定义颜色值
    Header("Content-type: image/PNG");
    $im = imagecreate($w, $h);
    $black = imagecolorallocate($im, mt_rand(0, 200), mt_rand(0, 120), mt_rand(0, 120));
    $gray = imagecolorallocate($im, 118, 151, 199);
    $bgcolor = imagecolorallocate($im, 235, 236, 237);
    //画背景
    imagefilledrectangle($im, 0, 0, $w, $h, $bgcolor);
    //画边框
    imagerectangle($im, 0, 0, $w-1, $h-1, $gray);
    //imagefill($im, 0, 0, $bgcolor);
    //在画布上随机生成大量点，起干扰作用;
    for ($i = 0; $i < 80; $i++) {
        imagesetpixel($im, rand(0, $w), rand(0, $h), $black);
    }
    //将字符随机显示在画布上,字符的水平间距和位置都按一定波动范围随机生成
    $strx = rand(3, 8);
    for ($i = 0; $i < $num; $i++) {
        $strpos = rand(1, 6);
        imagestring($im, 5, $strx, intval($h/4), substr($code, $i, 1), $black);
        $strx += rand(8, 14);
    }
    imagepng($im);
    imagedestroy($im);
}

/**
 * 纯数字验证码
 * @param:: int $num 长度
 * @param:: int $w 图片宽
 * @param:: int $h 图片高
 * @return:: image
 */
function _oephp_validcode_number($num, $w, $h) {
    $code = "";
    for ($i = 0; $i < $num; $i++) {
        $code .= rand(0, 9);
    }
    $_SESSION["verifycode"] = $code;
    //创建图片，定义颜色值
    Header("Content-type: image/PNG");
    $im = imagecreate($w, $h);
    $black = imagecolorallocate($im, 0, 0, 0);
    $gray = imagecolorallocate($im, 200, 200, 200);
    $bgcolor = imagecolorallocate($im, 255, 255, 255);
    imagefill($im, 0, 0, $gray);
    //画边框
    imagerectangle($im, 0, 0, $w-1, $h-1, $black);
    //随机绘制两条虚线，起干扰作用
    $style = array (
        $black,
        $black,
        $black,
        $black,
        $black,
        $gray,
        $gray,
        $gray,
        $gray,
        $gray
    );
    imagesetstyle($im, $style);
    $y1 = rand(0, $h);
    $y2 = rand(0, $h);
    $y3 = rand(0, $h);
    $y4 = rand(0, $h);
    imageline($im, 0, $y1, $w, $y3, IMG_COLOR_STYLED);
    imageline($im, 0, $y2, $w, $y4, IMG_COLOR_STYLED);
    //在画布上随机生成大量黑点，起干扰作用;
    for ($i = 0; $i < 80; $i++) {
        imagesetpixel($im, rand(0, $w), rand(0, $h), $black);
    }
    //将数字随机显示在画布上,字符的水平间距和位置都按一定波动范围随机生成
    $strx = rand(3, 8);
    for ($i = 0; $i < $num; $i++) {
        $strpos = rand(1, 6);
        imagestring($im, 5, $strx, intval($h/4), substr($code, $i, 1), $black);
        $strx += rand(8, 12);
    }
    imagepng($im);
    imagedestroy($im);
}

/**
 * 算术题
 * @param:: int $w 图片宽
 * @param:: int $h 图片高
 * @return:: image
 */
function _oephp_validcode_math($w, $h) {
    $im = imagecreate($w, $h);
    $red = imagecolorallocate($im, 255, 0, 0);
    $white = imagecolorallocate($im, 255, 255, 255);
    $num1 = rand(1, 20);
    $num2 = rand(1, 20);
    $_SESSION['verifycode'] = ($num1 + $num2);
    $gray = imagecolorallocate($im, 118, 151, 199);
    $black = imagecolorallocate($im, mt_rand(0, 100), mt_rand(0, 100), mt_rand(0, 100));
    //画背景
    imagefilledrectangle($im, 0, 0, $w, $h, $black);
    //在画布上随机生成大量点，起干扰作用;
    for ($i = 0; $i < 80; $i++) {
        imagesetpixel($im, rand(0, $w), rand(0, $h), $gray);
    }
    imagestring($im, 5, 5, intval($h/4), $num1, $red);
    imagestring($im, 5, 30, intval($h/4), "+", $red);
    imagestring($im, 5, 45, intval($h/4), $num2, $red);
    imagestring($im, 5, 70, intval($h/4), "=", $red);
    imagestring($im, 5, 80, intval($h/4), "?", $white);
    header("Content-type: image/png");
    imagepng($im);
    imagedestroy($im);
}

/**
 * 仿google验证码
 * @param:: int $text 字符
 * @param:: int $w 图片宽
 * @param:: int $h 图片高
 * @return:: image
 */
function _gg_buildchar($text, $w, $h) {
    $im_x = $w;
    $im_y = $h;
    $im = imagecreatetruecolor($im_x,$im_y);
    $text_c = ImageColorAllocate($im, mt_rand(0,100),mt_rand(0,100),mt_rand(0,100));
    $tmpC0=mt_rand(100,255);
    $tmpC1=mt_rand(100,255);
    $tmpC2=mt_rand(100,255);
    $buttum_c = ImageColorAllocate($im,$tmpC0,$tmpC1,$tmpC2);
    imagefill($im, 16, 13, $buttum_c);
    $font = 't1.ttf';
    for ($i=0;$i<strlen($text);$i++) {
        $tmp =substr($text,$i,1);
        $array = array(-1,1);
        $p = array_rand($array);
        $an = $array[$p]*mt_rand(1,10);//角度
        $size = 28;
        imagettftext($im, $size, $an, 15+$i*$size, 35, $text_c, $font, $tmp);
    }
    $distortion_im = imagecreatetruecolor ($im_x, $im_y);
    imagefill($distortion_im, 16, 13, $buttum_c);
    for ( $i=0; $i<$im_x; $i++) {
        for ( $j=0; $j<$im_y; $j++) {
            $rgb = imagecolorat($im, $i , $j);
            if( (int)($i+20+sin($j/$im_y*2*M_PI)*10) <= imagesx($distortion_im)&& (int)($i+20+sin($j/$im_y*2*M_PI)*10) >=0 ) {
                imagesetpixel ($distortion_im, (int)($i+10+sin($j/$im_y*2*M_PI-M_PI*0.1)*4) , $j , $rgb);
            }
        }
    }
    //加入干扰象素;
    $count = 160;//干扰像素的数量
    for($i=0; $i<$count; $i++){
        $randcolor = ImageColorallocate($distortion_im,mt_rand(0,255),mt_rand(0,255),mt_rand(0,255));
        imagesetpixel($distortion_im, mt_rand()%$im_x , mt_rand()%$im_y , $randcolor);
    }
    $rand = mt_rand(5,30);
    $rand1 = mt_rand(15,25);
    $rand2 = mt_rand(5,10);
    for ($yy=$rand; $yy<=+$rand+2; $yy++){
        for ($px=-80;$px<=80;$px=$px+0.1) {
            $x=$px/$rand1;
            if ($x!=0) {
                $y=sin($x);
            }
            $py=$y*$rand2;
            imagesetpixel($distortion_im, $px+80, $py+$yy, $text_c);
        }
    }
    //设置文件头;
    Header("Content-type: image/JPEG");
    //以PNG格式将图像输出到浏览器或文件;
    ImagePNG($distortion_im);
    //销毁一图像,释放与image关联的内存;
    ImageDestroy($distortion_im);
    ImageDestroy($im);
}
function _gg_randchar($length=6) {
    $str="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    $result="";
    for($i=0;$i<$length;$i++){
        $num[$i]=rand(0,25);
        $result.=$str[$num[$i]];
    }
    return $result;
}
/**
 * 仿谷歌验证码
 * @param:: int $num 长度
 * @param:: int $w 图片宽
 * @param:: int $h 图片高
 * @return:: image
 */
function _oephp_validcode_gg($num, $w, $h) {
    $checkcode = _gg_randchar($num);
    $_SESSION['verifycode']=strtolower($checkcode);
    _gg_buildchar($checkcode, $w, $h);
}

?>  