# 动态验证码部署 ## 快速使用 ```bash docker load -i dynamic-qrcode.tar.gz && docker run -d --name dq -p 8027:80 dynamic-qrcode:v1.0 ``` ##编译 ```bash docker build -t dynamic-qrcode:v1.0 . ``` ## 安装 ```bash docker load -i dynamic-qrcode.tar.gz ``` ## 运行 ```bash docker run -d --name dq -p PORT:80 dynamic-qrcode:v1.0 // PORT 按需修改 ``` # 服务端PHP验证码校验 ## 工具类 ```php 0) { $str = substr($str, 0, -($paddingCharCount)); } $str = str_split($str); $binaryString = ""; for ($i = 0; $i < count($str); $i = $i + 8) { $x = ""; for ($j = 0; $j < 8; $j++) { $x .= str_pad(base_convert(@$base32charsFlipped[@$str[$i + $j]], 10, 2), 5, '0', STR_PAD_LEFT); } $eightBits = str_split($x, 8); for ($z = 0; $z < count($eightBits); $z++) { $binaryString .= ($eightBits[$z] == '') ? '' : chr(base_convert($eightBits[$z], 2, 10)); } } return $binaryString; } // TOTP 令牌生成函数 public static function generateTOTPToken($secretKey) { if (empty($secretKey)) return false; $timestamp = floor(time() / 30); $validityPeriod = 30 - (time() % 30); $secretKey = self::base32_decode($secretKey); $timestamp = pack('N*', 0) . pack('N*', $timestamp); $hash = hash_hmac('sha1', $timestamp, $secretKey, true); $offset = ord(substr($hash, -1)) & 0x0F; $token = ( (ord($hash[$offset + 0]) & 0x7F) << 24 | (ord($hash[$offset + 1]) & 0xFF) << 16 | (ord($hash[$offset + 2]) & 0xFF) << 8 | (ord($hash[$offset + 3]) & 0xFF) ) % pow(10, 6); return array($token, $validityPeriod); } } ``` ## 测试用例 ```php assertIsArray($tokenInfo); $this->assertCount(2, $tokenInfo); $this->assertIsInt($tokenInfo[0]); $this->assertIsInt($tokenInfo[1]); $this->assertGreaterThan(0, $tokenInfo[1]); } } ```