Jump to content
新域网络技术论坛

充值卡生成及验证模块


Jamers
 Share

Recommended Posts

最近整理硬盘,发现了许多年前做的东西,拿出来分享一下吧,如果能够用上就拿去用吧。里面有具体调用示例。

<?php
/*
充值卡生成、验证模块
Jamers  2012.2.1
*/

class prepay {
    
    var $keylen=10;      //卡号总长度
    var $passlen=10;    //密码总长度
    
    const KEY = '0123456789';     //卡号允许出现的字符串
    const PASS = '0123456789ABCDEFGHJKLMNPQRSTUVWXYZ';  //密码字符串列表
    const KEYCHK = 'E01A2C34FD567B89';
    
    
    //检查卡号和密码匹配性
    public function check($id,$pass) {
        if ($this->chk_key($id)) {
            //ID没问题
            if (strtoupper(substr($pass,-2,1)) == $this->gen_fkey($id)) {
                //卡号较验正常
                if (strtoupper(substr($pass,-1)) == $this->gen_pass_chk(substr($pass,0,strlen($pass)-1))) {
                    return true;
                }
            }
        }
        return false;
    }
    
    //批量生成卡号和密码
    public function batch_genstr($num,$prefix='W000000000') {
        $result = '';
        $id = $prefix;
        for ($i=0;$i<$num;$i++) {
            $id = $this->gen_key($id);
            $pass = $this->gen_pass($id);
            $result .= $id.','.$pass.',';
        }
        $result = substr($result,0,strlen($result)-1);
        return $result;
    }
    
    public function batch_genary($num,$prefix='W000000000') {
        $result = array();
        $id = $prefix;
        for ($i=0;$i<$num;$i++) {
            $id = $this->gen_key($id);
            $pass = $this->gen_pass($id);
            $result[$i] = $id.','.$pass;
        }
        return $result;
    }
    
    //生成密码,$pid为充值卡号 如果不写肯定错误
    public function gen_pass($pid) {
        $result = '';
        if ($this->chk_key($pid)) {
            //卡号正确
            $result = $this->randit(self::PASS,$this->passlen-2);
            $result .= $this->gen_fkey($pid);       //卡号较验
            $result .= $this->gen_pass_chk($result);    //总密较验
        }
        return $result;
    }
    //生成卡号 密码位较验码
    private function gen_fkey($key) {
        $value = 10;
        for ($i=0;$i<strlen($key);$i++) {
            $k = $i % 3;
            switch ($k) {
                case 0:
                    $value +=ord($key[$i]);
                    break;
                case 1:
                    $value +=ord($key[$i])*2;
                    break;
                case 2:
                    $value -=ord($key[$i]);
                    break;
            }
        }
        return substr(self::PASS,$value%strlen(self::PASS),1);
    }
    
    //生成密码较验码
    private function gen_pass_chk($pass) {
        $value = 255;
        for ($i=0;$i<strlen($pass);$i++) {
            $k = $i % 2;
            if ($k == 0) { 
                $value += ord($pass[$i]);
            }else{
                $value -= ord($pass[$i])-30;
            }
        }
        return substr(self::PASS,$value%strlen(self::PASS),1);
    }
    
    public function gen_key($prefix='') {
        $result = '';
        if ($prefix == '') {
            //没预定义卡号
            $result = $this->randit(self::KEY,$this->keylen-1);
        }else{
            //有上一个卡号
            if (strlen($prefix)<$this->keylen) {
                //长度不够
                $result = $prefix.$this->randit(self::KEY,$this->keylen-1-strlen($prefix));
            }else{
                $result = substr($prefix,0,$this->keylen-1);
                $result = $this->nextval($result);
            }
        }
        $result .= $this->gen_key_chk($result);
        return $result;
    }
    
    //生成下一个卡号
    private function nextval($key) {
        $bit = strlen($key)-1;
        $tmp = substr($key,$bit,1);
        $pos = strpos(self::KEY,$tmp);
        if ($pos === false) return $key;
        if ($pos>=strlen(self::KEY)-1) {
            $result = $this->nextval(substr($key,0,$bit)).substr(self::KEY,0,1);
        }else{
            $result = substr($key,0,$bit).substr(self::KEY,$pos+1,1);
        }
        return $result;
    }
    
    
    //生成卡号较验码
    private function gen_key_chk($key) {
        $chkvalue = 151;
        for($i=0;$i<=strlen($key);$i++) {
            $chkvalue += ord(substr($key,$i,1))+3;
        }
        $chkvalue = $chkvalue  % 100;
        //$test = $chkvalue%strlen(self::KEYCHK);
        //echo "(".$chkvalue.'%'.strval(strlen(self::KEYCHK)+1).'='.$test.")";
        return substr(self::KEYCHK,$chkvalue%strlen(self::KEYCHK),1);
    }
    
    //验证卡号
    private function chk_key($key){
        if (strlen($key) != $this->keylen) {
            return false;
        }else{
            $chk = substr($key,-1);
            $v = $this->gen_key_chk(substr($key,0,$this->keylen-1));
            if ($chk != $v) return false;
        }
        return true;
    }
    
    //随机生成字符串
    private function randit($strlist,$len) {
        $result = '';
        while (strlen($result)<$len) {
            $result .= substr($strlist,mt_rand(0,strlen($strlist)),1);
        }
        return $result;
    }
    
}


$test = new prepay;
$ary = $test->batch_genary(100);
print_r($ary);

if ($test->check('WG00000017','175833VTVC')) {
    echo 'True!';
}else{
    echo 'False';
}
/*$tmp =  $test->gen_key('W000000000');
//$next = $test->nextval(substr($tmp,0,strlen($tmp)-1));
echo $tmp.'('.strlen($tmp).')<br><br>';
//echo "<br><br>{$next}<br>";

$pass = $test->gen_pass($tmp);
echo "{$pass}(".strlen($pass).")";

$id = 'W000000018';
//$pass = 'TN9K3955JP';
$pass = 'TN9K3955JN';
$tmp = $test->check($id,$pass);
echo "<br><br>卡号:{$id}<br>密码:{$pass}<br><br>";
if ($tmp) {
    echo "为有效卡号密码";
}else{
    echo "无效数据!";
}
*/
/*
W000000018(10)

TN9K3955JP(10)


if (isset($_REQUEST['key'])) {
    $key = $_REQUEST['key'];
    $tmp = $test->chk_key($key);
    if ($tmp) {
        echo "{$key}是合法的卡号";
    }else{
        echo "{$key}是错误的卡号";
    }
        
}
*/
?>

Link to comment
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
 Share

×
×
  • Create New...