REDIS字串-二進位制安全的含義
阿新 • • 發佈:2019-02-09
一、sds vs c字串
在 C 語言中,字串可以用一個 \0
結尾的 char
陣列來表示。
比如說, hello world
在 C 語言中就可以表示為 "hello world\0"
。
這種簡單的字串表示,在大多數情況下都能滿足要求,但是,它並不能高效地支援長度計算和追加(append)這兩種操作:
- 每次計算字串長度(
strlen(s)
)的複雜度為 O(N)。 - 對字串進行 N 次追加,必定需要對字串進行 N 次記憶體重分配(
realloc
)。
而redis除了要處理c語言字串之外,還需要處理redis的伺服器協議等等。所以,redis實現的sds(簡單動態字串),是二進位制安全的。
資料結構的定義如下:
typedef char *sds;
struct sdshdr {
// buf 已佔用長度
int len;
// buf 剩餘可用長度
int free;
// 實際儲存字串資料的地方
char buf[];
};
從上面的資料結構定義,可以看出,redis的sds和c語言的區別就是,sds是通過buf以及len來判斷字串內容的,而不是通過“\0”來判斷
二、二進位制安全
看下面程式碼
c語言: str = "1234\0123" strlen(str)=4 redis: strlen(str)=7
所以,簡單來說,二進位制安全就是,字串不是根據某種特殊的標誌來解析的,無論輸入是什麼,總能保證輸出是處理的原始輸入而不是根據某種特殊格式來處理。
比如這邊redis通過len來表示字串長度,不會因為中間插入了“\0”就返回錯誤結果。
再舉個例子:(展示非二進位制安全)
main(){ char ab[] = "Hello"; char ac[] = "Hello\0Hello"; strcmp(ab, ac); /*返回0, 由於是非二進位制安全,誤判為相等 */ }