在系統開發中,權限控制是核心功能之一。參考 Linux/UNIX 的權限編碼思想,採用位運算實現權限控制,不僅邏輯清晰,而且運行效率極高。本文將詳細介紹這種通用的權限控制算法,並提供 Java 代碼實現。
將每一個具體操作分配一個唯一的整數索引(從 0 開始),例如:
用戶的權限值計算公式為:permissionValue = Σ 2operationIndex。也就是將用戶擁有的所有操作索引對應的 2 的冪次方相加。
假設用戶擁有「新增 A (2)」、「刪除 B (3)」、「修改 B (4)」三個權限,則:
permissionValue = 22 + 23 + 24 = 4 + 8 + 16 = 28
二進制表示:11100
驗證用戶是否擁有某項權限,只需將用戶權限值與該操作的權限值進行位與(&)運算。若結果等於該操作的權限值,則擁有權限。
// 驗證用戶是否擁有刪除 B (索引 3) 的權限
int userPerm = 28; // 用戶總權限值
int opIndex = 3; // 操作索引
int opPermValue = (int) Math.pow(2, opIndex); // 8
boolean hasPermission = (userPerm & opPermValue) == opPermValue;
// 結果為 true
11100 (28)
& 01000 (8 = 2^3)
--------
01000 = 8 → 等於 2^3,擁有權限
若驗證「刪除 A (索引 0)」,則 28 & 1 = 0,不等於 1,表示無權限。
若需驗證用戶是否同時擁有多項權限(如刪除 A 和 刪除 B),可將多個操作的權限值相加後再進行位與運算:
int required = (int)Math.pow(2, 0) + (int)Math.pow(2, 3); // 1 + 8 = 9
boolean hasBoth = (userPerm & required) == required;
系統可預先定義角色對應的權限值組合,根據用戶的總權限值快速判斷其角色,實現 RBAC(基於角色的存取控制)。
public class PermissionUtils {
/**
* 檢查用戶是否擁有指定操作權限
* @param userPermValue 用戶總權限值
* @param operationIndex 操作索引(未經冪運算)
* @return 是否擁有權限
*/
public static boolean checkPermission(int userPermValue, int operationIndex) {
int permValue = 1 << operationIndex; // 等同於 2^operationIndex,效率更高
return (userPermValue & permValue) == permValue;
}
/**
* 根據操作索引列表生成總權限值
* @param indices 操作索引數組
* @return 總權限值
*/
public static int buildPermissionValue(int[] indices) {
int sum = 0;
for (int index : indices) {
sum |= (1 << index);
}
return sum;
}
}
建議建立權限數據字典,使用常量類管理操作索引,便於維護:
public class PermConstants {
// 常規信息模塊
public static final int CGXX_XF = 0; // 下發
public static final int CGXX_LB = 1; // 列表
public static final int CGXX_SH = 2; // 審核
// 包月用戶
public static final int BYYH_CK = 3; // 查看
// 違章點播
public static final int WZDB_TJ = 4; // 統計
// 定制提取
public static final int DZTQ_XX = 5; // 詳情
// 請求記錄
public static final int QQJL = 6;
// 管理員
public static final int GLY_QX = 7;
}
int 存儲,最多支援 32 個操作(0-31);若超過請改用 long(64 位)或 BigInteger。基於位運算的權限控制算法,以其簡潔的數學模型、卓越的性能表現,成為許多成熟系統的首選方案。掌握其核心邏輯,能幫助開發者構建高效、可擴展的權限體系。