中宣部防沉迷系统PHP版本(管局防沉迷验证-PHP-全版本-接口测试样例)

现在对接游戏,无论是登录还是支付都是要去对接防沉迷实名认证接口,但前期的话你要登录网络游戏防沉迷实名认证系统进行接口测试,$appid ,$bizId,$key去接口测试页面找(正式上线在密钥管理)接下来跟大家说说调试步骤:

第一步:配置白名单

 第二步:点击接口测试,配置好你要测试的IP白名单(api服务器IP),接下来操作那一列有一个【开始测试】按钮,点击获取测试码(最好一个个接口测试)。

第三步: 添加测试代码(thinkphp框架,Wlc类请看文章最后)

1、testcase01-实名认证接口(认证成功),testcase02-实名认证接口(认证中),testcase03-实名认证接口(认证失败)

测试地址:https://wlc.nppa.gov.cn/test/authentication/check/测试码

// 测试防成谜(接口测试)
    public function checkTest()
    {
        $appid = '';
        $bizId = ;
        $key = "";
        $wlc = new Wlc($appid, $key, $bizId);
        //认证成功
        $body = [
            "ai" => '1000023000000007',
            "name" => '某一七',
            "idNum" => '110000190101030010',
        ];

        $res = $wlc->setBody($body)->check();
        print_r($res);
    }

 说明:参数按照传就行说明文档,testcase03的参数随便改错一个即可

2、testcase04-实名认证结果查询接口(认证成功),testcase05-实名认证结果查询接口(认证中),testcase06-实名认证结果查询接口(认证失败)

测试地址:https://wlc.nppa.gov.cn/test/authentication/query/测试码?

// 测试防成谜(接口测试)
    public function queryTest()
    {
        $appid = '';
        $bizId = ;
        $key = "";
        $wlc = new Wlc($appid, $key, $bizId);
        //认证成功
        $body = [
            "ai" => '300000000000000002',
        ];
        $res = $wlc->setParams($body)->query();
        print_r($res);
    }

说明:参数按照传就行说明文档,testcase06的参数随便改错一个即可

3、 testcase07-游戏用户行为数据上报接口(游客模式),testcase08-游戏用户行为数据上报接口(已认证)

测试地址:https://wlc.nppa.gov.cn/test/collection/loginout/测试码

游客模式:

   // 测试防成谜(接口测试)
    public function loginoutTest()
    {
        $appid = '';
        $bizId = ;
        $key = "";
        $wlc = new Wlc($appid, $key, $bizId);
        //认证成功 (游客模式)
        $body =[
            'collections'=>[
                [
                    'no'=>1,
                    'si'=>'95edkzei5exh47pk0z2twm6zpielesrd',
                    'bt'=>0,
                    'ot'=>time(),
                    'ct'=>2,
                    'di'=>'ecvndx6r6xfwofmufs3lbimcr639r33t',
                ]
            ],
        ];

     
        $res = $wlc->setBody($body)->loginout();
        print_r($res);
    }

已认证模式:

// 测试防成谜(接口测试)
    public function loginoutTest()
    {
        $appid = '';
        $bizId = ;
        $key = "";
        $wlc = new Wlc($appid, $key, $bizId);

        //认证用户测试上报
        $presetlist = [
            ['pi'=>'1fffbjzos82bs9cnyj1dna7d6d29zg4esnh99u'],
            ['pi'=>'1fffbkmd9ebtwi7u7f4oswm9li6twjydqs7qjv'],
        ];
        $preset = $presetlist[mt_rand(0,count($presetlist)-1)];
        $pi = $preset['pi'];
        $body =[
            'collections'=>[
                [
                    'no'=>1,
                    'si'=>'95edkzei5exh47pk0z2twm6zpielesrd',
                    'bt'=>0,
                    'ot'=>time(),
                    'ct'=>0,
                    'di'=>'ecvndx6r6xfwofmufs3lbimcr639r33t',
                    'pi'=>$pi
                ]
            ],
        ];

        $res = $wlc->setBody($body)->loginout();
        print_r($res);
    }
第四步:调试系统返回错误码

附录:  响应参数 

字段                  类型       名称             字段说明 

errcode               Int       状态码             状态码 

errmsg                String    状态描述           状态描述 

data                  Object    响应对象          响应结果 

data.result           Object    响应结果对象      响应结果内容 

data.result.status    Int       实名认证结果      认证结果 0:认证成功 1:认证中  2:认证失败 

data.result.pi       String     用户唯一标识      已通过实名认证用户的唯一标识

    

接口返回状态码

状态码               状态描述           状态说明 

0                     OK                请求成功

1001                SYS ERROR           系统错误 

1002      SYS REQ RESOURCE NOT EXIST    接口请求的资源不存在 

1003        SYS REQ METHOD ERROR        接口请求方式错误 

1004      SYS REQ HEADER MISS ERROR     接口请求核心参数缺失 

1005      SYS REQ IP ERROR              接口请求IP地址非法 

1006      SYS REQ BUSY ERROR            接口请求超出流量限制 

1007      SYS REQ EXPIRE ERROR          接口请求过期 

1008      SYS REQ PARTNER ERROR         接口请求方身份非法 

1009      SYS REQ PARTNER AUTH DISABLE  接口请求方权限未启用 

1010        SYS REQ AUTH ERROR          接口请求方无该接口权限 

1011      SYS REQ PARTNER AUTH ERROR    接口请求方身份核验错误 

1012      SYS REQ PARAM CHECK ERROR     接口请求报文核验失败

实名认证业务异常

2001      BUS AUTH IDNUM ILLEGAL        身份证号格式校验失败 

2002      BUS AUTH RESOURCE LIMIT       实名认证条目已达上限 

2003      BUS AUTH CODE NO AUTH RECODE  无该编码提交的实名认证记录 

2004      BUS AUTH CODE ALREADY IN USE  编码已经被占用

游戏用户行为数据上报业务异常 

3001     BUS COLL PARTIAL ERROR         行为数据部分上报失败 

3002     BUS COLL BEHAVIOR NULL ERROR   行为数据为空 

3003     BUS COLL OVER LIMIT COUNT      行为数据超出条目数量限制 

3004     BUS COLL NO INVALID            行为数据编码错误 

3005     BUS COLL BEHAVIOR TIME ERROR   行为发生时间错误 

3006     BUS COLL PLAYER MODE INVALID   用户类型无效 

3007     BUS COLL BEHAVIOR MODE INVALID 行为类型无效 

3008     BUS COLL PLAYERID MISS         缺失PI(用户唯一标识)值 

3009     BUS COLL DEVICEID MISS         缺失DI(设备标识)值 3

010      BUS COLL PLAYERID INVALID PI (用户唯一标识)值无效

Wlc类:(里面的地址都是正式地址)

<?php
namespace app\extend\wlc;
use app\extend\wlc\AESGCM;

class Wlc
{
    public $app_id;
    public $secret_key;
    public $biz_id;

    public $headers;
    public $body;
    public $params = [];

    public function __construct($app_id, $secret_key, $biz_id)
    {
        $this->app_id = $app_id;
        $this->secret_key = $secret_key;
        $this->biz_id = $biz_id;

        $time = $this->mtime();
        $this->headers = [
            "appId" => $this->app_id,
            "bizId" => $this->biz_id,
            "timestamps" => "$time",
        ];
        return $this;
    }

    /**
     * 获取毫秒
     * @return float
     */
    protected function mtime()
    {
        list($msec, $sec) = explode(' ', microtime());
        $mtime = round(round($sec . substr($msec, 2, 3)));
        return $mtime;
    }

    /**
     * 加密请求体
     * @param $text
     * @return string
     */
    protected function encrypt($text)
    {
        $key = hex2bin($this->secret_key);
        $cipher = "aes-128-gcm";

        $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length($cipher));

        //php7.1以上可直接使用以下代码
       if (version_compare(PHP_VERSION, '7.1.0') >= 0) {
            $encrypt = openssl_encrypt($text, $cipher, $key, OPENSSL_RAW_DATA, $iv, $tag);
            return base64_encode($iv . $encrypt . $tag);
        }

        //php5.6-7.0使用以下代码
        list($encrypt, $tag) = AESGCM::encrypt($key, $iv, $text);
        $str = bin2hex($iv) . bin2hex($encrypt) . bin2hex($tag);
        return base64_encode(hex2bin($str));
    }

    /**
     * 签名
     * @param $body
     * @return string
     */
    protected function sign($body)
    {
        $data = array_merge($this->headers, $this->params);
        ksort($data);
        $sign_str = '';
        foreach ($data as $k => $v) {
            $sign_str .= "{$k}{$v}";
        }
        $sign_str = $this->secret_key . $sign_str . $body;
        $sign = hash("sha256", $sign_str);
        return $sign;
    }

    /**
     * 发送请求
     * @param $url
     * @param $method
     * @param $headers
     * @param $body
     * @return mixed
     */
    protected function request($url, $method, $headers, $body)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, strtoupper($method));

        curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HEADER, false);
        curl_setopt($ch, CURLOPT_TIMEOUT, 5);
        $response = curl_exec($ch);
        curl_close($ch);
        unset($ch);

        return json_decode($response, true);
    }

    /**
     * 设置url 请求参数
     * @param $params
     * @return $this
     */
    public function setParams($params)
    {
        $this->params = $params;
        return $this;
    }

    /**
     * 设置请求体
     * @param $body
     * @return $this
     */
    public function setBody($body)
    {
        $this->body = $body;
        return $this;
    }

    public function check()
    {
        $url = "https://api.wlc.nppa.gov.cn/idcard/authentication/check";
        //加密请求体
        $body = json_encode([
            "data" => $this->encrypt(json_encode($this->body, JSON_UNESCAPED_UNICODE)),
        ]);

        //签名
        $sign = $this->sign($body);
        $headers[] = "sign:$sign";
        $headers[] = "Content-Type:application/json; charset=utf-8";
        foreach ($this->headers as $k => $v) {
            $headers[] = "{$k}:{$v}";
        }

        return $this->request($url, "POST", $headers, $body);
    }

    public function query()
    {
        $url = "http://api2.wlc.nppa.gov.cn/idcard/authentication/query";

        //设置url参数
        $params = '';
        if (!empty($this->params)) {
            $params = http_build_query($this->params);
            $url .= "?$params";
        }

        $body = '';
        $sign = $this->sign($body);
        $headers[] = "sign:$sign";
        foreach ($this->headers as $k => $v) {
            $headers[] = "{$k}:{$v}";
        }

        return $this->request($url, "GET", $headers, $body);
    }

    public function loginout()
    {
        $url = "http://api2.wlc.nppa.gov.cn/behavior/collection/loginout";
        //加密请求体
        $body = json_encode([
            "data" => $this->encrypt(json_encode($this->body, JSON_UNESCAPED_UNICODE)),
        ]);

        //签名
        $sign = $this->sign($body);
        $headers[] = "sign:$sign";
        $headers[] = "Content-Type:application/json; charset=utf-8";
        foreach ($this->headers as $k => $v) {
            $headers[] = "{$k}:{$v}";
        }

        return $this->request($url, "POST", $headers, $body);
    }


}
AESGCM类:
<?php
/*
 * https://github.com/Spomky-Labs/php-aes-gcm
 * 从以上gitub项目提取的单文件
 */
namespace app\extend\wlc;

class AESGCM
{
    /**
     * @param string      $K          Key encryption key
     * @param string      $IV         Initialization vector
     * @param null|string $P          Data to encrypt (null for authentication)
     * @param null|string $A          Additional Authentication Data
     * @param int         $tag_length Tag length
     *
     * @return array
     */
    public static function encrypt($K, $IV, $P = null, $A = null, $tag_length = 128)
    {
        $key_length = mb_strlen($K, '8bit') * 8;

        if (version_compare(PHP_VERSION, '7.1.0RC5') >= 0 && null !== $P) {
            return self::encryptWithPHP71($K, $key_length, $IV, $P, $A, $tag_length);
        } elseif (class_exists('\Crypto\Cipher')) {
            return self::encryptWithCryptoExtension($K, $key_length, $IV, $P, $A, $tag_length);
        }

        return self::encryptWithPHP($K, $key_length, $IV, $P, $A, $tag_length);
    }

    /**
     * This method will append the tag at the end of the ciphertext.
     *
     * @param string      $K          Key encryption key
     * @param string      $IV         Initialization vector
     * @param null|string $P          Data to encrypt (null for authentication)
     * @param null|string $A          Additional Authentication Data
     * @param int         $tag_length Tag length
     *
     * @return string
     */
    public static function encryptAndAppendTag($K, $IV, $P = null, $A = null, $tag_length = 128)
    {
        return implode(self::encrypt($K, $IV, $P, $A, $tag_length));
    }

    /**
     * @param string      $K          Key encryption key
     * @param string      $key_length Key length
     * @param string      $IV         Initialization vector
     * @param null|string $P          Data to encrypt (null for authentication)
     * @param null|string $A          Additional Authentication Data
     * @param int         $tag_length Tag length
     *
     * @return array
     */
    private static function encryptWithPHP71($K, $key_length, $IV, $P = null, $A = null, $tag_length = 128)
    {
        $mode = 'aes-'.($key_length).'-gcm';
        $T = null;
        $C = openssl_encrypt($P, $mode, $K, OPENSSL_RAW_DATA, $IV, $T, $A, $tag_length / 8);

        return [$C, $T];
    }

    /**
     * @param string      $K          Key encryption key
     * @param string      $key_length Key length
     * @param string      $IV         Initialization vector
     * @param null|string $P          Data to encrypt (null for authentication)
     * @param null|string $A          Additional Authentication Data
     * @param int         $tag_length Tag length
     *
     * @return array
     */
    private static function encryptWithPHP($K, $key_length, $IV, $P = null, $A = null, $tag_length = 128)
    {
        list($J0, $v, $a_len_padding, $H) = self::common($K, $key_length, $IV, $A);

        $C = self::getGCTR($K, $key_length, self::getInc(32, $J0), $P);
        $u = self::calcVector($C);
        $c_len_padding = self::addPadding($C);

        $S = self::getHash($H, $A.str_pad('', $v / 8, "\0").$C.str_pad('', $u / 8, "\0").$a_len_padding.$c_len_padding);
        $T = self::getMSB($tag_length, self::getGCTR($K, $key_length, $J0, $S));

        return [$C, $T];
    }

    /**
     * @param string      $K          Key encryption key
     * @param string      $key_length Key length
     * @param string      $IV         Initialization vector
     * @param null|string $P          Data to encrypt (null for authentication)
     * @param null|string $A          Additional Authentication Data
     * @param int         $tag_length Tag length
     *
     * @return array
     */
    private static function encryptWithCryptoExtension($K, $key_length, $IV, $P = null, $A = null, $tag_length = 128)
    {
        $cipher = \Crypto\Cipher::aes(\Crypto\Cipher::MODE_GCM, $key_length);
        $cipher->setAAD($A);
        $cipher->setTagLength($tag_length / 8);
        $C = $cipher->encrypt($P, $K, $IV);
        $T = $cipher->getTag();

        return [$C, $T];
    }

    /**
     * @param string      $K  Key encryption key
     * @param string      $IV Initialization vector
     * @param string|null $C  Data to encrypt (null for authentication)
     * @param string|null $A  Additional Authentication Data
     * @param string      $T  Tag
     *
     * @return string
     */
    public static function decrypt($K, $IV, $C, $A, $T)
    {
        $key_length = mb_strlen($K, '8bit') * 8;

        $tag_length = self::getLength($T);

        if (version_compare(PHP_VERSION, '7.1.0RC5') >= 0 && null !== $C) {
            return self::decryptWithPHP71($K, $key_length, $IV, $C, $A, $T);
        } elseif (class_exists('\Crypto\Cipher')) {
            return self::decryptWithCryptoExtension($K, $key_length, $IV, $C, $A, $T, $tag_length);
        }

        return self::decryptWithPHP($K, $key_length, $IV, $C, $A, $T, $tag_length);
    }

    /**
     * This method should be used if the tag is appended at the end of the ciphertext.
     * It is used by some AES GCM implementations such as the Java one.
     *
     * @param string      $K          Key encryption key
     * @param string      $IV         Initialization vector
     * @param string|null $Ciphertext Data to encrypt (null for authentication)
     * @param string|null $A          Additional Authentication Data
     * @param int         $tag_length Tag length
     *
     * @return string
     *
     * @see self::encryptAndAppendTag
     */
    public static function decryptWithAppendedTag($K, $IV, $Ciphertext = null, $A = null, $tag_length = 128)
    {
        $tag_length_in_bits = $tag_length / 8;
        $C = mb_substr($Ciphertext, 0, -$tag_length_in_bits, '8bit');
        $T = mb_substr($Ciphertext, -$tag_length_in_bits, null, '8bit');

        return self::decrypt($K, $IV, $C, $A, $T);
    }

    /**
     * @param string      $K          Key encryption key
     * @param string      $key_length Key length
     * @param string      $IV         Initialization vector
     * @param string|null $C          Data to encrypt (null for authentication)
     * @param string|null $A          Additional Authentication Data
     * @param string      $T          Tag
     *
     * @return string
     */
    private static function decryptWithPHP71($K, $key_length, $IV, $C, $A, $T)
    {
        $mode = 'aes-'.($key_length).'-gcm';
        $P = openssl_decrypt(null === $C ? '' : $C, $mode, $K, OPENSSL_RAW_DATA, $IV, $T, null === $A ? '' : $A);

        return $P;
    }

    /**
     * @param string      $K          Key encryption key
     * @param string      $key_length Key length
     * @param string      $IV         Initialization vector
     * @param string|null $C          Data to encrypt (null for authentication)
     * @param string|null $A          Additional Authentication Data
     * @param string      $T          Tag
     * @param int         $tag_length Tag length
     *
     * @return string
     */
    private static function decryptWithPHP($K, $key_length, $IV, $C, $A, $T, $tag_length = 128)
    {
        list($J0, $v, $a_len_padding, $H) = self::common($K, $key_length, $IV, $A);

        $P = self::getGCTR($K, $key_length, self::getInc(32, $J0), $C);

        $u = self::calcVector($C);
        $c_len_padding = self::addPadding($C);

        $S = self::getHash($H, $A.str_pad('', $v / 8, "\0").$C.str_pad('', $u / 8, "\0").$a_len_padding.$c_len_padding);
        $T1 = self::getMSB($tag_length, self::getGCTR($K, $key_length, $J0, $S));

        return $P;
    }

    /**
     * @param string      $K          Key encryption key
     * @param string      $key_length Key length
     * @param string      $IV         Initialization vector
     * @param string|null $C          Data to encrypt (null for authentication)
     * @param string|null $A          Additional Authentication Data
     * @param string      $T          Tag
     * @param int         $tag_length Tag length
     *
     * @return string
     */
    private static function decryptWithCryptoExtension($K, $key_length, $IV, $C, $A, $T, $tag_length = 128)
    {
        $cipher = \Crypto\Cipher::aes(\Crypto\Cipher::MODE_GCM, $key_length);
        $cipher->setTag($T);
        $cipher->setAAD($A);
        $cipher->setTagLength($tag_length / 8);

        return $cipher->decrypt($C, $K, $IV);
    }

    /**
     * @param $K
     * @param $key_length
     * @param $IV
     * @param $A
     *
     * @return array
     */
    private static function common($K, $key_length, $IV, $A)
    {
        $H = openssl_encrypt(str_repeat("\0", 16), 'aes-'.($key_length).'-ecb', $K, OPENSSL_NO_PADDING | OPENSSL_RAW_DATA); //---
        $iv_len = self::getLength($IV);

        if (96 === $iv_len) {
            $J0 = $IV.pack('H*', '00000001');
        } else {
            $s = self::calcVector($IV);

            $packed_iv_len = pack('N', $iv_len);
            $iv_len_padding = str_pad($packed_iv_len, 8, "\0", STR_PAD_LEFT);
            $hash_X = $IV.str_pad('', ($s + 64) / 8, "\0").$iv_len_padding;
            $J0 = self::getHash($H, $hash_X);
        }
        $v = self::calcVector($A);
        $a_len_padding = self::addPadding($A);

        return [$J0, $v, $a_len_padding, $H];
    }

    /**
     * @param string $value
     *
     * @return int
     */
    private static function calcVector($value)
    {
        return (128 * ceil(self::getLength($value) / 128)) - self::getLength($value);
    }

    /**
     * @param string $value
     *
     * @return string
     */
    private static function addPadding($value)
    {
        return str_pad(pack('N', self::getLength($value)), 8, "\0", STR_PAD_LEFT);
    }

    /**
     * @param string $x
     *
     * @return int
     */
    private static function getLength($x)
    {
        return mb_strlen($x, '8bit') * 8;
    }

    /**
     * @param int $num_bits
     * @param int $x
     *
     * @return string
     */
    private static function getMSB($num_bits, $x)
    {
        $num_bytes = $num_bits / 8;

        return mb_substr($x, 0, $num_bytes, '8bit');
    }

    /**
     * @param int $num_bits
     * @param int $x
     *
     * @return string
     */
    private static function getLSB($num_bits, $x)
    {
        $num_bytes = ($num_bits / 8);

        return mb_substr($x, -$num_bytes, null, '8bit');
    }

    /**
     * @param int $s_bits
     * @param int $x
     *
     * @return string
     */
    private static function getInc($s_bits, $x)
    {
        $lsb = self::getLSB($s_bits, $x);
        $X = self::toUInt32Bits($lsb) + 1;
        $res = self::getMSB(self::getLength($x) - $s_bits, $x).pack('N', $X);

        return $res;
    }

    /**
     * @param string $bin
     *
     * @return mixed
     */
    private static function toUInt32Bits($bin)
    {
        list(, $h, $l) = unpack('n*', $bin);

        return $l + ($h * 0x010000);
    }

    /**
     * @param $X
     * @param $Y
     *
     * @return string
     */
    private static function getProduct($X, $Y)
    {
        $R = pack('H*', 'E1').str_pad('', 15, "\0");
        $Z = str_pad('', 16, "\0");
        $V = $Y;

        $parts = str_split($X, 4);
        $x = sprintf('%032b%032b%032b%032b', self::toUInt32Bits($parts[0]), self::toUInt32Bits($parts[1]), self::toUInt32Bits($parts[2]), self::toUInt32Bits($parts[3]));
        $lsb_mask = "\1";
        for ($i = 0; $i < 128; $i++) {
            if ($x[$i]) {
                $Z = self::getBitXor($Z, $V);
            }
            $lsb_8 = mb_substr($V, -1, null, '8bit');
            if (ord($lsb_8 & $lsb_mask)) {
                $V = self::getBitXor(self::shiftStringToRight($V), $R);
            } else {
                $V = self::shiftStringToRight($V);
            }
        }

        return $Z;
    }

    /**
     * @param string $input
     *
     * @return string
     */
    private static function shiftStringToRight($input)
    {
        $width = 4;
        $parts = array_map('self::toUInt32Bits', str_split($input, $width));
        $runs = count($parts);

        for ($i = $runs - 1; $i >= 0; $i--) {
            if ($i) {
                $lsb1 = $parts[$i - 1] & 0x00000001;
                if ($lsb1) {
                    $parts[$i] = ($parts[$i] >> 1) | 0x80000000;
                    $parts[$i] = pack('N', $parts[$i]);
                    continue;
                }
            }
            $parts[$i] = ($parts[$i] >> 1) & 0x7FFFFFFF;
            $parts[$i] = pack('N', $parts[$i]);
        }
        $res = implode('', $parts);

        return $res;
    }

    /**
     * @param string $H
     * @param string $X
     *
     * @return mixed
     */
    private static function getHash($H, $X)
    {
        $Y = [];
        $Y[0] = str_pad('', 16, "\0");
        $num_blocks = (int) (mb_strlen($X, '8bit') / 16);
        for ($i = 1; $i <= $num_blocks; $i++) {
            $Y[$i] = self::getProduct(self::getBitXor($Y[$i - 1], mb_substr($X, ($i - 1) * 16, 16, '8bit')), $H);
        }

        return $Y[$num_blocks];
    }

    /**
     * @param string $K
     * @param int    $key_length
     * @param string $ICB
     * @param string $X
     *
     * @return string
     */
    private static function getGCTR($K, $key_length, $ICB, $X)
    {
        if (empty($X)) {
            return '';
        }

        $n = (int) ceil(self::getLength($X) / 128);
        $CB = [];
        $Y = [];
        $CB[1] = $ICB;
        for ($i = 2; $i <= $n; $i++) {
            $CB[$i] = self::getInc(32, $CB[$i - 1]);
        }
        $mode = 'aes-'.($key_length).'-ecb';
        for ($i = 1; $i < $n; $i++) {
            $C = openssl_encrypt($CB[$i], $mode, $K, OPENSSL_NO_PADDING | OPENSSL_RAW_DATA);
            $Y[$i] = self::getBitXor(mb_substr($X, ($i - 1) * 16, 16, '8bit'), $C);
        }

        $Xn = mb_substr($X, ($n - 1) * 16, null, '8bit');
        $C = openssl_encrypt($CB[$n], $mode, $K, OPENSSL_NO_PADDING | OPENSSL_RAW_DATA);
        $Y[$n] = self::getBitXor($Xn, self::getMSB(self::getLength($Xn), $C));

        return implode('', $Y);
    }

    /**
     * @param string $o1
     * @param string $o2
     *
     * @return string
     */
    private static function getBitXor($o1, $o2)
    {
        $xorWidth = PHP_INT_SIZE;
        $o1 = str_split($o1, $xorWidth);
        $o2 = str_split($o2, $xorWidth);
        $res = '';
        $runs = count($o1);
        for ($i = 0; $i < $runs; $i++) {
            $res .= $o1[$i] ^ $o2[$i];
        }

        return $res;
    }
}

特别说明:如果你复制过去调试不行,请下载样例自己再去封装一下就行了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/458162.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Cadence之创建自己的titleblock

在刚接触PCB原理图设计的时候&#xff0c;很多人是不会关注图纸Tile Block的。原因是觉得用不上。然而工作的时候这个反而很重要。原因呢&#xff0c;一是形成一个统一标准&#xff0c;便于归档&#xff0c;整洁清楚&#xff0c;二是其中包含重要信息&#xff0c;比如你的大名&…

派对游戏2024年新局面:二超多强,市场细分

2023年末&#xff0c;《元梦之星》上线迎战《蛋仔派对》&#xff0c;网腾大战打响。 这场战役从开局就进入到了白热化&#xff0c;双方投入真金白银来拉拢玩家&#xff0c;于春节这一亲朋相聚最适合派对游戏的时段集中发力&#xff0c;互有胜负。 目前《元梦之星》略处下风&a…

【STM32学习】基本定时器,输出比较模式,基本参数

1、概述 此项功能是用来控制一个输出波形&#xff0c;或者指示一段给定的的时间已经到时。 如输出PWM信号时&#xff0c;可用这个模式。 2、输出比较初始化函数&#xff0c;基本参数 以上函数是用来配置输出比较模块的&#xff0c;每个函数对应一个定时器的通道&#xff0c;配…

学习Android的第二十八天

目录 Android Service (服务) 线程 Service (服务) Service 相关方法 Android 非绑定 Service startService() 启动 Service 验证 startService() 启动 Service 的调用顺序 Android 绑定 Service bindService() 启动 Service 验证 BindService 启动 Service 的顺序 …

【论文阅读】

4. Analysis of Large-Scale Multi-Tenant GPU Clusters for DNN Training Workloads 出处&#xff1a;2019 USENIX-TAC 大规模多租户GPU集群对DNN训练工作负载的分析 主要工作&#xff1a;描述了Microsoft中一个多租户GPU集群两个月的工作负载特征&#xff0c;研究影响多租户…

Vue2 + node.js项目

1、Vue2 vue2主要功能包括登入、退出、用户权限、表格的增删改查、文件下载。 Vue2项目地址https://gitee.com/www6/finance1.git 2、node.js编写后端接口 2.1、项目初始化 后端地址https://gitee.com/www6/finance-backend.git 创建项目 npm install -g koa-generator …

3dmax导入模型渲染过亮---模大狮模型网

在3ds Max中导入模型后渲染过亮可能是由于以下原因导致的&#xff1a; 材质和贴图设置&#xff1a; 检查导入的模型的材质和贴图设置&#xff0c;确保它们没有过度亮度或反射。调整材质的Diffuse(漫反射)颜色和Specular(高光)属性&#xff0c;以使渲染看起来更加自然。 光源设…

自媒体干货:PC版剪映实用小技巧介绍

目录 界面认识 导入素材 调整视频比例 调整时间线比例 调整素材 素材分割 添加转场 添加/删除滤镜 添加贴纸 添加文字 添加音乐 导出视频 剪映常用快捷键 剪映是一款全能易用的剪辑软件&#xff0c;用它可以非常轻松的制作出精美又有趣的视频。可以说&#xff0c…

Gis导航控件

收费工具&#xff0c;白嫖党、学生党、闹眼子党勿扰 收费金额为100元 1 概述 最近研究了一下电子海图相关内容&#xff0c;发现海图解析和显示相关的功能&#xff0c;都没有好用的开源工具… 在Gis地图显示那一块&#xff0c;有一个导航控件小控件&#xff0c;好像还没有人专门…

全球化服务能力,助力企业拓展海外市场,仓储物流行业解决方案

随着全球化的加速推进&#xff0c;越来越多的企业开始将目光投向海外市场&#xff0c;寻求更广阔的发展空间。然而&#xff0c;海外市场的拓展并非易事&#xff0c;需要企业具备强大的全球化服务能力。作为通信行业的领军企业&#xff0c;中国联通凭借其强大的网络资源和技术实…

普林斯顿算法讲义(二)

原文&#xff1a;普林斯顿大学算法课程 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 2.2 归并排序 原文&#xff1a;algs4.cs.princeton.edu/22mergesort 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 我们在本节中考虑的算法基于一种简单的操作&#xff…

【Python数据结构与判断7/7】数据结构小结

目录 序言 整体回忆 定义方式 访问元素 访问单个元素 访问多个与元素 修改元素 添加元素 列表里添加元素 字典里添加元素 删除元素 in运算符 实战案例 总结 序言 今天将对前面学过的三种数据结构&#xff1a;元组&#xff08;tuple&#xff09;、列表&#xff08;…

IDEA把中国大陆高校教育邮箱都封了?

今天本想趁着快到期前&#xff0c;用教育邮箱续命&#xff0c;没想到&#xff1a; 天不遂人愿&#xff01;只能继续申请开源项目的许可证&#xff01; 可惜了&#xff0c;没提交在每个月&#xff1a;

unityprotobuf自动生成C#

Release Protocol Buffers v3.19.4 protocolbuffers/protobuf GitHub 导入Source code 里面的 csharp/src/Google.Protobuf 进入Unity 拷贝其他版本的 System.Runtime.CompilerServices.Unsafe进入工程 使用protoc-3.19.4-win32 里面的exe去编译proto文件为C# using Sys…

QT c++ 双精度数拆分和组合 Tool

本文描述QT c的双精度数拆分和合并&#xff0c;即双精度浮点数拆为四个16位无符号整数以及将四个16位无符号整数组合为双精度浮点数。 开发平台&#xff1a;win10QT6.2.4 MSVC2019 64 bit 在本文的最好列出了代码和可执行文件打包下载链接&#xff08;可直接使用&#xff09;…

基于Java的天然气工程运维系统(Vue.js+SpringBoot)

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 系统角色分类2.2 核心功能2.2.1 流程 12.2.2 流程 22.3 各角色功能2.3.1 系统管理员功能2.3.2 用户服务部功能2.3.3 分公司&#xff08;施工单位&#xff09;功能2.3.3.1 技术员角色功能2.3.3.2 材料员角色功能 2.3.4 安…

学会Web UI框架--Bootstrap,快速搭建出漂亮的前端界面

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 所属的专栏&#xff1a;前端泛海 景天的主页&#xff1a;景天科技苑 文章目录 Bootstrap1.Bootstrap介绍2.简单使用3.布局容器4.Bootstrap实现轮播…

java SSM在线学习网站系统myeclipse开发mysql数据库springMVC模式java编程计算机网页设计

一、源码特点 java SSM在线学习网站系统是一套完善的web设计系统&#xff08;系统采用SSM框架进行设计开发&#xff0c;springspringMVCmybatis&#xff09;&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用…

【Python】新手入门学习:详细介绍迪米特原则(LoD)及其作用、代码示例

【Python】新手入门学习&#xff1a;详细介绍迪米特原则&#xff08;LoD&#xff09;及其作用、代码示例 &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集】、PyTor…

git、、

有学弟想快速上手git&#xff0c;我就发个文章吧。 git区域划分&#xff1a; 缓冲区&#xff1a;英文叫 stage 或 index。一般存放在 .git 目录下的 index 文件&#xff08;.git/index&#xff09;中。版本库&#xff1a;工作区有一个隐藏目录 .git&#xff0c;就是 Git 的版本…