首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 產生英數混合隨機字串:安全、高效、可自訂長度的實作

     編輯:PHP 綜合知識

需求分析

  • 產生指定長度的隨機字串,包含大小寫字母 + 數字(可選符號)。
  • 適用於驗證碼、API Token、臨時密碼、檔案命名等場景。
  • **安全性要求視用途而定**:驗證碼可用 `mt_rand`,Token/密碼**必須用 CSPRNG**(`random_bytes`/`random_int`)。

方案一:通用函數(mt_rand,適用非安全場景)

<?php
/**
 * 產生英數混合隨機字串 (非加密安全)
 * @param int $length 長度
 * @param string $charset 字元集,預設大小寫+數字
 * @return string
 */
function randomAlphaNum(int $length = 8, string $charset = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'): string {
    $max = strlen($charset) - 1;
    $result = '';
    for ($i = 0; $i < $length; $i++) {
        $result .= $charset[mt_rand(0, $max)];
    }
    return $result;
}

// 使用
echo randomAlphaNum(4);  // 例: a7K9
echo randomAlphaNum(32); // 例: xY3k9Lp2...
?>

方案二:加密安全隨機字串(random_bytes,PHP 7+ 必用)

<?php
/**
 * 產生加密安全的英數混合隨機字串
 * 使用 random_bytes + Base62 編碼,無模數偏差
 */
function randomSecureAlphaNum(int $length = 32): string {
    // Base62 字元集
    $chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $bytes = random_bytes($length); // 取得足夠熵
    $result = '';
    $mask = 0x3F; // 63 (Base62 需 6 bits,但 64 > 62,需拒絕採樣)
    $charCount = strlen($chars);

    for ($i = 0; $i < $length; $i++) {
        // 拒絕採樣避免模數偏差
        do {
            $byte = $bytes[$i % strlen($bytes)];
            $val = $byte & $mask;
        } while ($val >= $charCount);
        $result .= $chars[$val];
    }
    return $result;
}

// 更簡潔:random_bytes + base64url 編碼 (含 - _,非純英數)
function randomToken(int $bytes = 32): string {
    return rtrim(strtr(base64_encode(random_bytes($bytes)), '+/', '-_'), '=');
}

// 使用
echo randomSecureAlphaNum(24); // 例: k7X9pL2m...
echo randomToken(32);          // 例: xY3k9Lp2-abc_def...
?>

方案三:RandomLib / paragonie/random_compat(專業庫)

composer require paragonie/random_lib

<?php
use ParagonIE\RandomLib\Factory;
use ParagonIE\RandomLib\Generator;

$factory = new Factory();
$generator = $factory->getGenerator(Generator::MEDIUM_STRENGTH); // 或 HIGH_STRENGTH

// 產生指定字元集字串
$token = $generator->generateString(32, '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ');
echo $token;
?>

場景選型指南

用途安全等級推薦函數長度建議
圖形驗證碼低`mt_rand` / `random_int`4-6
簡短邀請碼中`random_int` + Base328-12
API Access Token高`random_bytes` + Base64url / `randomSecureAlphaNum`32-64
密碼重設 Token高`random_bytes(32)` + Base64url32 bytes (43 chars)
CSRF Token高`random_bytes(32)`32 bytes
臨時檔案名中`uniqid('', true)` 或 `random_bytes(16)`16-32

常見錯誤與修正

錯誤寫法問題正確寫法
md5(uniqid(rand(), true))可預測、熵不足、長度固定 32`bin2hex(random_bytes(16))`
str_shuffle('abc...')非 CSPRNG、分布不均`random_int` 選索引
rand() / mt_rand() 用於 Token非加密安全、可被暴力破解`random_bytes` / `random_int`
自訂字元集含模稜兩可字元 (0/O, 1/l/I)人工辨識困難移除模稜字元:`23456789ABCDEFGHJKMNPQRSTUVWXYZ`

進階:Base62 / Base58 編碼工具類

<?php
class BaseEncoder {
    public const BASE62 = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    public const BASE58 = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'; // 無 0 O I l

    public static function encode(string $bytes, string $alphabet = self::BASE62): string {
        $base = strlen($alphabet);
        $num = new \GMP(gmp_init(bin2hex($bytes), 16));
        $result = '';
        while (gmp_cmp($num, 0) > 0) {
            list($num, $rem) = gmp_div_qr($num, $base);
            $result = $alphabet[gmp_intval($rem)] . $result;
        }
        return $result ?: $alphabet[0];
    }

    public static function decode(string $str, string $alphabet = self::BASE62): string {
        $base = strlen($alphabet);
        $num = gmp_init(0);
        foreach (str_split($str) as $char) {
            $val = strpos($alphabet, $char);
            if ($val === false) throw new InvalidArgumentException("Invalid char: $char");
            $num = gmp_add(gmp_mul($num, $base), $val);
        }
        return gmp_export($num);
    }
}

// 使用:32 bytes 隨機 -> Base62 字串
$token = BaseEncoder::encode(random_bytes(32));
echo $token; // 約 43 字元
?>

根據安全需求選擇正確隨機源,善用 CSPRNG 專業庫,避免常見陷阱,產出既安全又易用的隨機字串。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved