前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Redis字符串-二进制安全(sds:简单动态字符串

Redis字符串-二进制安全(sds:简单动态字符串

作者头像
用户8639654
修改2021-08-23 18:35:10
8490
修改2021-08-23 18:35:10
举报
文章被收录于专栏:云计算运维云计算运维

简单来说,二进制安全就是,字符串不是根据某种特殊的标志来解析的,无论输入是什么,总能保证输出是处理的原始输入而不是根据某种特殊格式来处理。

在 C 语言中,字符串可以用一个 \0 结尾的 char 数组来表示。

比如说, hello world 在 C 语言中就可以表示为 "hello world\0"

这种简单的字符串表示,在大多数情况下都能满足要求,但是,它并不能高效地支持长度计算和追加(append)这两种操作:

  • 每次计算字符串长度(strlen(s))的复杂度为 O(N)。
  • 对字符串进行 N 次追加,必定需要对字符串进行 N 次内存重分配(realloc)。

而redis除了要处理c语言字符串之外,还需要处理redis的服务器协议等等。所以,redis实现的sds(简单动态字符串),是二进制安全的。

数据结构的定义如下:

代码语言:javascript
复制
typedef char *sds;    
  
struct sdshdr {  
    // buf 已占用长度  
    int len;  
    // buf 剩余可用长度  
    int free;  
    // 实际保存字符串数据的地方  
    char buf[];  
};  

从上面的数据结构定义,可以看出,redis的sds和c语言的区别就是,sds是通过buf以及len来判断字符串内容的,而不是通过\0来判断。

二进制安全

看下面代码

代码语言:javascript
复制
str = "1234\0123"
// c语言:
strlen(str)=4
// redis:
strlen(str)=7

所以,简单来说,二进制安全就是,字符串不是根据某种特殊的标志来解析的,无论输入是什么,总能保证输出是处理的原始输入而不是根据某种特殊格式来处理。

比如这边redis通过len来表示字符串长度,不会因为中间插入了\0就返回错误结果。

再举个例子:(展示非二进制安全)

代码语言:javascript
复制
main(){  
    char ab[] = "Hello";  
    char ac[] = "Hello\0Hello";  
    /*返回0, 由于是非二进制安全,误判为相等 */
    strcmp(ab, ac); 
 }

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 二进制安全
相关产品与服务
云数据库 Redis
腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档