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

PHP 實現數字 ID 與短字母 ID 雙向轉換(alphaID)完整解析

     編輯:PHP 綜合知識

在 URL 短鏈接、訂單號混淆、文件分佈存儲等場景,常需將數字 ID(如自增主鍵)轉為短字母串,且支持反向還原。alphaID 是經典實現,基於進制轉換 + 字符集打亂,支持自定義長度、密鑰加密。本文深度解析原理、代碼、使用場景與注意事項。

核心功能演示

<?php
// 數字 → 字母
echo alphaID(12354);              // PpQXn7COf
echo alphaID(12354, false, 6);    // 指定長度 6

// 字母 → 數字
echo alphaID('PpQXn7COf', true);  // 12354

// 帶密鑰(更難破解)
echo alphaID(12354, false, 0, 'my_secret_key'); // 輸出不同字符串
echo alphaID($encoded, true, 0, 'my_secret_key'); // 還原需同密鑰
?>

完整 alphaID 函數代碼

<?php
/**
 * 數字 ID 與短字母 ID 雙向轉換
 *
 * @param mixed  $in       輸入:數字(轉字母) 或 字符串(轉數字)
 * @param bool   $toNum    true=字母轉數字, false=數字轉字母
 * @param mixed  $padUp    數字/長度:最小長度補位
 * @param string $passKey  密鑰:打亂字符集,增加破解難度
 * @return mixed 轉換結果
 */
function alphaID($in, $toNum = false, $padUp = false, $passKey = null) {
    // 基礎字符集:62 位 (a-z, 0-9, A-Z)
    $index = 'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    
    // 密鑰打亂字符集(可選)
    if ($passKey !== null) {
        $i = str_split($index);
        $passHash = hash('sha256', $passKey);
        $passHash = (strlen($passHash) < strlen($index)) ? hash('sha512', $passKey) : $passHash;
        $p = str_split($passHash);
        array_multisort($p, SORT_DESC, $i); // 以密鑰哈希排序字符集
        $index = implode($i);
    }
    
    $base = strlen($index); // 62
    
    if ($toNum) {
        // === 字母 → 數字 ===
        $in = strrev($in); // 反轉
        $out = 0;
        $len = strlen($in) - 1;
        for ($t = 0; $t <= $len; $t++) {
            $bcp = bcpow($base, $len - $t); // 大數冪運算
            $out += strpos($index, $in[$t]) * $bcp;
        }
        // 補位還原
        if (is_numeric($padUp)) {
            $padUp--;
            if ($padUp > 0) $out -= pow($base, $padUp);
        }
        $out = sprintf('%F', $out); // 避免科學計數法
        $out = substr($out, 0, strpos($out, '.'));
    } else {
        // === 數字 → 字母 ===
        // 補位
        if (is_numeric($padUp)) {
            $padUp--;
            if ($padUp > 0) $in += pow($base, $padUp);
        }
        $out = '';
        for ($t = floor(log($in, $base)); $t >= 0; $t--) {
            $bcp = bcpow($base, $t);
            $a = floor($in / $bcp) % $base;
            $out .= $index[$a];
            $in -= $a * $bcp;
        }
        $out = strrev($out); // 反轉輸出
    }
    return $out;
}
?>

原理深度解析

1. 62 進制轉換

字符集長度 62,相當於 **62 進制**。數字轉字母本質是「10 進制 → 62 進制」,字母轉數字是「62 進制 → 10 進制」。

例子: 12354 (10進制) → 62進制表示
12354 = 3×62² + 17×62¹ + 8×62⁰
索引:  3   17   8
字符:  d   r   i  → "dri" (未打亂時)

2. 字符集打亂(密鑰加密)

使用 `hash('sha256', $passKey)` 生成 64 位十六進制字符串,按字符值降序排序,帶動原字符集同步重排。這相當於**替換密碼**,無密鑰無法還原映射關係。

3. 反轉輸出

轉換後 `strrev()` 反轉,使高位在前、低位在後,符合人類閱讀習慣,且使目錄分佈更均勻(見下文)。

4. 補位機制 ($padUp)

指定最小長度,避免 ID 過短(如 `1` → `b`)。原理:轉換前給數字加上 `base^padUp`,轉換後減去。確保輸出長度 ≥ `padUp`。

典型應用場景

場景一:短鏈接 / 短 URL

<?php
// 數據庫自增 ID → 短碼
$shortCode = alphaID($autoIncrementId); // 如 123456789 → "aB3fG"
// 存儲映射: short_codes 表 (code, target_url)
// 訪問 /aB3fG → 解碼得 ID → 查詢目標 URL → 302 跳轉
?>

場景二:訂單號/單號混淆

<?php
// 避免暴露業務量(連續數字)
$publicOrderNo = alphaID($internalOrderId, false, 8, 'order_salt_2024');
// 內部系統解碼還原真實 ID 處理
$realId = alphaID($publicOrderNo, true, 8, 'order_salt_2024');
?>

場景三:文件分佈存儲(目錄均勻化)

<?php
// 利用反轉特性:前兩位字符決定目錄層級
$alphaId = alphaID($fileId); // 如 "PpQXn7COf"
$dir1 = $alphaId[0]; // 'P'
$dir2 = $alphaId[1]; // 'p'
$dir3 = substr($alphaId, 2); // 'QXn7COf'
$path = "/storage/$dir1/$dir2/$dir3";
// 好處:62×62=3844 個二級目錄,文件均勻分佈,避免單目錄文件過多
?>

限制與注意事項 ⚠️

限制說明應對
最大支持數字~9007199254740992 (2^53, JS/ PHP float 安全整數上限)超大數字用 BCMath/GMP 或分段編碼
非加密安全僅為混淆,非加密算法,已知算法+樣本可逆推密鑰敏感數據請用 AES/openssl_encrypt
大小寫敏感字符集含大小寫,URL 中區分大小寫Web 服務器配置忽略大小寫或統一轉小寫
PHP 版本要求需 BCMath 擴展 (`bcpow`, `bcadd` 等)安裝 php-bcmath / php7.x-bcmath

現代替代方案

  • Hashids (推薦):hashids/hashids.php,專為 ID 混淆設計,支持最小長度、字符集自定義、多 ID 編碼、解碼驗證,無依賴 BCMath。
  • Base62 編碼庫:如 tuupola/base62,純編碼無加密,極快。
  • UUID/ULID:分布式系統首選,無需中心化自增 ID。

總結

alphaID 是一個經典、輕量的數字-短字母雙向轉換函數,通過 62 進制轉換 + 字符集打亂 + 反轉輸出 實現。適用於短鏈接、訂單號混淆、文件分佈等**非安全敏感**場景。生產環境建議使用成熟庫 Hashids,獲得更好可維護性與功能豐富度。

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