1. 程式人生 > >REDIS字串-二進位制安全的含義

REDIS字串-二進位制安全的含義

一、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, 由於是非二進位制安全,誤判為相等 */
 }