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

PHP 實現短網址 ID 雙向轉換:類似優酷視頻 ID 的 Base62 編碼實戰

     編輯:PHP 綜合知識

前言:為什麼需要短 ID?

觀察優酷(id_XNjA5MjE5OTM2)、騰訊視頻等平台的分享連結,會發現其 ID 並非單純數字,而是混合大小寫字母與數字的短字串。這不僅美觀、利於分享,還能隱藏業務實體 ID,避免競對爬蟲推算業務量。本文介紹一個經典的 PHP alphaID 函數,實現數字與短字串的雙向無損轉換,並支援密鑰加密增強安全性。

核心原理:進制轉換與字符集打亂

alphaID 本質上是將 10 進制整數轉換為 62 進制(a-z + 0-9 + A-Z),反之亦然。引入 $passKey 時,會對字符集進行 SHA256/SHA512 雜湊打亂,使無密鑰者難以逆向推導原始數字。

完整代碼實現

/**
 * 數字與短字串雙向轉換
 * @param mixed $in 輸入字串或長整數
 * @param bool $to_num true 時反向解析為數字
 * @param mixed $pad_up 補位長度或布林值
 * @param string $passKey 密鑰,用於打亂字符集增強安全性
 * @return mixed 轉換後的字串或長整數
 */
function alphaID($in, $to_num = false, $pad_up = false, $passKey = null) {
    $index = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    
    if ($passKey !== null) {
        // 密鑰打亂字符集
        for ($n = 0; $n < strlen($index); $n++) {
            $i[] = substr($index, $n, 1);
        }
        $passhash = hash('sha256', $passKey);
        $passhash = (strlen($passhash) < strlen($index)) ? hash('sha512', $passKey) : $passhash;
        for ($n = 0; $n < strlen($index); $n++) {
            $p[] = substr($passhash, $n, 1);
        }
        array_multisort($p, SORT_DESC, $i);
        $index = implode($i);
    }
    
    $base = strlen($index);
    
    if ($to_num) {
        // 字串 -> 數字
        $out = 0;
        $in = strrev($in);
        for ($t = 0; $t < strlen($in); $t++) {
            $bcp = bcpow($base, $t);
            $a = strpos($index, substr($in, $t, 1));
            $out += $a * $bcp;
        }
        if (is_numeric($pad_up)) {
            $pad_up--;
            if ($pad_up > 0) $out -= pow($base, $pad_up);
        }
        $out = sprintf('%F', $out);
        $out = substr($out, 0, strpos($out, '.'));
    } else {
        // 數字 -> 字串
        if (is_numeric($pad_up)) {
            $pad_up--;
            if ($pad_up > 0) $in += pow($base, $pad_up);
        }
        $out = "";
        for ($t = floor(log($in, $base)); $t >= 0; $t--) {
            $bcp = bcpow($base, $t);
            $a = floor($in / $bcp) % $base;
            $out .= substr($index, $a, 1);
            $in -= ($a * $bcp);
        }
        $out = strrev($out);
    }
    return $out;
}

使用範例

// 加密:數字 -> 短字串
$short = alphaID(9007199254740989); 
// 結果:fE2XnNGpF

// 解密:短字串 -> 數字
$original = alphaID('fE2XnNGpF', true); 
// 結果:9007199254740989

// 帶密鑰加密(同一數字在不同密鑰下產生不同短字串)
$shortWithKey = alphaID(123456, false, false, 'mySecretKey');
$originalWithKey = alphaID($shortWithKey, true, false, 'mySecretKey');

應用場景與注意事項

  • 短網址服務:將資料庫自增 ID 轉為短碼,如 domain.com/fE2XnNGpF
  • 訂單號/券碼生成:避免連續數字洩露業務增長數據
  • 分享連結美化:替代冗長的數字參數
  • 注意:此演算法非加密演算法,$passKey 僅增加逆向難度,嚴禁用於敏感資料加密

效能與替代方案

alphaID 使用 bcpow 處理大數,效能尚可。若追求極致效能或更短編碼,可考慮:

  • Base62 編碼庫:如 tuupola/base62 (Composer 套件)
  • Hashids:專為 ID 混淆設計,支援自定義字符集、長度、鹽值
  • Optimus:基於 Knuth 整數哈希,可逆、無碰撞、極快
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved