JS 中的二進制散列值和權限設計
不管是前端還是後端的夥伴,在工作中會經常遇到權限控制的場景,業務上無非就幾種權限:頁面權限、操作權限、數據權限,不同公司根據業務需要都採取不同的方法區控制權限,我們這裏討論一下使用 JavaScript 中的位運算符來控制權限。
進制類型
JavaScript 中提供的進製表示方法有四種:十進制、二進制、十六進制、八進制。
對於數值字面量,主要使用不同的前綴來區分:
-
十進制:取值數字 0-9;不用前綴。
-
二進制 (Binary): 取值數字 0 和 1 ;前綴 0b 或 0B。
-
十六進制 (Hexadecimal):取值數字 0-9 和 a-f ;前綴 0x 或 0X。
-
八進制 (Octal):取值數字 0-7 ;前綴 0o 或 0O (ES6 規定)。
位運算符
什麼是位運算符?
位運算符指的是二進制位的運算,先將十進制數轉成二進制後再進行運算。 在二進制位運算中,1 表示 true,0 表示 false。
JavaScript 中的按位操作符有:
示例:
const A = 0101,B = 0001
// 按位與(AND)
A & B = 0001
// 按位或(OR)
A | B = 0101
// 按位異或(XOR)
A ^ B = 0100
// 按位非(NOT)
~A = 1010
// 按位左移
A << 1 = 1010
// 按位右移
A >> 1 = 0010
// 無符號右移
A >>> 1 = 0010
位運算符在工作中的應用得比較少,但有時候它可以很巧妙地解決我們工作中一些問題。
運用場景
在傳統的權限系統中,不同的權限之間存在很多關聯關係,而且有很多種權限組合方式,在這種情況下,權限就越難以維護。這種情況我們就可以使用位運算符,可以很巧妙地解決這個問題。
假設我們現在權限系統中有 4 種基本權限:可讀、可寫、創建、刪除。
那麼我們可以定義 4 個二進制變量表示:
// 所有權限碼的二進制數形式,有且只有一位值爲 1,其餘全部爲 0
const READ = 0b1000 // 可讀
const WRITE = 0b0100 // 可寫
const CREATE = 0b0010 // 創建
const DELETE = 0b0001 // 刪除
權限操作
1、使用 按位或(OR) 添加權限:
// 賦予用戶全部權限
const ALL = READ | WRITE | CREATE | DELETE
console.log(ALL)
// 結果位 1111,每個位置的1就代表擁有這個權限,這裏全部是1,就代表擁有全部權限。
// 同樣的,這些權限可以自由組合
const READ_AND_WRITE = READ | WRITE // 可讀和可寫,結果爲 1100
const READ_AND_CREATE = READ | CREATE // 可讀和創建,結果爲 1010
const WRITE_AND_DELETE = WRITE | DELETE // 可寫和刪除,結果爲 0101
2、使用 按位與(AND) 校驗權限:
// 比如我們拿到一個用戶的權限,我們怎麼根據返回的數據判斷是否擁有某個權限呢?
// 假設現在返回了 擁有可讀可寫的權限組合:1100
const auth = READ | WRITE // 可讀和可寫,結果爲 1100
// 判斷是否包含 READ 權限
const isRead = (auth & READ) === READ // true
// 是否包含 DELETE 權限
const isDelete = (auth & DELETE) === DELETE // false
3、使用 按位非(NOT) 剔除權限:
// 全部權限
const ALL = READ | WRITE | CREATE | DELETE
// 如果要剔除 WRITE 權限,應該怎麼做呢,先執行 ~ 取反,再執行 & 運算
const notWrite = ALL & ~WRITE // 輸出 1011
// 剔除 DELETE 權限
const notDelete = ALL & ~DELETE // 輸出 1110
侷限性
本文提到的這種位運算符方案,有一定的前提條件:
-
每種權限碼都是唯一的,有且只有一位值爲 1。
-
一個數字的範圍只能在 -(2^53 -1) 和 2^53 -1 之間,如果權限系統設計得比較龐大,這種方式可能不合適。
不過總的來說,這種方式在中小型業務中應該夠用了。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/v-sqguXI-V0-s5QeGbj__Q?poc_token=HNJKUGajiPsB7qDvvvcDaqyMHBtRcIo32y7JXtmf