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 令牌生成函数 function generateTOTPToken($secretKey) { if(empty($secretKey)) return false; // 检查密钥是否为空 $timestamp = floor(time() / 30); // 时间戳以 30 秒为单位 $validityPeriod = 30 - (time() % 30); // 计算当前时间距离下一个 30 秒的时间差,作为有效期 $secretKey = base32_decode($secretKey); $timestamp = pack('N*', 0) . pack('N*', $timestamp); // 将时间戳转换为字节流 $hash = hash_hmac('sha1', $timestamp, $secretKey, true); // 使用 HMAC-SHA1 算法生成哈希 $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); // 取哈希结果的四个字节生成一个 6 位动态验证码 return array($token, $validityPeriod); // 返回 6 位验证码 和 有效期 } // 示例用户令牌密钥 $userSecretKey = 'JBSWY3DPEHPK3PXP'; // 这是一个示例密钥,实际应用中应该是随机生成的 // 生成动态验证码和有效期 list($token, $validityPeriod) = generateTOTPToken($userSecretKey); if($token === false) { echo "Failed to generate TOTP token."; // 在生成动态验证码失败时输出错误消息 exit(); // 出错时停止执行后续代码 } // 导入 QR Code 生成库 require_once 'vendor/autoload.php'; use chillerlan\QRCode\QRCode; use chillerlan\QRCode\QROptions; // 生成二维码 $options = new QROptions; //$options->version = 7; $options->outputInterface = QRGdImagePNG::class; $options->scale = 20; $options->bgColor = [200, 150, 200]; $options->imageTransparent = true; $qrCode = new QRCode($options); // 生成二维码数据 $qrCodeData = $qrCode->render($token); // 输出HTML页面 echo " 动态验证码

Dynamic QR Code

\"Dynamic "; ?>