<?php
namespace imcat;

//生成验证码
class comVCode {

    private 
$im;            //图片对象
    
private $dis;           //图片对象
    
private $imw 160;     //宽
    
private $imh 40;      //高
    
private $mod '';      //模块
    
private $ttf '';      //字体文件 //array
    
private $ttOld '';
    private 
$clOld Null;
    private 
$code '';     //字符
    
private $corg '';     //字符
    
private $ctab '';     //随机颜色表
    //private $cTab = "";
    //private $oTab = '';
    
static $ctabN = [];
    static 
$ctabA = [];
    static 
$ctabB = [];

    static function 
initTab(){
        
self::$ctabN['4'] = ['0'=>0'5'=>85'A'=>170'F'=>255]; # gap:5 : 0-5-A-F
        
self::$ctabN['5'] = ['00'=>0'40'=>64'80'=>128'C0'=>192'F0'=>255]; # gap:8 : 00:80:C0:F0 
        
self::$ctabN['6'] = ['0'=>0'3'=>51'6'=>102'9'=>153'C'=>204'F'=>255];
        
//
        
self::$ctabA['6'] = [ # gap:6
            
'0'=>['6','9','C','F'],
            
'3'=>[    '9','C','F'],
            
'6'=>['0',    'C','F'],
            
'9'=>['0','3',    'F'],
            
'C'=>['0','3','6'    ],
            
'F'=>['0','3','6','9'],
        ];
        
self::$ctabB['6'] = [ # gap:6
            
'0'=>['3'],
            
'3'=>['0','6'],
            
'6'=>['3','9'],
            
'9'=>['6','C'],
            
'C'=>['9','F'],
            
'F'=>['C'],
        ];
    }

    
# 前背景颜色
    
static function tabrc($n=6$rc3=0$rx=0){
        
$tbcn self::$ctabN['6']; $tbkn array_keys($tbcn); 
        
$tban self::$ctabA['6']; $tbbn self::$ctabB['6'];
        
# one
        
if(!$n){
            return 
$rc3 implode('',$tb3) : [$tbcn[$tb3[0]],$tbcn[$tb3[1]],$tbcn[$tb3[2]]];
        }
        
# RGB(n+1)
        
$tb3 $ts1 = []; shuffle($tbkn); #dump($tbkn);
        
$xb3 $xs1 = [];
        for(
$i=0;$i<3;$i++){
            
$tb3[] = $k1 $tbkn[$i]; $ts1[] = $tban[$k1];
            
$xb3[] = $k1 $tbkn[$i]; $xs1[] = $tbbn[$k1];
        } 
#dump($tb3); dump($ts1);
        # return n + 1 
        
$ts3[] = $rc3 implode('',$tb3) : [$tbcn[$tb3[0]],$tbcn[$tb3[1]],$tbcn[$tb3[2]]];
        for(
$i=0;$i<$n;$i++){ 
            
$k1 array_rand($ts1[0],1); $c1=$ts1[0][$k1]; $k2 array_rand($ts1[1],1); $c2=$ts1[1][$k2]; $k3 array_rand($ts1[2],1); $c3=$ts1[2][$k3];
            
$ts3[] = $rc3 "$c1$c2$c3: [$tbcn[$c1],$tbcn[$c2],$tbcn[$c3]];
            
$k1 array_rand($xs1[0],1); $c1=$xs1[0][$k1]; $k2 array_rand($xs1[1],1); $c2=$xs1[1][$k2]; $k3 array_rand($xs1[2],1); $c3=$xs1[2][$k3];
            
$xs3[] = $rc3 "$c1$c2$c3: [$tbcn[$c1],$tbcn[$c2],$tbcn[$c3]];
        }
        
#dump($tb3); dump($ts1); dump($ts3); 
        
return [$ts3$xs3];
    }

    function 
__construct($mod='(istest)'$ttf=''$corg='0'){ 
        
$this->mod $mod
        
$this->ttf $ttf;
        
$this->corg $corg;
        
self::initTab();
        
// 显示图片一般图片
        
if(function_exists('imagecreate')){ 
            
$this->show();
        }else{ 
//bmp
            
glbError::show("NO function:imagecreate!");
        }
    }
    function 
init(){
        if(
$this->mod=='(emtel)'){
            
$this->code $this->corg;
            
$this->imw 20+strlen($this->corg)*20;
        }else{
            
$this->code self::strRand();
        }
        
$this->im imagecreate($this->imw$this->imh); 
        
// 填充
        
$this->ctbs $this->tabrc(strlen($this->code), 01); # n+1个颜色
        
$this->bgColor $this->rndCimg($this->ctbs[0][0]);
        
imagefill($this->im,0,0,$this->bgColor);
    }
    
// 输出
    
function output(){
        
$typa = array(1=>'gif'2=>'png'3=>'jpeg'); 
        
$type $typa[rand(1,3)]; 
        
basEnv::obClean();
        
#header("Pragma:no-cache");
        #header("Cache-control:no-cache");
        #header("Content-type:image/$type");
        
$func "image$type"//imagejpeg
        
$func($this->im); 
    }
    
// 显示
    
function show(){
        
$this->init();
        
safComm::formCVimg($this->mod$this->code'save'); 
        
// 干扰: 点,线,特殊字符,雪花
        
if($this->mod!='(emtel)'){
            
$r rand(1,4);
            if(
$r==1$this->_rndPixels();
            if(
$r==2$this->_rndLines();
            if(
$r==3$this->_rndChars();
            if(
$r==4$this->_rndSnow();
        }
        
$this->drawStr(); // Draw字符,划边框
        //$this->distOrtion(); // 扭曲文字 
        
$this->output();
        
imagedestroy($this->im); 
        if(
is_resource($this->dis)){
            
imagedestroy($this->dis);
        }
    }
    
// Draw字符
    
function drawStr(){        
        for(
$i=0;$i<strlen($this->code);$i++) {
            
$chr $this->code[$i];
            if(
$this->mod=='(emtel)'){
                
$size 20;
            }elseif(
ord($chr)>96){
                
$size mt_rand(22,26);
            }else{
                
$size mt_rand(16,20); 
            }
            
$angle $this->mod=='(emtel)' 0              mt_rand(-20,20);
            
$x     $this->mod=='(emtel)' $i*20+8        mt_rand(15,20)+$i*26;
            
$y     $this->mod=='(emtel)' mt_rand(24,30) : mt_rand(27,30);
            
$ffile $this->rndFonts(); $tcolor $this->rndCimg($this->ctbs[0][$i+1]);
            if(
$this->mod!='(emtel)'){
                
// 外围描边(空心效果) ctab -> ctbs
                
$cb $this->rndCimg($this->ctbs[1][$i]); 
                
imagettftext($this->im$size$angle$x+1$y$cb$ffile$chr); // x
                
imagettftext($this->im$size$angle$x$y+1$cb$ffile$chr); // y
            
}
            
// 文字本身
            
imagettftext($this->im$size$angle$x$y$tcolor$ffile$chr);
        }
    }

    function 
rndCimg($ctab){
        
$cl imagecolorallocate($this->im$ctab[0], $ctab[1], $ctab[2]);
        if(
$cl===false){
            
$cl imagecolorclosest($this->im$ctab[0], $ctab[1], $ctab[2]);
        } 
        return 
$cl;
    }

    
// 随机颜色
    
function rndColor($no=0){
        
$ct = [];
        for(
$i=0;$i<3;$i++){ $ct[]=mt_rand(2,254); }
        
$cl $this->rndCimg($ct); 
        return 
$cl;
    }
    
// 随机Font
    
public function rndFonts(){
        if(
is_string($this->ttf)){
            
$tti $this->ttf;
        }else{
            
$tti $this->ttf[mt_rand(0,count($this->ttf)-1)];
            while(
$this->ttOld==$tti){
                
$tti $this->ttf[mt_rand(0,count($this->ttf)-1)];
            }
            
$this->ttOld $tti
        } 
        
$ffile DIR_STATIC.'/media/fonts/'.$tti.'.ttf'
        return 
$ffile;
    }
    
// 干扰象素
    
function _rndPixels(){ //加入干扰象素
        
for($i=0;$i<200;$i++){  
           
imagesetpixel($this->imrand()%160 rand()%100 $this->rndColor());    
        }
    }
    
// 干扰线
    
function _rndLines(){ 
        
$w $this->imw-2;
        
$h $this->imh-2;
        
$cnt mt_rand(5,8);
        for(
$j=2;$j<$cnt;$j++){
            
imageline($this->imrand(2,$w),rand(2,$h),rand(2,$w),rand(2,$h), $this->rndColor()
            ); 
//18
        
}
        
imagerectangle($this->im00$this->imw-1$this->imh-1$this->rndColor()); // 边框 
    
}
    
// 干扰字符
    
function _rndChars(){ 
        if(empty(
$this->ttf)){ return; }
        
$cnt mt_rand(5,10); //《!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~》// All:32 '+','-',
        
$chars = array('!',"'",'(',')',',','/',";","?","^","`","~");
        for(
$i=1$i<=$cnt$i++){
            
imagestring($this->im,mt_rand(1,5),mt_rand(1,$this->imw),mt_rand(1,$this->imh),$chars[mt_rand(0,4)],$this->rndColor());
        }
    }
    
// 雪花
    
function _rndSnow(){  
        for (
$i=0;$i<30;$i++) {
            
$color imagecolorallocate($this->im,mt_rand(200,255),mt_rand(200,255),mt_rand(200,255));
            
imagestring($this->im,mt_rand(2,5),mt_rand(0,$this->imw),mt_rand(0,$this->imh),'*',$color);
        }
    }
    
// 扭曲文字
    
public function distOrtion(){
        
$rate floor(0.08 $this->imh);   // 扭曲程度
        
$this->dis imagecreatetruecolor($this->imw$this->imh);
        
imagefill($this->dis00$this->bgColor);
        for (
$x 0$x $this->imw$x++) {
            for (
$y 0$y $this->imh$y++) {
                
$rgb imagecolorat($this->im$x$y);
                if( (int)(
$x sin($y $this->imh M_PI) * $rate) <= $this->imw && (int)($x sin($y $this->imh M_PI) * $rate) >= 
                {
                    
imagesetpixel($this->dis, (int)($x sin($y $this->imh M_PI M_PI 0.1) * $rate) , $y$rgb);
                }
            }
        }
        
$this->im $this->dis;
    }
    
// *** 随机码
    
static function strRand(){
        global 
$_cbase;
        
$vimg $_cbase['ucfg']['vimg'];
        
$type in_array($vimg,array('0','H','K')) ? $vimg 'K';
        
$str basKeyid::kidRand($type,rand(4,5));
        return 
strtoupper($str);
    }
    
// 颜色表
    /*function setCtab($xTab,$xArr,$init){}*/
    //basDebug::bugLogs('vcode', $this->code, 'vcode.txt', 'file');
    
}