參考文章:
深度分析redis的二進位制安全
c語言中字串是以特殊字元「\0」來作為字串的結束標識。對於字串str="0123456789\0123456789」來說,在c語言裡面str的長度就是10(strlen(str)=10),所以strlen()函式不是二進位制安全的。
簡單動態字串(****** dynamic strings,sds)是redis的基本資料結構之一,主要用於儲存字串、整型數字。
struct sdshdr
;
柔性陣列:c語言中結構體的最後乙個元素可以是大小未知的陣列,也就是所謂的0長度,所以我們可以用結構體來建立柔性陣列。而定義sds的結構體中的陣列就是柔性陣列,可以根據需要調整陣列長度,也可以通過柔性陣列的首位址偏移得到結構體首位址。
sds採用柔性陣列的缺點:不同sds字串占用了相同大小的頭部空間(buf、leng長度),浪費空間。
圖中:1、len表示buf中已占用位元組數。
2、alloc表示buf中已分配位元組數,記錄的是為buf分配的總長度,不同於free。
3、flags標識當前結構體的型別,低3位用作標識位,高5位預留。
4、buf柔性陣列,真正儲存字串的資料空間。
(1)五種型別都多了乙個flags欄位,但sdsdr5沒有了頭部(len和free )
(2)sdshdr5結構中,flags佔1個字元,其低3位表示結構體型別,高5位表示長度,能表示的長度區間為0~31,flags後面就是字串的內容。而長度大於31的字串,1個位元組存不下,那麼就要將len和free單獨存放,因此redis存放資料時會先檢查字串長度,再根據字串長度計算好不同型別的頭部和初始長度,然後動態分配記憶體
(1)sds如何相容c語言字串?如何保證二進位制安全?
sds物件中的buf是乙個柔性陣列,上層呼叫時,sds直接返回了buf。由於buf是直接指向內容的指標,所以相容c語言函式。而當真正讀取內容時,sds會通過len來限制讀取長度,而非「0」,所以保證了二進位制安全。
(2)sdshdr5的特殊之處是什麼?
sdshdr5只負責儲存小於32位元組的字串。一般情況下,小字串的儲存更普遍,所以redis進一步壓縮了sdshdr5的資料結構,將sdshdr5的型別和長度放入了同乙個屬性中,用flags的低3位儲存型別,高5位儲存長度。建立空字串時,sdshdr5會被sdshdr8替代。
(3)sds是如何擴容的?
sds在涉及字串修改時會呼叫sdsmakeroomfor函式進行檢查,會根據空閒長度和新增內容的長度進行比較判斷,然後根據不同情況動態擴容
redis中string型別的二進位制安全
二進位制安全是什麼意思?二進位制安全是指,在傳輸資料時,保證二進位制資料的資訊保安,也就是不被篡改 破譯等,如果被攻擊,能夠及時檢測出來。二進位制安全包含了密碼學的一些東西,比如加解密 簽名等。舉個例子,你把資料11110000加密成10001000,然後傳給我,就是一種二進位制安全的做法。redi...
操作二進位制寫入二進
操作二進位制 寫入二進位制 1 宣告變數 sqlite3 stmt stat 2 把sql語句解析到stat結構中去 sqlite3 prepare 3 繫結替換 sqlite3 bind blob 4 儲存到資料庫 int result sqlite3 step 5 釋放stat結構 sqlite...
mysql儲存二進位制 mysql 儲存二進位制資料
晚上小研究了下mysql儲存於讀取二進位制資料的功能。關鍵步驟為以下三點 最重要的一點 儲存二進位制資料的表的型別需要是blob型別 按長度不同分為tiny,media,long 插入二進位制資料時需要利用mysql real escape string函式對資料進行轉換 從資料庫中讀取二進位制資料...