觀察優酷(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');
domain.com/fE2XnNGpF$passKey 僅增加逆向難度,嚴禁用於敏感資料加密alphaID 使用 bcpow 處理大數,效能尚可。若追求極致效能或更短編碼,可考慮:
tuupola/base62 (Composer 套件)